zoukankan      html  css  js  c++  java
  • 讲讲消灭星星的算法实现思路吧

    这个游戏的关键算法是选取同色区域。

    我的方法是每个方块是一个对象,包含几项属性:自身所在的行,自身所在的列,自身的颜色。

    还加了一个id作备用,暂时没用到。

    基本思路是递归,显而易见。

    首先准备两个列表。

    一个用来装被检查过了的方块,因为左边方块的右边就等于右边方块的左边,如果不检查的话就无限递归到溢出了。

    另一个用来装与传入方块颜色相同的方块,留待递归完成后作为返回值。

    然后传入第一个方块,分别检查它四个方向上的方块,如果颜色和它相同的话就用对应方向上的方块来进行下一次递归。

    上方检测举例,其他方向同理:

    private static void checkUp(Block block) {
        // 越界(上方不存在方块)则跳出。
        if ((block.getRow()-1) < 0) {
            return;
        }
        
        // 获取上方方块。
        Block blockUpside = GameSurfaceView.blockList[block.getRow()-1][block.getColumn()];
        
        // 如果方块不存在或者颜色不同就跳出。
        if (blockUpside == null || blockUpside.getColor() != block.getColor()) {
            return;
        }
        
        // 下一次递归。
        checkFourSides(blockUpside);
    }

    跳出递归的唯一条件是当前方块有没有被检查过,因为考虑到单一职责原则,我把方块对比的代码都放到了单个方向检测的方法里了,包括是否越界和颜色是否相同还有对应方向上的方块存不存在。

    这些是找到了对应方向上的方块才有讨论的必要的。

    比如我看到的那个C++的条件判断是这样的……

    //递归求解
    void MyRecursion(LinkList _head1, LinkList _head2, int _x, int _y, int number) {
        if ((_x >= 10) || (_x < 0) || (_y >= 10) || (_y < 0)
                || (MyTraverseLinkList(_head2, _x, _y)) || (0 == MyArray[_x][_y])) {
            return;
        } else {
            MyInsertLinkList(_head2, _x, _y);
            if ((MyArray[_x][_y] == number)) {
                MyInsertLinkList(_head1, _x, _y);
                if ((_x - 1) >= 0)    //递归 - 上
                        {
                    MyRecursion(_head1, _head2, _x - 1, _y, number);
                }
                if ((_y - 1) >= 0)    //递归 - 左
                        {
                    MyRecursion(_head1, _head2, _x, _y - 1, number);
                }
                if ((_x + 1) < 10)    //递归 - 下
                        {
                    MyRecursion(_head1, _head2, _x + 1, _y, number);
                }
                if ((_y + 1) < 10)    //递归 - 右
                        {
                    MyRecursion(_head1, _head2, _x, _y + 1, number);
                }
            }
        }
    }
    姐夫你不要这样你是有对象的啊

    里面还有重复的边界判断。

    而且这哥们的起名姿势很有特点。

    如果一个方法只做一件事的话,思路就清晰多了,像这样。

    /** 递归,不停检查四面。*/
    private void checkFourSides(Block block) {
        // 如果当前方块已被检查过,则跳出当前递归。
        if (isChecked(block)) {
            return;
        }
        
        // 标记当前方块为已被检查过。
        checkedBlocks.add(block);
        // 将当前方块加入同色列表。
        blocksInSameColor.add(block);
        
        // 检查上下左右的方块。
        checkUp(block);
        checkDown(block);
        checkLeft(block);
        checkRight(block);
    }

    于是像这样,当检查方法碰到边界,或者碰到了不存在的方块,或者周围已经没有颜色相同的方块了的时候,递归停止。

    最后同色列表里保存的就是首尾相连的一片同色方块了。

    然后把整个算法封装起来,再对外暴露一个接口就搞定了。

    /** 获取存有与当前方块颜色相同首尾相连的一片方块的列表。*/
    public static ArrayList<Block> getBlocksInSameColor(Block selectedBlock) {
        // 初始化两个缓存列表。
        checkedBlocks = new ArrayList<Block>();
        blocksInSameColor = new ArrayList<Block>();
        
        // 执行递归。
        checkFourSides(selectedBlock);
        
        return blocksInSameColor;
    }
  • 相关阅读:
    性能测试篇 :Jmeter HTTP代理服务器录制压力脚本
    使用JMeter录制手机App脚本
    WEB接口测试之Jmeter接口测试自动化 (二)(数据分离)
    【Python】Python读取文件报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 20: illegal multibyte sequence
    【Python】学习笔记九:面向对象拓展
    【Python】学习笔记七:函数
    【Python】学习笔记五:缩进与选择
    【Python】学习笔记三:序列
    【Python】学习笔记二:基本数据类型
    【Python】学习笔记一:Hello world
  • 原文地址:https://www.cnblogs.com/chihane/p/3783370.html
Copyright © 2011-2022 走看看