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