2D 阵列帮助(井字游戏)


   public boolean isWin()
    {

       boolean winner= false;
       //checks rows first
       if(gameBoard[currentRow][0]==playerOne&&gameBoard[currentRow][1]==playerOne&&gameBoard[currentRow][2]==playerOne)
       {
           winner= true;
       }
       else if(gameBoard[currentRow][0]==playerTwo&&gameBoard[currentRow][1]==playerTwo&&gameBoard[currentRow][2]==playerTwo)
       {
           winner= true;
       }
       //checks columns next
       if(gameBoard[0][currentCol]==playerOne&&gameBoard[1][currentCol]==playerOne&&gameBoard[2][currentCol]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[0][currentCol]==playerTwo&&gameBoard[1][currentCol]==playerTwo&&gameBoard[2][currentCol]==playerTwo)
       {
           winner=true;
       }
       //checks one diagonal
       if(gameBoard[0][0]==playerOne&&gameBoard[1][1]==playerOne&&gameBoard[2][2]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[0][0]==playerTwo&&gameBoard[1][1]==playerTwo&&gameBoard[2][2]==playerTwo)
       {
           winner=true;
       }
       //checks other diagonal
       if(gameBoard[2][0]==playerOne&&gameBoard[1][1]==playerOne&&gameBoard[0][2]==playerOne)
       {
           winner=true;
       }
       else if(gameBoard[2][0]==playerTwo&&gameBoard[1][1]==playerTwo&&gameBoard[0][2]==playerTwo)
       {
           winner=true;
       }
       return winner;
   }

此代码测试标准 3 x 3 井字游戏的胜利。我的问题是,我将如何更改内部的数字以匹配任何大小的棋盘,例如 n x n?

目前,它检查第一行、第二行和第三行,以检查任何玩家是否在任何一行中获胜,接下来是列和对角线。但是,当电路板大小更改为其他任何内容时,这不再成立,因为它不会检查每个可能的行/列/对角线。那么我该如何让它为尺寸为 n x n 的板做到这一点。请不要代码,因为我不想抄袭,但如果有人可以提供意见,将不胜感激?

一个非常缓慢但可以保证有效的方法是,如果你遍历数组,如果单元格不为空,请检查周围的所有单元格 - 如果你找到一个由相同单元格类型(圆形或x(组成的线型,那么你就找到了赢家。如果找不到线条图案,请移动到下一个单元格并重复该过程,直到覆盖整个棋盘或找到获胜者。

例如,从单元格 0, 0 开始并找到一个 x。 0, 0检查0, 1; 1, 0; 1, 1。未找到获胜模式,因此请转到0, 1并再次检查所有相邻单元格。

我会这样做的方法是编写一个单独的函数,该函数具有字段尺寸和玩家输入,例如:

String whoWinner(int d, int p1, int p2)

一旦你完成了这个,放置 3 嵌套循环(水平、垂直、对角线(,并以以下方式检查每个玩家的获胜条件:

if (arr[i][j]='x') p1+=1;
if (arr[i][j]='o') p2+=1;
if (p1==d) return "P1 wins!";
if (p2==d) return "P2 wins!";

这是一种缓慢的方法,但是字段维度高达1000,我不知道,我认为你应该没有任何问题。

您可以有四个循环 - 一个循环检查水平、垂直、NE-SW 对角线和 NW-SE 对角线。

考虑水平情况:假设您仍然只需要连续三次获胜,您需要检查每一行是否有可能的获胜(即检查同一玩家是否连续三次获胜(。水平三行需要在 n-3 列之前开始,否则它将超过板的边界。因此,通过检查从第 0 列到 n-3 列开始的每个可能的水平三合一行,对于每一行,将找到任何水平获胜。

水平案例示例:

for (int j = 0; j < n; j++) {
    for (int i = 0; i < n-3; i++) {
        if (gameBoard[i][j] == gameBoard[i+1][j] && gameBoard[i][j] == gameBoard[i+2][j]) {
            return true;
        }
    }
}

使用此概念,您还可以检查垂直和对角线获胜。

如果你被允许在你的作业中使用Java 8,那么这是对流的一个非常好的使用。流解决方案如下所示:

  1. 生成表示最多 n 个数字的整数流(提示:IntStream.range (
  2. 将其映射到 2 组值:相应行和列的内容(提示:Stream.flatMap (
  3. 添加到两个对角线的流集(提示:Stream.concat (
  4. 筛选具有单个值的集
  5. 如果你找到任何,你就有一个赢家(提示:Stream.findAny(

如果您不知道流,那么这可能有点令人困惑,但它最终确实会得到一个非常优雅的获胜板表示(即让我所有集合都排成一行,并告诉我是否有任何一组只有一个值(。

这样做的一个很好的功能是,如果需要非常大的电路板,它可以简单地转换为并行流。

最新更新