计算威胁

时间:2014-03-11 13:29:45

标签: java

我必须使用模拟智能实现connect4。它已经有效,但速度很慢。我们必须得到两个玩家的威胁。威胁是行中3个硬币,行末端或行尾有空字段。我想在每次移动后只计算新的威胁,并删除不再受到威胁的威胁。如果最后一步有新的威胁,我会写一些方法来检查每个方向。

private Field row(int row, int column, String Player) {
        Field field = null;
        if(column - 1 >= 0 && column + 1 < board.getColumn() && board.getValue(row, column-1).equals(Player)
                && board.getValue(row, column+1).equals(Player)) {
            if(column -2 >= 0 &&board.getValue(row, column-2).equals(" ")) {
                return field = new Field(row, column -2);
            }
            else if(column + 2 < board.getColumn()&& board.getValue(row, column+2).equals(" ")) {
                return field = new Field(row, column +2);
            }
        }

        else if(column - 2 >= 0  && board.getValue(row, column-1).equals(Player)
                && board.getValue(row, column-2).equals(Player)) {
            if(column -3 >= 0 &&board.getValue(row, column-3).equals(" ")) {
                return field =  new Field(row, column -3);
            }
            else if(column +1 < board.getColumn()&& board.getValue(row, column+1).equals(" ")) {
                return field =  new Field(row, column +1);
            }
        }
        else if(column +2 < board.getColumn()  && board.getValue(row, column+1).equals(Player)
                && board.getValue(row, column+2).equals(Player)) {
            if(column -1 >= 0 &&board.getValue(row, column-1).equals(" ")) {
                return field =  new Field(row, column -1);
            }
            else if(column +3 < board.getColumn()&& board.getValue(row, column+3).equals(" ")) {
                return field =  new Field(row, column +3);
            }
        }
        else if(column - 2 >= 0  && column + 1 < board.getColumn() && board.getValue(row, column-2).equals(Player)
                && board.getValue(row, column+1).equals(Player)) {
            if(column -1 >= 0 &&board.getValue(row, column-1).equals(" ")) {
                return field = new Field(row, column -1);
            }

        }
        else if(column - 1 >= 0  && column +2 < board.getColumn() && board.getValue(row, column-1).equals(Player)
                && board.getValue(row, column+2).equals(Player)) {
            if(column +1 < board.getColumn() &&board.getValue(row, column+1).equals(" ")) {
                return field = new Field(row, column +1);
            }

        }

        else if(column - 3  >= 0 && board.getValue(row, column-2).equals(Player) && board.getValue(row, column-3).equals(Player)) {
            if(board.getValue(row, column-1).equals(" ")) {
                return new Field (row, column -1);
            }
        }
        else if(column-3 >= 0 && board.getValue(row, column-1).equals(Player) && board.getValue(row, column-3).equals(Player)) {
            if(board.getValue(row, column-2).equals(" ")) {
                return new Field(row, column - 2);
            }
        }
        else if(column + 3 < board.getColumn() && board.getValue(row, column+2).equals(Player) && board.getValue(row, column+3).equals(Player)) {
            if(board.getValue(row, column+1).equals(" ")) {
                return new Field(row, column + 1);
            }
        }
        else if(column + 3 < board.getColumn() && board.getValue(row, column+1).equals(Player) && board.getValue(row, column+3).equals(Player)) {
            if(board.getValue(row, column+2).equals(" ")) {
                return new Field(row, column +2);
            }
        }
        return field;
    }

private Field column(int row, int column, String Player) {
        Field field = null;
        if (row + 2 < board.getRow()
                && board.getValue(row + 1, column).equals(Player)
                && board.getValue(row + 2, column).equals(Player)) {
            if(row-1 >= 0 && board.getValue(row-1, column).equals(" ")) {
                return field =  new Field(row-1, column);
            }

        }
        return field;
    }

private Field diagonalRight(int row, int column, String Player) {
        Field field = null;
        if(row - 1 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 1 < board.getColumn()
                && board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row-1, column+1).equals(Player)) {
            if(row + 2 < board.getRow() && column - 2 >= 0 && board.getValue(row+2, column-2).equals(" ")) {
                return field = new Field(row+2, column - 2);
            }
            else if (row - 2 >=0 && column + 2 < board.getColumn() && board.getValue(row-2, column+2).equals(" ")) {
                return field = new Field(row-2, column + 2);
            }
        }
        else if(row + 2 < board.getRow() && column - 2 >= 0 && board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row+2, column-2).equals(Player)) {
            if(row +3 < board.getRow() && column - 3 >= 0 && board.getValue(row+3, column-3).equals(" ")) {
                return field = new Field(row+3, column - 3);
            }
            else if (row - 1 >=0 && column + 1 < board.getColumn() && board.getValue(row-1, column+1).equals(" ")) {
                return field = new Field(row-1, column + 1);
            }
        }
        else if(row - 2 >= 0 && column +2 < board.getColumn() && board.getValue(row- 1, column+1).equals(Player)&& board.getValue(row-2, column+2).equals(Player)) {
            if(row -3>= 0 && column + 3 < board.getColumn() && board.getValue(row-3, column+3).equals(" ")) {
                return field = new Field(row-3, column +3);
            }
            else if (row + 1 < board.getRow() && column -1 >=0 && board.getValue(row+1, column-1).equals(" ")) {
            return field = new Field(row+1, column -1);
            }
        }

        else if(row - 2 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 2 < board.getColumn()
                && board.getValue(row+ 1, column-1).equals(Player)&& board.getValue(row-2, column+2).equals(Player)) {


             if (row - 1 >=0 && column + 1 < board.getColumn() && board.getValue(row-1, column+1).equals(" ")) {
                return field = new Field(row-1, column + 1);
            }
        }
        else if(row + 2 < board.getRow() && column -2 >= 0 && row - 1 >= 0 && column + 1 < board.getColumn()
                && board.getValue(row+ 2, column-2).equals(Player)&& board.getValue(row-1, column+1).equals(Player)) {


             if (row + 1 < board.getRow() && column - 1 >= 0 && board.getValue(row+1, column-1).equals(" ")) {
                return field = new Field(row+1, column - 1);
            }
        }

        else if(row + 3 < board.getRow() && column  + 3 < board.getColumn() && board.getValue(row + 2, column+2).equals(Player) && board.getValue(row+3, column+3).equals(Player)) {
            if( board.getValue(row+1, column+1).equals(" ")) {
                return new Field(row+1, column +1);
            }

        }
        else if(row + 3 < board.getRow() && column + 3 < board.getColumn() && board.getValue(row+3, column+3).equals(Player) && board.getValue(row+1, column+1).equals(Player)) {
            if(board.getValue(row+2, column+2).equals(" ")) {
                return new Field (row +2, column + 2);
            }
        }
        else if(row - 3 >= 0 && column - 3 >= 0 && board.getValue(row-3, column-3).equals(Player) && board.getValue(row-2, column-2).equals(Player)) {
            if(board.getValue(row-1, column-1).equals(" ")) {
                return new Field(row-1, column -1);
            }
        }
        else if(row-3 >=0 && column -3>= 0 && board.getValue(row-3, column-3).equals(Player) && board.getValue(row-1, column-1).equals(Player)) {
            if(board.getValue(row-2, column-2).equals(" ")) {
                return new Field (row-2, column - 2);
            }
        }
        return field ;

    }

private Field diagonalLeft(int row, int column, String Player) {
        Field field = null;
        if(row - 1 >= 0 && column - 1 >= 0 && row + 1 < board.getRow() && column + 1 < board.getColumn()
                && board.getValue(row+ 1, column+1).equals(Player)&& board.getValue(row-1, column-1).equals(Player)) {
            if(row + 2 < board.getRow() && column + 2 < board.getColumn() && board.getValue(row+2, column+2).equals(" ")) {
                return field = new Field(row+2, column + 2);
            }
            else if (row - 2 >=0 && column - 2 >=0 && board.getValue(row-2, column-2).equals(" ")) {
                return field = new Field(row-2, column - 2);
            }
        }
        else if(row + 2 < board.getRow() && column + 2 < board.getColumn()&& board.getValue(row+ 1, column+1).equals(Player)&& board.getValue(row+2, column+2).equals(Player)) {
            if(row +3 < board.getRow() && column + 3 < board.getColumn() && board.getValue(row+3, column+3).equals(" ")) {
                return field = new Field(row+3, column + 3);
            }
            else if (row - 1 >=0 && column - 1 >=0 && board.getValue(row-1, column-1).equals(" ")) {
                return field = new Field(row-1, column - 1);
            }
        }
        else if(row - 2 >= 0 && column -2 >=0 && board.getValue(row- 1, column-1).equals(Player)&& board.getValue(row-2, column-2).equals(Player)) {
            if(row -3>= 0 && column - 3 >= 0 && board.getValue(row-3, column-3).equals(" ")) {
                return field = new Field(row-3, column -3);
            }
            else if (row + 1 < board.getRow() && column +1 <board.getColumn() && board.getValue(row+1, column+1).equals(" ")) {
                return field = new Field(row+1, column +1);
            }
        }

        else if(row - 1 >= 0 && column - 1 >= 0 && row + 2 < board.getRow() && column + 2 < board.getColumn()
                && board.getValue(row- 1, column-1).equals(Player)&& board.getValue(row+2, column+2).equals(Player)) {


             if (row + 1 < board.getRow() && column + 1 < board.getColumn() && board.getValue(row+1, column+1).equals(" ")) {
                return field = new Field(row+1, column + 1);
            }
        }
        else if(row + 1 < board.getRow() && column -2 >= 0 && row - 2 >= 0 && column + 1 < board.getColumn()
                && board.getValue(row- 2, column-2).equals(Player)&& board.getValue(row+1, column+1).equals(Player)) {


             if (row - 1 >= 0 && column - 1 >= 0 && board.getValue(row-1, column-1).equals(" ")) {
                return field = new Field(row-1, column - 1);
            }
        }

        else if(row - 3 >=0 && column  + 3 < board.getColumn() && board.getValue(row - 2, column+2).equals(Player) && board.getValue(row-3, column+3).equals(Player)) {
            if( board.getValue(row-1, column+1).equals(" ")) {
                return new Field(row-1, column +1);
            }

        }
        else if(row - 3 >=0 && column + 3 < board.getColumn() && board.getValue(row-3, column+3).equals(Player) && board.getValue(row-1, column+1).equals(Player)) {
            if(board.getValue(row-2, column+2).equals(" ")) {
                return new Field (row -2, column + 2);
            }
        }
        else if(row + 3 < board.getRow() && column - 3 >= 0 && board.getValue(row+3, column-3).equals(Player) && board.getValue(row+2, column-2).equals(Player)) {
            if(board.getValue(row+1, column-1).equals(" ")) {
                return new Field(row+1, column -1);
            }
        }
        else if(row+3 < board.getRow() && column -3>= 0 && board.getValue(row+3, column-3).equals(Player) && board.getValue(row+1, column-1).equals(Player)) {
            if(board.getValue(row+2, column-2).equals(" ")) {
                return new Field (row+2, column - 2);
            }
        }
        return field;
    }

方法真的很高,也有错误......但我找不到它。你能给我一些提示,告诉我如何更好地实施这些方法吗? 谢谢

编辑1:

perhebs你应该只看第一种方法。我采取最后一步行动,检查是否包含最后一步的威胁。所以如果在同一个玩家的行中有两个以上的硬币会造成威胁,我就会嗤之以鼻。大A是最后一个Move,我想检查teh是否是小a,以便他们制造威胁:

| | a | A | a | | | | 例如,我检查A的字段右边是a是否A的字段是a,如果这是真的,我检查是否有一个空字段围绕它,这样你就可以连续4行

| | | A | a | a | | |

| a | a | A | | | | |

| | | A | a | | A | |

| | | A | | | A | A |

等等..我检查威胁的每一种可能性。在行之后,我为列和对角线

执行此操作

你看到了更好的解决方案吗?

编辑2:

private Field row(int row, int column, int Player) {
        Field field = null;
        int j = 0;
        boolean check = false;
        if(column + 3 < board.getColumn()) {
            for(int i = column; i< column + 4; i++) {
                if(board.getValue(row, i).equals(Player)){
                    j++;
                }
                else if(board.getValue(row, i).equals(" ") && check == false) {
                    j++;
                    check = true;
                    field = new Field(row,i);
                }
            }
            if(j == 4) {
                return field;
            }
        }
        return null;
    }

我将从4个不同点调用该方法。你这个会起作用吗?

3 个答案:

答案 0 :(得分:2)

为什么以一切神圣的名义,你有相同的血腥代码复制粘贴N次?唯一的区别是血腥数字会发生变化。在循环中重写它们,然后只有一个点来检查是否正确。

答案 1 :(得分:1)

如果您有不同的概念,我认为您的代码会更好很多,例如:

1,检查方向的方法:diagonalChecker(2x),verticalChecker,horizo​​ntalChecker。这些方法是在循环中检查来自一个方向的威胁(例如coulmn是x,row是

for(row = n; row<n+4; row++) {
...
}

2,如果您知道这些方法不会构成威胁,请暂停这些方法

3,从新硬币周围的不同起点调用这些方法。可能有一个循环。

+1 :也许您应该查看this解决方案并获得一些想法

如果您的解决方案更清晰,也会更容易发现错误。

更新到您的更新:我会做大致类似的事情(没有经过测试,只是为了这个想法):

对不同的玩家使用枚举会更好。

enum Player {
    RED, BLUE
}

使rowCheck尽可能简单:

private boolean rowCheck(int row, int column, Player player) {
    boolean isThreeOfTheSameInOneRow = true;

    for (int i = column; i < column + 4; i++) {
        if (!boundariesCheck(row, i) || !board.getValue(row, i).equals(player)) {
      isThreeOfTheSameInOneRow = false;
      break;
    }

    return isThreeOfTheSameInOneRow;
}

这样你就可以在一个地方检查边界。您可能希望将其拆分为2(列和行)。

private boolean boundariesCheck(int row, int column) {
        boolean result = false;
        if (0 < column && column < board.getColumn() && 0 < row && row < board.getRow()) {
            result = true;
        }
        return result;
    }

答案 2 :(得分:0)

你可以简化这些事情。主要是通过使用for - 循环和一些执行边界检查的实用程序方法。

在更大的范围内:你在那里做的只是一个“真正的人工智能”的一小步。事实上,当你想为这么简单的棋盘游戏编写一个AI时,只有三件事是必须的:

  • 你必须能够行动
  • 您必须能够评估当前的情况(即:对于玩家来说是好还是坏?)
  • 您必须能够撤消移动

这三种简单的方法已经允许您实现MiniMax算法(http://en.wikipedia.org/wiki/Minimax)。对于像“连接四”这样的简单游戏,即使是最简单的算法实现也很容易击败任何休闲玩家。 (并且......有“Connect Four”的认真的玩家吗?)。如果你想要更复杂的AI,它甚至可以扩展为使用Alpha-Beta-Pruning(http://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning)。

然而:您可能想要考虑结合检查玩家是否已经赢了,以及您在那里尝试的检查 - 即如果玩家能够获胜,如果他放置在特定位置。当你已经有一个方法来检查玩家是否赢了,你可以通过

检查玩家是否获胜
  • “虚拟地”执行有问题的移动
  • 检查玩家是否赢了
  • 撤消“虚拟”移动

这个实现粗略看起来像这样。 (不是为优雅或效率而优化,而是为了简单和希望直观......)

private boolean canWinByPlacingOn(String player, int r, int c)
{
    if (board.getValue(r, c).equals(" "));
    {
        board.setValue(r, c, player);
        boolean hasWon = hasWon(player);
        board.setValue(r, c, " ");
        if (hasWon)
        {
            return true;
        }
    }
    return false;
}

private boolean hasWon(String player)
{
    int maxR = board.getRow()-4;
    int maxC = board.getColumn()-4;
    for (int r=0; r<maxR; r++)
    {
        for (int c=0; c<maxC; c++)
        {
            if (startsLineAt(player, r, c, 1, 0))
            {
                return true;
            }
            if (startsLineAt(player, r, c, 0, 1))
            {
                return true;
            }
            if (startsLineAt(player, r, c, 1, 1))
            {
                return true;
            }
        }
    }
    return false;
}

private boolean startsLineAt(String player, int r, int c, int dr, int dc)
{
    for (int i=0; i<4; i++)
    {
        String current = board.getValue(r, c);
        if (!current.equals(player))
        {
            return false;
        }
        r += dr;
        c += dc;
    }
    return true;
}