我正在使用2D阵列在Kotlin中创建一个简单的Connect Four程序来打印电路板。除了我的水平胜利检查器功能之外,其他所有功能都正常运行。由于我使用的逻辑,尝试将您的片段放在第一列时出现错误(索引超出范围),因为它试图检查数组中的下一列,但没有错误。有没有更好的方法来检查优胜者?这是我的功能:
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 = 0
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
}
注意:以上内容未经测试-我怀疑它是否可以编译,但希望它能对您有所启发。
如果需要,您也可以进一步概括。您可以为这些移动创建Iterator
实例,然后使用一个带有2个迭代器(例如,一个向左移动和一个向右移动)的单一函数,而不是使用向左,向右,向上/向下和对角线移动的不同功能,进行检查。这样,您可以使用相同的精确方法来检查水平,垂直或对角线获胜。