加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

利用PHP实现开心消消乐的算法示例

发布时间:2021-03-15 12:24:53 所属栏目:PHP教程 来源:网络整理
导读:前言 本文主要介绍了关于PHP如何实现我们大家都知道的开心消消乐的算法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 一、需求描述: 1、在一个8*8的矩阵方格中随机出现5种颜色的色块。 2、当有三个或以上色块在横向或纵向上相连,则
副标题[/!--empirenews.page--]

前言

本文主要介绍了关于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分。

二、上代码

/开始消除
$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,$k1 .'-'. $k2 .'-'. $v2);
}

if($k2 === 0){
$sam[$now][$k1 .'-'. $k2] = array($k1,$k1 .'-'. $k2 .'-'. $v2);
}else{
if($v2 != $xxl[$k1][$k2-1]){//同一行上和前一个颜色不一样
$now++;
}
$sam[$now][$k1 .'-'. $k2] = array($k1,$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);//继续找相邻的点
}
}
}

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读