资讯专栏INFORMATION COLUMN

用PHP实现开心消消乐算法

tain335 / 2649人阅读

摘要:一需求描述在一个的矩阵方格中随机出现种颜色的色块。当有三个或以上色块在横向或纵向上相连,则消除这些色块。开始第步本次消除获得积分数量开始第步本次消除获得积分数量开始第步消除完毕共获得积分数量

一、需求描述:
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($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}
";
    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 .= "
";
    }
    echo "
".$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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30618.html

相关文章

  • 【Pygame实战】开心——消消,你,我,大家~

    摘要:正文开心消消乐分为二部分首先是开心然后是消消乐游戏嘛嘿嘿一开心小故事三则近视聪明的学生杀手二消消乐游戏素材图片开心消消乐语音提示环境安装本文是由写的小游戏。 导语 你今天消消乐了吗? ​ 哈喽哈喽~木木子之前不是写过一篇百变消消乐嘛? 可能你们不记得了,没关系——今天重温一下,来一篇开心?...

    changfeng1050 评论0 收藏0
  • Python生成歌词词云

    摘要:上面是生成词云的方法封装,还有一些其他方法根据词频生成词云根据文本生成词云根据词频生成词云根据文本生成词云将长文本分词并去除屏蔽词此处指英语,中文分词还是需要自己用别的库先行实现,使用上面的对现有输出重新着色。 对于数据展示这一块有时候会用到词云,python中提供的wordcloud模块可以很灵活的完成生成词云除了使用python提供的wordcloud模块以为还有在线的生成方式ht...

    junbaor 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<