好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

利用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分。

二、上代码

<?php //所有图形初始化数据,key代表位置,value代表颜色 $xxl = array(  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''),  array('', '', '', '', '', '', '', ''), ); $point = play($xxl, $point);//开始游戏 echo "\n共获得积分数量:{$point}"; /*开始消除  *$xxl  array 所有图形集合  *$point int  获得积分数量 */ $bu = 0; function play($xxl, $point){  global $bu;  $bu ++;  echo '=================================开始第'.$bu.'步==================================';  $color = array(1 => 'red',2 => 'green',3 => 'yellow',4 => 'blue',5 => 'black');//代表5种颜色  $samCol = array();//列上相连色块集合  $nowCol = array();//列上相连色块指针  $samArr = array();//相连色块总集合  $group = 1;//组指针  //随机填充颜色,并获得行上相连色块start  foreach($xxl as $k1 => $v1){   $sam = array();//行上相连色块集合   $now = 1;//行上相连色块指针   foreach($v1 as $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($sam as $x => $y){    if(count($y) > 2){     $key = 'R-'.$group;     foreach($y as $x2 => $y2){      $y[$x2]['group']['r'] = $key;     }     $samArr += $y;     $group ++;    }   }   //获得行上相连色块end  }  //随机填充颜色,并获得行上相连色块end  //获得列上相连色块start  $group = 1;  foreach($samCol as $k => $v){   foreach($v as $x => $y){    if(count($y) > 2){     $key = 'L-'.$group;     foreach($y as $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($samArr as $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($res as $k => $v){   foreach($v as $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";  return play($next, $point); } /*计算获得积分数量  *$xxl  array 相连色块集合  */ function countPoint($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($xxl as $v){   $key = count($v);   $point += $config[$key];  }  return $point; } /*消掉并左移  *$xxl  array 所有图形集合  */ function step($xxl){  foreach($xxl as $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; } /*找相邻点  *$xxl  array 相连图形集合  *$one   array 某一个点  *$arr   array 图形集合里的相邻的点 */ function seek($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($near as $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);//继续找相邻的点   }  } } /*打印图形  *$xxl  array 所有图形集合  */ function show($xxl){  //顺时针旋转矩阵start  $arr = array();  foreach($xxl as $k => $v){   foreach($v as $k2 => $v2){    $arr[7-$k2][$k] = $v2;   }  }  ksort($arr);  //顺时针旋转矩阵end  $str = '';  foreach($arr as $v){   foreach($v as $v2){    $str .= ' '.$v2;   }   $str .= "\n";  }  echo "\n".$str; }

运行结果如下:

12345分别代表5种颜色。

=================================开始第1步==================================  3 3 2 2 1 1 1 4  4 3 4 3 4 1 1 3  3 1 4 1 1 4 1 2  2 3 4 3 1 2 4 4  4 2 4 2 2 2 1 4  3 3 2 1 2 3 1 1  5 2 1 3 2 1 4 5  3 4 5 1 3 2 3 3  3 3 2 2 * * * 4  4 3 * 3 4 1 * 3  3 1 * 1 1 4 * 2  2 3 * 3 1 2 4 4  4 2 * * * * 1 4  3 3 2 1 * 3 1 1  5 2 1 3 * 1 4 5  3 4 5 1 3 2 3 3  3 3   4  4 3 2  3  3 1 3 1 2  2 3 1 4 4 4  4 2 2 3 4 2 1 4  3 3 2 1 1 3 1 1  5 2 1 3 1 1 4 5  3 4 5 1 3 2 3 3 本次消除获得积分数量:55 =================================开始第2步==================================  3 3 2 2 3 3 2 4  4 3 3 2 1 3 3 3  3 1 3 3 4 1 4 2  2 3 5 1 2 4 4 4  4 2 2 3 4 2 1 4  3 3 2 1 1 3 1 1  5 2 1 3 1 1 4 5  3 4 5 1 3 2 3 3  3 3 2 2 3 3 2 4  4 3 3 2 1 * * *  3 1 3 3 4 1 4 2  2 3 5 1 2 * * *  4 2 2 3 4 2 1 4  3 3 2 1 1 3 1 1  5 2 1 3 1 1 4 5  3 4 5 1 3 2 3 3  3 3 2 2 3    4 3 3 2 1    3 1 3 3 4 3 2 4  2 3 5 1 2 1 4 2  4 2 2 3 4 2 1 4  3 3 2 1 1 3 1 1  5 2 1 3 1 1 4 5  3 4 5 1 3 2 3 3 本次消除获得积分数量:20 =================================开始第3步==================================  3 3 2 2 3 4 1 3  4 3 3 2 1 4 2 5  3 1 3 3 4 3 2 4  2 3 5 1 2 1 4 2  4 2 2 3 4 2 1 4  3 3 2 1 1 3 1 1  5 2 1 3 1 1 4 5  3 4 5 1 3 2 3 3 =================================消除完毕!================================== 共获得积分数量:75

查看更多关于利用PHP实现开心消消乐的算法示例的详细内容...

  阅读:67次