我正在使用Kotlin中的minimax算法来开发简单的tictactoe AI。似乎有些奏效,但在这种情况下失败了:
我先走,然后是“ X”。 AI是'O'
X | |
----------
| |
----------
| |
则返回值为
X | O |
----------
| |
----------
| |
应该是中间位置而不是最佳位置。
我发现的内容: 我尝试调试并意识到,在我的第一步中,minimax函数的所有返回值都是10(10是我为AI获胜时要返回的函数设置的常数)
findPossibleMoves
fun findPossibleMoves(board: CharArray) : IntArray {
var possibleMoves: ArrayList<Int> = ArrayList(0)
for (cellIndex in board.indices) {
if (board[cellIndex] == ' ') {
possibleMoves.add(cellIndex)
}
}
return possibleMoves.toIntArray()
}
findBestMove
fun findBestMove(board: CharArray) : Int {
var boardClone = CharArray(9)
for (cellIndex in boardClone.indices) {
boardClone[cellIndex] = board[cellIndex]
}
val possibleMoves = findPossibleMoves(boardClone)
var bestMove = 0
var max = -1000
for (move in possibleMoves) {
boardClone[move] = currentPlayer
var value = minimax(boardClone, false, 1)
Log.wtf("T", "$move $value")
boardClone[move] = EMPTY
if (value > max) {
max = value
bestMove = move
}
}
Log.wtf("T", "-------------------------------")
return bestMove
}
minimax
fun minimax(board: CharArray, isMaximising: Boolean, depth: Int) : Int {
if (isGameOver(board)) {
if (doesWinenrExist(board)) {
when (getWinner(board)) {
PLAYER -> {
return -10
}
CPU -> {
return 10
}
}
}
return 0
}
var possibleMoves = findPossibleMoves(board)
if (isMaximising) {
var bestValue = -1000
for (move in possibleMoves) {
board[move] = CPU
var temp = minimax(board, !isMaximising, depth + 1)
board[move] = EMPTY
if (temp > bestValue) {
bestValue = temp
}
}
return bestValue
} else {
var bestValue = 1000
for (move in possibleMoves) {
board[move] = PLAYER
var temp = minimax(board, !isMaximising, depth + 1)
board[move] = EMPTY
if (temp < bestValue) {
bestValue = temp
}
}
return bestValue
}
}
帮助功能
fun isBoardFull(board: CharArray) : Boolean {
for (cell in board) {
if (cell == ' ') {
return false
}
}
return true
}
fun doesWinenrExist(board: CharArray) : Boolean {
var board2d: Array<CharArray> = arrayOf(board.sliceArray(0..2), board.sliceArray(3..5), board.sliceArray(6..8))
//check row
for (row in board2d) {
if (row.all { it == PLAYER } || row.all { it == CPU }) {
return true
}
}
//check col
for (i in 0..2) {
var col: ArrayList<Char> = ArrayList(0)
for (firstIndexInGroupsOf3 in i until board.size step 3) {
col.add(board[firstIndexInGroupsOf3])
}
if (col.all { it == PLAYER } || col.all { it == CPU }) {
return true
}
}
//check diag
for (x in 0..2 step 2) {
var diag: ArrayList<Char> = ArrayList(0)
for (y in 0..2) {
diag.add(board2d[y][if (x == 2) (x - y) else y])
}
if (diag.all { it == PLAYER } || diag.all { it == CPU }) {
return true
}
}
return false
}
fun isGameOver(board: CharArray) : Boolean {
return isBoardFull(board) || doesWinenrExist(board)
}
fun getWinner(board: CharArray) : Char {
var noOfX = board.count { it == PLAYER }
var noOfO = board.count { it == CPU }
return if (noOfO > noOfX) CPU else PLAYER
}
非常感谢您的帮助!谢谢!
================================================ =====
已解决! 问题出在getWinner()
更新了getWinner函数:
fun getWinner() : Char {
return currentPlayer
}