利用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
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。