利用PHP实现开心消消乐的算法示例
前言
本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
一、需求描述:
1、在一个8*8的矩阵方格中随机出现5种颜色的色块。
2、当有三个或以上色块在横向或纵向上相连,则消除这些色块。
3、色块消除后,上方色块往下平移,并掉下颜色随机的色块填充矩阵空缺。
4、重复2、3步骤。
5、消除3个相同色块加10分,4个加15分,5个加20分,6个加30分,7个加40分,8个加70分,9个加100分,10个加150分,再往后每增加一个就比上一个多加50分。
二、上代码
'red',2=>'green',3=>'yellow',4=>'blue',5=>'black');//代表5种颜色 $samCol=array();//列上相连色块集合 $nowCol=array();//列上相连色块指针 $samArr=array();//相连色块总集合 $group=1;//组指针 //随机填充颜色,并获得行上相连色块start foreach($xxlas$k1=>$v1){ $sam=array();//行上相连色块集合 $now=1;//行上相连色块指针 foreach($v1as$k2=>$v2){ if(empty($v2)||$v2==''){ $v2=$xxl[$k1][$k2]=array_rand($color);//随机填充颜色 } if(!isset($nowCol[$k2])){ $nowCol[$k2]=1; } if($k1===0){ $samCol[$k2][$nowCol[$k2]][$k1.'-'.$k2]=array($k1,$k2,$v2,$k1.'-'.$k2.'-'.$v2); }else{ if($v2!=$xxl[$k1-1][$k2]){//同一列上和前一个颜色不一样 $nowCol[$k2]++; } $samCol[$k2][$nowCol[$k2]][$k1.'-'.$k2]=array($k1,$k2,$v2,$k1.'-'.$k2.'-'.$v2); } if($k2===0){ $sam[$now][$k1.'-'.$k2]=array($k1,$k2,$v2,$k1.'-'.$k2.'-'.$v2); }else{ if($v2!=$xxl[$k1][$k2-1]){//同一行上和前一个颜色不一样 $now++; } $sam[$now][$k1.'-'.$k2]=array($k1,$k2,$v2,$k1.'-'.$k2.'-'.$v2); } } //获得行上相连色块start foreach($samas$x=>$y){ if(count($y)>2){ $key='R-'.$group; foreach($yas$x2=>$y2){ $y[$x2]['group']['r']=$key; } $samArr+=$y; $group++; } } //获得行上相连色块end } //随机填充颜色,并获得行上相连色块end //获得列上相连色块start $group=1; foreach($samColas$k=>$v){ foreach($vas$x=>$y){ if(count($y)>2){ $key='L-'.$group; foreach($yas$x2=>$y2){ $y[$x2]['group']['l']=$key; if(isset($samArr[$x2]['group']['r'])){//判断本点是否已出现在横向组里 $samArr[$x2]['group']['l']=$key; } } $samArr+=$y; $group++; } } } //获得列上相连色块end //查找相连色块start $res=array();//相连色块集合 $hasRes=array(); foreach($samArras$k=>$v){ if(isset($hasRes[$k])){ continue; } $arr=array(); seek($samArr,$v,$arr); $res[]=array_keys($arr); $hasRes+=$arr; } //查找相连色块end show($xxl);//打印消除前的图形 if(empty($res)){//如果没有相连色块则退出递归 echo'=================================消除完毕!=================================='; return$point; } $thisPoint=countPoint($res);//计算本次消除获得积分 $point+=$thisPoint;//累计到总积分 //消除相连色块start $next=$xxl; foreach($resas$k=>$v){ foreach($vas$k2=>$v2){ $y=$samArr[$v2][0]; $x=$samArr[$v2][1]; $xxl[$y][$x]='*'; unset($next[$y][$x]); } } //消除相连色块end show($xxl);//打印消除时的图形 $next=step($next); show($next);//打印消除后的图形 echo"本次消除获得积分数量:{$thisPoint}\n"; returnplay($next,$point); } /*计算获得积分数量 *$xxlarray相连色块集合 */ functioncountPoint($xxl){ //初始化积分配置start $config=array(3=>10,4=>15,5=>20,6=>30,7=>40,8=>70,9=>100); for($i=10;$i<=64;$i++){ $config[$i]=100+($i-9)*50; } //初始化积分配置end $point=0; foreach($xxlas$v){ $key=count($v); $point+=$config[$key]; } return$point; } /*消掉并左移 *$xxlarray所有图形集合 */ functionstep($xxl){ foreach($xxlas$k=>$v){ $temp=array_merge($v); $count=count($temp); if($count==8){ continue; } for($i=$count;$i<=7;$i++){ $temp[$i]=''; } $xxl[$k]=$temp; } return$xxl; } /*找相邻点 *$xxlarray相连图形集合 *$onearray某一个点 *$arrarray图形集合里的相邻的点 */ functionseek($xxl,$one,&$arr){ //global$i; $near=array(); $near['up']=($one[0]-1).'-'.$one[1];//上面的点 $near['down']=($one[0]+1).'-'.$one[1];//下面的点 $near['left']=$one[0].'-'.($one[1]-1);//左面的点 $near['right']=$one[0].'-'.($one[1]+1);//右面的点 foreach($nearas$v){ if(isset($xxl[$v])&&$xxl[$v][2]==$one[2]){//找到相邻点 $xj=array_intersect($one['group'],$xxl[$v]['group']); if(empty($xj)){//如果相邻的点不是本组的就跳过 continue; } if(isset($arr[$v])){//如果该点已被遍历过则跳过 continue; } $arr[$v]=$xxl[$v]; seek($xxl,$xxl[$v],$arr);//继续找相邻的点 } } } /*打印图形 *$xxlarray所有图形集合 */ functionshow($xxl){ //顺时针旋转矩阵start $arr=array(); foreach($xxlas$k=>$v){ foreach($vas$k2=>$v2){ $arr[7-$k2][$k]=$v2; } } ksort($arr); //顺时针旋转矩阵end $str=''; foreach($arras$v){ foreach($vas$v2){ $str.=''.$v2; } $str.="\n"; } echo"\n".$str; }
运行结果如下:
12345分别代表5种颜色。
=================================开始第1步================================== 33221114 43434113 31411412 23431244 42422214 33212311 52132145 34513233 3322***4 43*341*3 31*114*2 23*31244 42****14 3321*311 5213*145 34513233 334 4323 31312 231444 42234214 33211311 52131145 34513233 本次消除获得积分数量:55 =================================开始第2步================================== 33223324 43321333 31334142 23512444 42234214 33211311 52131145 34513233 33223324 43321*** 31334142 23512*** 42234214 33211311 52131145 34513233 33223 43321 31334324 23512142 42234214 33211311 52131145 34513233 本次消除获得积分数量:20 =================================开始第3步================================== 33223413 43321425 31334324 23512142 42234214 33211311 52131145 34513233 =================================消除完毕!================================== 共获得积分数量:75
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。