【问题标题】:TicTacToe resizable board, WIN method errorTicTacToe 可调整大小的棋盘,WIN 方法错误
【发布时间】:2014-10-18 04:11:41
【问题描述】:

您好,刚刚尝试了一个井字游戏项目,但遇到了一个错误。我的错误与检查获胜解决方案特别是对角线有关。

我需要什么: 创建嵌套循环以沿对角线向下循环数组,然后将其递增,使其沿对角线向下扫描或扫描到该大小,直到最终扫描整个数组。

我做了什么: 我尝试创建一个嵌套的 for 循环,该循环将遍历行并将其添加到计数器直到行的末尾,然后检查计数器是否等于内联(赢得所需的一行中的数量)。我相信它适用于行和列。

问题: 但是对于对角线,我得到一个数组越界异常,我认为这是因为我的 ab 被添加到可能是 gameBoard 的 i [3][4] 当谈到 3x3 游戏板时。

尝试解决: 我尝试了一个解决方案,您可以看到它奇怪地放置了带有 j 的 for 循环。这样我就只会去 j 而不会超过数组限制。

我想知道这背后的逻辑是否可行?

对不起,如果代码很混乱,尤其是添加的 for 循环包含 j

/*
 * Method winner will determine if the symbol (X or O) wins
 *
 * @param symbol will be either X or O
 * @return will return true if the symbol has won from any of the methods
 */
public boolean winner(char symbol) {

  int counter = 0;

  /* Scan from ROWS for any symbols inline to win */

  for (int i = 0; i < gameBoard.length; i++) { // loop through the rows
    for (int j = 0; j < gameBoard.length; j++) { // Loop through the columns
      if (gameBoard[i][j] == symbol) {
        counter++;
      }
      if (gameBoard[i][j] != symbol) { // If the next one in the row is not equal then reset counter to 0
        counter = 0;
      }
      if (counter == inline) { // Counter will only equal inline if there is amount of inliine in a row
        return true;
      }
    }
  }

  /* Scan and search for winning conditions in COLUMNS */
  for (int i = 0; i < gameBoard.length; i++) { // loop through the rows
    for (int j = 0; j < gameBoard.length; j++) { // Loop through the columns
      if (gameBoard[j][i] == symbol) {
        counter++;
      }
      if (gameBoard[j][i] != symbol) { // Reset counter to 0 if not equal to symbol 
        counter = 0;
      }
      if (counter == inline) { // If counter reached amount of inline then it must have had amount of inline in a row to win
        return true;
      }
    }
  }

  /* Scan for RIGHT DIAGONALS for winning conditions */

  // a shifts the position of diagonal to the right by one
  // after diagonally looping through the board
  for (int a = 0; a < gameBoard.length; a++) {

    // i loops diagonally through the board
    for (int j = gameBoard.length; j < 0; j--) {
      for (int i = 0; i < j; i++) {
        if (gameBoard[i][i + a] == symbol) {
          counter++;
        }
        if (gameBoard[i][i + a] != symbol) {
          counter = 0;
        }
        if (counter == inline) {
          return true;
        }
      }
    }
  }

  // b shifts the position of the diagonal down by one
  for (int b = 1; b < gameBoard.length; b++) {

    for (int j = gameBoard.length - 1; j < 0; j--)
    // i loops diagonally through the board
      for (int i = 0; i < j; i++) {
      if (gameBoard[i + b][i] == symbol) {
        counter++;
      }
      if (gameBoard[i + b][i] != symbol) {
        counter = 0;
      }
      if (counter == inline) {
        return true;
      }
    }
  }

  /* Scan for LEFT DIAGONALS for winning conditions */

  // a shifts the position of diagonal to the left by one
  for (int a = gameBoard.length; a >= 0; a--) {
    for (int j = gameBoard.length; j < 0; j--) {
      // i loops diagonally through the board
      for (int i = 0; i < j; i++) {
        if (gameBoard[i][a - i] == symbol) {
          counter++;
        }
        if (gameBoard[i][a - i] != symbol) {
          counter = 0;
        }
        if (counter == inline) {
          return true;
        }
      }
    }
  }

  // b shifts the position of the diagonal down by one
  for (int b = 0; b < gameBoard.length; b++) {
    for (int j = gameBoard.length - 1; j < 0; j--) {
      // i loops diagonally in the left direction of through the board
      for (int i = 0; i < j; i++) {
        if (gameBoard[i + b][gameBoard.length - i] == symbol) {
          counter++;
        }
        if (gameBoard[i + b][gameBoard.length - i] != symbol) {
          counter = 0;
        }
        if (counter == inline) {
          return true;
        }
      }
    }
  }


  return false; // If it reaches here then no one has won yet and the game is ongoing

}

【问题讨论】:

  • +1,在编辑之前对您的外部安排非常满意!

标签: java arrays tic-tac-toe


【解决方案1】:

据我在您的代码中看到的,您必须得到Array Index Out Of Bounds Exception。我假设您尝试实现经典的井字游戏,所以我们正在处理 3x3 矩阵。以下是您的游戏板的索引方式:

[0.0] [1.0] [2.0]

[0.1] [1.1] [2.1]

[0.2] [1.2] [2.2]

这就是右对角线循环中发生的情况:
int a 递增 0 --> 2
int j 递减 2 --> 0
int i 递增 0 --> 2


所以你的循环是这样的:
[0.0+0] --> i++ [1.1+0] --> i++ [2.2+0] j--
[0.0+0] --> i++ [1.1+0] j--
[0.0+0] 一个++
[0.0+1] --> i++ [1.1+1] --> i++ [2.2+1] j--


此外,在通过主对角线检查后,您将通过 [0.0] [1.1],它根本不是对角线,并且您已经在行的循环中执行了此操作。甚至不需要通过底部对角线移动([0.1][1.2]),因为您之前已经在循环中这样做了。所以检查 [0.0] [1.1] [2.2] 会为你工作。


我认为这是检查获胜条件的无效方法。只需存储找到元素的位置,您就可以摆脱 3 个循环。

【讨论】:

  • 问题现在真的很清楚了,感谢您的回答。在我添加那些奇怪的 for 循环之前,我遇到了问题,现在我意识到我做得多么无效。我刚刚添加了 for 循环,希望修复扫描通过数组。我使用 for 循环的目标只是扫描每个对角线行。但是井字游戏在自定义板尺寸和自定义内联(连续获胜所需的数量)上运行。想知道这种方法是否适用于大型定制尺寸的井字游戏。
【解决方案2】:

抱歉,无法获取 cmets 的格式,所以我将在这里发布我得到的内容

/* Scan for RIGHT DIAGONALS for winning conditions */

int j = gameBoard.length

  for (int a = 0; a < gameBoard.length; a++) {

// i loops diagonally through the board
  for (int i = 0; i < j; i++) {
    if (gameBoard[i][i + a] == symbol) {
      counter++;
    }
    if (gameBoard[i][i + a] != symbol) {
      counter = 0;
    }
    if (counter == inline) {
      return true;
    }
  } j--; // Incrementing after the i for loop.
}

output: 
a:0 i:0 j:3 
[0.0+0] --> i++ [1.1+0] --> i++ [2.2+0] /*end for loop. i:2 j:3 a: 0 */ 
j-- a++ 
[0.0+1] --> i++ [1.1+1] /*end for loop. i:1   j:2 a: 1*/ 
j-- a++ 
[0.0+2] /* end for loop. i:0 j: 1 a:2 */

并且数组在检查对角线时保持在边界内。所以我认为think可以在更大范围内发挥作用。

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 1970-01-01
    • 2021-11-22
    • 2015-01-24
    • 2020-05-17
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多