Tic Tac Toe Kotlin的Minimax算法

时间:2020-04-06 13:24:30

标签: algorithm kotlin recursion minimax

我正在使用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

    }

0 个答案:

没有答案