Java 正在检查Connect Four-Kotlin中的赢家

Java 正在检查Connect Four-Kotlin中的赢家,java,kotlin,indexoutofboundsexception,2d-games,Java,Kotlin,Indexoutofboundsexception,2d Games,我正在Kotlin中创建一个简单的Connect-Four程序,使用2D阵列打印电路板。除了我的水平win checker功能外,一切都正常。由于我使用的逻辑,当我试图将您的片段放在第一列时,会出现索引越界错误,因为它试图检查数组中的下一列,但没有。有没有更好的方法来检查赢家?这是我的职责: fun checkWinsHorizontal() { for(row in 0 until gameBoard.size) { for(col in 0 until gameBoa

我正在Kotlin中创建一个简单的Connect-Four程序,使用2D阵列打印电路板。除了我的水平win checker功能外,一切都正常。由于我使用的逻辑,当我试图将您的片段放在第一列时,会出现索引越界错误,因为它试图检查数组中的下一列,但没有。有没有更好的方法来检查赢家?这是我的职责:

fun checkWinsHorizontal() {
    for(row in 0 until gameBoard.size) {
        for(col in 0 until gameBoard.size){
            // if this spot is taken up by an "X", and the horizontally adjacent spaces are the same, declare winner
            if (gameBoard[row][col] == "X" && (gameBoard[row][col] == gameBoard[row][col - 1] && gameBoard[row][col] == gameBoard[row][col - 2] && gameBoard[row][col] == gameBoard[row][col - 3]) ){
                printBoard()
                println("YOU WIN")
                winner = true
                return
            }
            // same thing as above but for a "computer" opponent
            else if (gameBoard[row][col] == "O" && gameBoard[row][col] == gameBoard[row][col - 1] && gameBoard[row][col] == gameBoard[row][col - 2] && gameBoard[row][col] == gameBoard[row][col - 3]){
                printBoard()
                println("COMPUTER WINS")
                winner = true
                return
            }
        }
    }
}

上面的评论解释了为什么索引超出了界限,因为您有硬编码的值,比如gameBoard[row][col-1],但col可能是0。我建议一些修复方法:

首先,没有必要在每次移动后检查板上的每个单元格。玩家获胜的唯一方法是,他们刚刚放置的棋子完成一行、一列或一条对角线。所以我建议你只检查涉及该细胞的潜在胜利

若要连续执行此操作,您可以使用以下内容:

fun completesRow(row: Int, col: Int) : Boolean {
  var count: Int = 1
  val symbol = gameBoard[row][col]
  // First move left - now we check that the symbols (X or O) match
  // AND that we're within bounds.
  var curCol = col - 1
  while (curCol >= 0 && gameBoard[row][curCol] == symbol) {
    ++count
    if (count == 4) {
        return true
    }
    --curCol
  }

  // same thing to the right; numColumns is assumed to be the number of
  // columns in the board.
  curCol = col + 1
  while (curCol < numColumns && gameBoard[row][curCol] == symbol) {
    ++count
    if (count == 4) {
        return true
    }
    ++curCol
  }

  // if you got here there weren't 4 in a row
  return false
}
注:以上内容未经测试——我甚至怀疑它是否能够编译,但希望它具有指导意义


如果你愿意,你也可以进一步推广。您可以为这些移动创建迭代器实例,然后使用一个函数,以两个迭代器(一个向左移动,一个向右移动)为例进行检查,而不是使用不同的函数来左/右、上/下和对角移动。通过这种方式,您可以使用相同的精确方法来检查水平、垂直或对角赢。

索引越界是因为您在整个长度上进行迭代,并使用前导和后继。此外:算法应该只检查水平赢条件还是垂直赢条件和对角赢条件?有几个选项。我可能会进行一些重构,但目前为止,在外部循环中,您可以使用ganeBoard[row][0]的值初始化变量,然后在内部循环中,只需将每个游戏板[row][col]与该值进行比较。如果有任何不同,退出循环,因为没有赢家。如果你到达了内部循环的末尾,那么赢家就是该变量中符号的所有者您好,这非常有用,肯定会让我回到正轨,但我确实有一个小问题,因为我对布尔函数没有太多经验。第二个while语句似乎总是返回true,你知道为什么会这样吗?两个while语句都返回true当且仅当连续符号的计数为4表示有人赢得了比赛。例如,假设col右侧的符号与[row][col]处的符号不匹配。然后while语句应该在不返回true的情况下退出,并且您会点击函数末尾返回false的那一行。我确实注意到了一个小错误,并更新了代码计数,因为[row][col]处的单元格应该初始化为1而不是0我知道当count等于4时,这两个语句都应该返回true。然而,第二个while语句一被调用就返回true。我必须查看@acuf558的一些代码才能理解为什么会发生这种情况。我也有兴趣了解您为什么认为会发生这种情况,例如,您是否添加了一些打印语句或在调试器中运行了它-换句话说,这种情况发生的确切证据是什么。