当前位置: 首页 > 知识库问答 >
问题:

奥赛罗-寻找可用选项的算法

吴星汉
2023-03-14

我正在尝试用Java开发游戏《奥赛罗》,我正在努力寻找玩家可用的动作(而不是电脑)。

比如我是玩家1,我在玩白色的棋子,

  1. 检查按钮是否是空的。(我使用按钮作为瓷砖)
  2. 检查是否有相反颜色的邻居。
  3. 如果有,继续检查每个方向有相反的颜色,直到
  4. 如果我们到达边界-返回false.
  5. 如果我们达到我们的颜色-把所有的碎片变成我的颜色。

我在努力实现3。五,。

我如何迭代通过所有的方向(最大的8个方向,如果我在板的内部部分),我如何可以提前检查每个方向的颜色?

我考虑为内板实现所有8个方向,然后在外板实现所有可能性,并检查边缘选项,这是非常不有效的,我不想这样编码。

您不必查看代码,我正在尝试如何处理它(考虑2个for循环),但下面是函数和整个代码:(每个按钮都有一个图标-黑色/白色部分)

private void checkLegalPlay(int row, int col) {

        if(playerNum == 0){ //Black player
            if(row > 0 && row < 7 && col > 0 && col < 7){ //Inner board - 
                     //not good, i want from any point of the board
                    for(int i = col-1; i != 0; i--)
                        if(squares[row][i].getIcon() != null){
                            if(squares[row][i].getIcon() == blackPiece){
                                //Advance until boundary - return false
                                //Advance if there're black pieces
                                //If we get to white piece, turn all to 
                                //  white pieces
                            }
                        }
                }
            }
        }

它已经有将近300行代码了,所以如果你真的想看看我到目前为止做了什么,我更愿意给你一个链接:-删除-

共有1个答案

东方权
2023-03-14

软件开发是一门抽象的艺术。你应该努力培养一种技能,去发现逻辑片段之间的相似之处,并把它们抽象出来。例如,要检查移动是否合法,您必须应用相同的检查逻辑从单元格的不同方向进行迭代。此外,检查移动和应用移动(翻转片段)共享相同的迭代逻辑。所以让我们把它抽象出来,也就是说,让我们把迭代和我们在迭代中做的逻辑分开:

    private static final int SIZE = 8;

    static boolean isValidPos(int pos) {
        return pos >= 0 && pos < SIZE;
    }


    static class Point {
        public final int row;
        public final int col;

        public Point(int row, int col) {
            this.row = row;
            this.col = col;
        }
    }


    private static final Point[] ALL_DIRECTIONS = new Point[]{
            new Point(1, 0),
            new Point(1, 1),
            new Point(0, 1),
            new Point(-1, 1),
            new Point(-1, 0),
            new Point(-1, -1),
            new Point(0, -1),
            new Point(1, -1),
    };


    interface CellHandler {
        boolean handleCell(int row, int col, Icon icon);
    }


    void iterateCells(Point start, Point step, CellHandler handler) {
        for (int row = start.row + step.row, col = start.col + step.col;
             isValidPos(row) && isValidPos(col);
             row += step.row, col += step.col) {
            Icon icon = squares[row][col].getIcon();
            // empty cell
            if (icon == null)
                break;
            // handler can stop iteration
            if (!handler.handleCell(row, col, icon))
                break;

        }
    }


    static class CheckCellHandler implements CellHandler {
        private final Icon otherIcon;
        private boolean hasOtherPieces = false;
        private boolean endsWithMine = false;

        public CheckCellHandler(Icon otherIcon) {
            this.otherIcon = otherIcon;
        }

        @Override
        public boolean handleCell(int row, int column, Icon icon) {
            if (icon == otherIcon) {
                hasOtherPieces = true;
                return true;
            } else {
                endsWithMine = true;
                return false;
            }
        }

        public boolean isGoodMove() {
            return hasOtherPieces && endsWithMine;
        }
    }

    class FlipCellHandler implements CellHandler {
        private final Icon myIcon;
        private final Icon otherIcon;
        private final List<Point> currentFlipList = new ArrayList<Point>();

        public FlipCellHandler(Icon myIcon, Icon otherIcon) {
            this.myIcon = myIcon;
            this.otherIcon = otherIcon;
        }

        @Override
        public boolean handleCell(int row, int column, Icon icon) {
            if (icon == myIcon) {
                // flip all cells
                for (Point p : currentFlipList) {
                    squares[p.row][p.col].setIcon(myIcon);
                }
                return false;
            } else {
                currentFlipList.add(new Point(row, column));
                return true;
            }
        }
    }


    private boolean checkLegalPlay(int row, int col) {
        ImageIcon otherIcon = (playerNum == 0) ? whitePiece : blackPiece;
        Point start = new Point(row, col);
        for (Point step : ALL_DIRECTIONS) {
            // handler is stateful so create new for each direction
            CheckCellHandler checkCellHandler = new CheckCellHandler(otherIcon);
            iterateCells(start, step, checkCellHandler);
            if (checkCellHandler.isGoodMove())
                return true;
        }
        return false;
    }

ALL_DIRECTIONS表示您可以导航的所有8个方向iterateCells方法接受某个方向,并在其中导航,直到到达空单元格或边框。对于传递的CellHandler的每个非空单元格handleCell,都会被调用。所以现在你的checkLegalPlay变得很简单:实现CheckCellHandler并迭代所有可能的方向,看看我们是否可以朝那个方向翻转。实现实际的翻转逻辑实际上非常相似:只需实现FlipCellHandler,并以类似的方式使用它。请注意,您还可以通过显式地将myIconotherIcon传递给处理程序来抽象“当前玩家”。

 类似资料:
  • 我正在实现一个Alpha Beta修剪算法,该算法将用于在奥赛罗游戏中获得最佳移动。当算法到达叶节点(即没有有效移动或达到最大深度)时,我基于此计算该节点的启发式值: 最大化玩家(正在运行算法并将使用算法返回的移动的玩家)在这个节点的棋盘上有多少块砖块?(每个砖块1块) 最大化玩家在这个节点上有多少有效动作?(每招10) 最大化玩家有多少角砖?(每块角砖100) 问题是:当不是玩家在叶节点中交出的

  • 我有以下奥赛罗(reversi)游戏的阿尔法-贝塔极小值的实现。不知怎的,这永远不会返回正确的行动。它似乎返回了我在函数(0,0)中设置的默认操作和第二个值-32768,这意味着它在MAX子例程中被删减了。关于我可以改进什么以及如何解决这个问题,有什么建议吗? 注意:我已经确定了大部分正确返回的继任者。目前的最大深度是8。电脑玩家的pn(玩家数量)是1,人类玩家的是0。第一阶段,0,是MINIMA

  • 假设我有一个无向多图,即一个(G,E)对,其中G是一个有限的结点集,E是一个有限的边集。我正在寻找一个算法,将分配一个单一的字符串值到每个节点在以下的约束。 1. 每个节点都被赋予一组约束(可能是空的),这些约束限制了允许的值。我希望至少支持以下类型的值约束: null 有两种类型的边缘: 不同, 相同, 这意味着应该为相关节点分配不同/相同的值(意味着不相等/相等的字符串)。 null 这意味着

  • 我正在做一个个人项目,试图找到一个人的长相,因为数据库中有其他人的照片,所有照片都是以一致的方式拍摄的——人们直视相机,表情中立,不歪头(想想护照照片)。 我有一个系统,用于在人脸上放置二维坐标的标记,我想知道是否有任何已知的方法可以在这种方法下找到一张相似的脸? 我找到了以下面部识别算法:http://www.face-rec.org/algorithms/ 但是,没有一个专门负责寻找相貌相似的

  • 为了澄清,这与Eratosthenes的问题Sieve-Finding Primes Python不同,因为我不想在两个数字之间生成素数,但我想检查一个数字是否是素数。 我做了下面的代码来确定一个数字是否是素数。然后我听说了埃拉托色尼算法的筛子,它显然更快,但我不知道如何在下面的代码中编写它? 你们能帮帮我吗?

  • 我有一组排列的数组,我想移除同构排列。 我们有 组排列,其中每个集合包含 个排列,每个排列表示为 元素的数组。我目前将其保存为数组,其中,和是固定的,N大于K。 如果存在将元素从< code>A转换为< code>B的置换< code>P,则两组置换< code>A和< code>B是同构的(例如,如果< code>a是集合< code>A的元素,则< code>P(a)是集合< code>B的元