当前位置:Gxlcms > PHP教程 > php实现开心消消乐的算法的过程分享

php实现开心消消乐的算法的过程分享

时间:2021-07-01 10:21:17 帮助过:46人阅读

开心消消乐应该对大家来说都不陌生吧,下面这篇文章主要给大家介绍了关于如何利用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分。

二、上代码


  1. <?php
  2. //所有图形初始化数据,key代表位置,value代表颜色
  3. $xxl = array(
  4. array('', '', '', '', '', '', '', ''),
  5. array('', '', '', '', '', '', '', ''),
  6. array('', '', '', '', '', '', '', ''),
  7. array('', '', '', '', '', '', '', ''),
  8. array('', '', '', '', '', '', '', ''),
  9. array('', '', '', '', '', '', '', ''),
  10. array('', '', '', '', '', '', '', ''),
  11. array('', '', '', '', '', '', '', ''),
  12. );
  13. $point = play($xxl, $point);//开始游戏
  14. echo "\n共获得积分数量:{$point}";
  15. /*开始消除
  16. *$xxl array 所有图形集合
  17. *$point int 获得积分数量
  18. */
  19. $bu = 0;
  20. function play($xxl, $point){
  21. global $bu;
  22. $bu ++;
  23. echo '=================================开始第'.$bu.'步==================================';
  24. $color = array(1 => 'red',2 => 'green',3 => 'yellow',4 => 'blue',5 => 'black');//代表5种颜色
  25. $samCol = array();//列上相连色块集合
  26. $nowCol = array();//列上相连色块指针
  27. $samArr = array();//相连色块总集合
  28. $group = 1;//组指针
  29. //随机填充颜色,并获得行上相连色块start
  30. foreach($xxl as $k1 => $v1){
  31. $sam = array();//行上相连色块集合
  32. $now = 1;//行上相连色块指针
  33. foreach($v1 as $k2 => $v2){
  34. if(empty($v2) || $v2 == ' '){
  35. $v2 = $xxl[$k1][$k2] = array_rand($color);//随机填充颜色
  36. }
  37. if(!isset($nowCol[$k2])){
  38. $nowCol[$k2] = 1;
  39. }
  40. if($k1 === 0){
  41. $samCol[$k2][$nowCol[$k2]][$k1 .'-'. $k2] = array($k1, $k2, $v2, $k1 .'-'. $k2 .'-'. $v2);
  42. }else{
  43. if($v2 != $xxl[$k1-1][$k2]){//同一列上和前一个颜色不一样
  44. $nowCol[$k2] ++;
  45. }
  46. $samCol[$k2][$nowCol[$k2]][$k1 .'-'. $k2] = array($k1, $k2, $v2, $k1 .'-'. $k2 .'-'. $v2);
  47. }
  48. if($k2 === 0){
  49. $sam[$now][$k1 .'-'. $k2] = array($k1, $k2, $v2, $k1 .'-'. $k2 .'-'. $v2);
  50. }else{
  51. if($v2 != $xxl[$k1][$k2-1]){//同一行上和前一个颜色不一样
  52. $now++;
  53. }
  54. $sam[$now][$k1 .'-'. $k2] = array($k1, $k2, $v2, $k1 .'-'. $k2 .'-'. $v2);
  55. }
  56. }
  57. //获得行上相连色块start
  58. foreach($sam as $x => $y){
  59. if(count($y) > 2){
  60. $key = 'R-'.$group;
  61. foreach($y as $x2 => $y2){
  62. $y[$x2]['group']['r'] = $key;
  63. }
  64. $samArr += $y;
  65. $group ++;
  66. }
  67. }
  68. //获得行上相连色块end
  69. }
  70. //随机填充颜色,并获得行上相连色块end
  71. //获得列上相连色块start
  72. $group = 1;
  73. foreach($samCol as $k => $v){
  74. foreach($v as $x => $y){
  75. if(count($y) > 2){
  76. $key = 'L-'.$group;
  77. foreach($y as $x2 => $y2){
  78. $y[$x2]['group']['l'] = $key;
  79. if(isset($samArr[$x2]['group']['r'])){//判断本点是否已出现在横向组里
  80. $samArr[$x2]['group']['l'] = $key;
  81. }
  82. }
  83. $samArr += $y;
  84. $group ++;
  85. }
  86. }
  87. }
  88. //获得列上相连色块end
  89. //查找相连色块start
  90. $res = array();//相连色块集合
  91. $hasRes = array();
  92. foreach($samArr as $k => $v){
  93. if(isset($hasRes[$k])){
  94. continue;
  95. }
  96. $arr = array();
  97. seek($samArr, $v, $arr);
  98. $res[] = array_keys($arr);
  99. $hasRes += $arr;
  100. }
  101. //查找相连色块end
  102. show($xxl);//打印消除前的图形
  103. if(empty($res)){//如果没有相连色块则退出递归
  104. echo '=================================消除完毕!==================================';
  105. return $point;
  106. }
  107. $thisPoint = countPoint($res);//计算本次消除获得积分
  108. $point += $thisPoint;//累计到总积分
  109. //消除相连色块start
  110. $next = $xxl;
  111. foreach($res as $k => $v){
  112. foreach($v as $k2 => $v2){
  113. $y = $samArr[$v2][0];
  114. $x = $samArr[$v2][1];
  115. $xxl[$y][$x] = '*';
  116. unset($next[$y][$x]);
  117. }
  118. }
  119. //消除相连色块end
  120. show($xxl);//打印消除时的图形
  121. $next = step($next);
  122. show($next);//打印消除后的图形
  123. echo "本次消除获得积分数量:{$thisPoint}\n";
  124. return play($next, $point);
  125. }
  126. /*计算获得积分数量
  127. *$xxl array 相连色块集合
  128. */
  129. function countPoint($xxl){
  130. //初始化积分配置start
  131. $config = array(3 => 10, 4 => 15, 5 => 20, 6 => 30, 7 => 40, 8 => 70, 9 => 100);
  132. for($i = 10; $i <= 64; $i++){
  133. $config[$i] = 100 + ($i - 9) * 50;
  134. }
  135. //初始化积分配置end
  136. $point = 0;
  137. foreach($xxl as $v){
  138. $key = count($v);
  139. $point += $config[$key];
  140. }
  141. return $point;
  142. }
  143. /*消掉并左移
  144. *$xxl array 所有图形集合
  145. */
  146. function step($xxl){
  147. foreach($xxl as $k => $v){
  148. $temp = array_merge($v);
  149. $count = count($temp);
  150. if($count == 8){
  151. continue;
  152. }
  153. for($i = $count; $i <= 7; $i++){
  154. $temp[$i] = ' ';
  155. }
  156. $xxl[$k] = $temp;
  157. }
  158. return $xxl;
  159. }
  160. /*找相邻点
  161. *$xxl array 相连图形集合
  162. *$one array 某一个点
  163. *$arr array 图形集合里的相邻的点
  164. */
  165. function seek($xxl, $one, &$arr){
  166. // global $i;
  167. $near = array();
  168. $near['up'] = ($one[0] - 1).'-'.$one[1];//上面的点
  169. $near['down'] = ($one[0] + 1).'-'.$one[1];//下面的点
  170. $near['left'] = $one[0].'-'.($one[1] - 1);//左面的点
  171. $near['right'] = $one[0].'-'.($one[1] + 1);//右面的点
  172. foreach($near as $v){
  173. if(isset($xxl[$v]) && $xxl[$v][2] == $one[2]){//找到相邻点
  174. $xj = array_intersect($one['group'], $xxl[$v]['group']);
  175. if(empty($xj)){//如果相邻的点不是本组的就跳过
  176. continue;
  177. }
  178. if(isset($arr[$v])){//如果该点已被遍历过则跳过
  179. continue;
  180. }
  181. $arr[$v] = $xxl[$v];
  182. seek($xxl, $xxl[$v], $arr);//继续找相邻的点
  183. }
  184. }
  185. }
  186. /*打印图形
  187. *$xxl array 所有图形集合
  188. */
  189. function show($xxl){
  190. //顺时针旋转矩阵start
  191. $arr = array();
  192. foreach($xxl as $k => $v){
  193. foreach($v as $k2 => $v2){
  194. $arr[7-$k2][$k] = $v2;
  195. }
  196. }
  197. ksort($arr);
  198. //顺时针旋转矩阵end
  199. $str = '';
  200. foreach($arr as $v){
  201. foreach($v as $v2){
  202. $str .= ' '.$v2;
  203. }
  204. $str .= "\n";
  205. }
  206. echo "\n".$str;
  207. }

运行结果如下:

12345分别代表5种颜色。


  1. =================================开始第1步==================================
  2. 3 3 2 2 1 1 1 4
  3. 4 3 4 3 4 1 1 3
  4. 3 1 4 1 1 4 1 2
  5. 2 3 4 3 1 2 4 4
  6. 4 2 4 2 2 2 1 4
  7. 3 3 2 1 2 3 1 1
  8. 5 2 1 3 2 1 4 5
  9. 3 4 5 1 3 2 3 3
  10. 3 3 2 2 * * * 4
  11. 4 3 * 3 4 1 * 3
  12. 3 1 * 1 1 4 * 2
  13. 2 3 * 3 1 2 4 4
  14. 4 2 * * * * 1 4
  15. 3 3 2 1 * 3 1 1
  16. 5 2 1 3 * 1 4 5
  17. 3 4 5 1 3 2 3 3
  18. 3 3 4
  19. 4 3 2 3
  20. 3 1 3 1 2
  21. 2 3 1 4 4 4
  22. 4 2 2 3 4 2 1 4
  23. 3 3 2 1 1 3 1 1
  24. 5 2 1 3 1 1 4 5
  25. 3 4 5 1 3 2 3 3
  26. 本次消除获得积分数量:55
  27. =================================开始第2步==================================
  28. 3 3 2 2 3 3 2 4
  29. 4 3 3 2 1 3 3 3
  30. 3 1 3 3 4 1 4 2
  31. 2 3 5 1 2 4 4 4
  32. 4 2 2 3 4 2 1 4
  33. 3 3 2 1 1 3 1 1
  34. 5 2 1 3 1 1 4 5
  35. 3 4 5 1 3 2 3 3
  36. 3 3 2 2 3 3 2 4
  37. 4 3 3 2 1 * * *
  38. 3 1 3 3 4 1 4 2
  39. 2 3 5 1 2 * * *
  40. 4 2 2 3 4 2 1 4
  41. 3 3 2 1 1 3 1 1
  42. 5 2 1 3 1 1 4 5
  43. 3 4 5 1 3 2 3 3
  44. 3 3 2 2 3
  45. 4 3 3 2 1
  46. 3 1 3 3 4 3 2 4
  47. 2 3 5 1 2 1 4 2
  48. 4 2 2 3 4 2 1 4
  49. 3 3 2 1 1 3 1 1
  50. 5 2 1 3 1 1 4 5
  51. 3 4 5 1 3 2 3 3
  52. 本次消除获得积分数量:20
  53. =================================开始第3步==================================
  54. 3 3 2 2 3 4 1 3
  55. 4 3 3 2 1 4 2 5
  56. 3 1 3 3 4 3 2 4
  57. 2 3 5 1 2 1 4 2
  58. 4 2 2 3 4 2 1 4
  59. 3 3 2 1 1 3 1 1
  60. 5 2 1 3 1 1 4 5
  61. 3 4 5 1 3 2 3 3
  62. =================================消除完毕!==================================
  63. 共获得积分数量:75

总结

以上就是php实现开心消消乐的算法的过程分享的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行