首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Othello -寻找可供选择的游戏的算法

Othello -寻找可供选择的游戏的算法
EN

Stack Overflow用户
提问于 2017-06-24 13:03:32
回答 1查看 6.3K关注 0票数 1

我正在尝试使用Java开发Othello游戏,我正在努力实现查找可用的移动,玩家有(而不是计算机)。

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

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

我正在努力实现3和5。

我如何遍历所有的方向(如果我在板的内部,最多有8个方向),我怎样才能进一步检查每个方向的颜色?

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

你不需要看代码,我正在努力弄清楚如何接近它(考虑2的循环),但是下面是函数和整个代码:(每个按钮都有一个图标--黑白块)

代码语言:javascript
复制
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行代码了,所以如果你真的想知道我做了什么,我宁愿给出一个链接:-删除-

EN

回答 1

Stack Overflow用户

发布于 2017-06-24 16:45:43

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

代码语言:javascript
复制
    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方法接受某些方向并在其中导航,直到到达空单元格或边框。对于每个非空单元格,调用传递的handleCellCellHandler。所以现在您的checkLegalPlay变得简单了:实现CheckCellHandler并遍历所有可能的方向,看看我们是否可以朝这个方向翻转。实现实际的翻转逻辑实际上非常相似:只需实现FlipCellHandler并以类似的方式使用它。请注意,您还可以通过显式地将myIconotherIcon传递给处理程序来抽象“当前播放器”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44736696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档