TicTacToe minimax算法没有选择最佳移动

时间:2018-04-05 01:02:34

标签: java algorithm tic-tac-toe minimax

我一直在为我的tictactoe游戏编写一个minimax算法,但似乎没有选择正确的动作。有可能赢得计算机,所以我必须在这里混淆一​​些东西。我认为算法本身似乎很好,所以我很确定问题是我如何获得最好的举动。有没有人有任何建议?

minimax方法

private int minimax(Board board, boolean maximizingPlayer, char symbol){
    //System.out.println(symbol);
    Board copyBoard = new Board(board.getCells());
    char winner = copyBoard.checkWin();
    if(winner!='-' || copyBoard.checkDraw()){
        return score(winner);
    }


    if(maximizingPlayer){
        int bestValue = Integer.MIN_VALUE;
        for(Board b : simulatePossibleMoves(copyBoard,mySymbol)){
            int value = minimax(b,false,switchSymbol(mySymbol));
            if(bestValue < value){
                bestValue = value;
                bestMove = b.getLastMove();
            }
        }
        return bestValue;
    }
    else{
        int bestValue = Integer.MAX_VALUE;
        for(Board b: simulatePossibleMoves(copyBoard, switchSymbol(mySymbol))){
            int value = minimax(b,true,mySymbol);
            if(bestValue > value){
                bestValue = value;
                bestMove = b.getLastMove();
            }
        }
        return bestValue;
    }
}

得分方法

private int score(char winner){
    if(winner == mySymbol)
        return 10;
    else if(winner == switchSymbol(mySymbol))
        return -10;
    return 0;
}

编辑:

游戏示例(人为X,AI为O)

O左上角
x中心
O中左侧
X左下方
O顶部中间
X右上角(人类胜利)

编辑2:

更多代码,不确定错误是否在这里,也可能包括它。

private ArrayList<Integer> getPossibleMoves(Board board){
    ArrayList<Integer> moves = new ArrayList<>();
    for(int i = 0; i < board.getCells().length; i++)
        if(!board.isCellTaken(i))
            moves.add(i);
    return moves;
}

private ArrayList<Board> simulatePossibleMoves(Board board, char symbol){
    ArrayList<Board> possibleBoards = new ArrayList<>();
    for(Integer move : getPossibleMoves(board)){
        Board temp = new Board(board.getCells());
        temp.setCell(move, symbol);
        possibleBoards.add(temp);
    }
    return possibleBoards;
}

private char switchSymbol(char s){
    if(s=='X')
        return 'O';
    return 'X';
}

1 个答案:

答案 0 :(得分:0)

事实证明,我一直试图通过选择minimax方法本身内部的最佳值来错误地使用算法。通过创建另一个调用minimax方法的方法,我能够找到最佳移动方式。以下代码对我有用。

public int getMiniMaxMove(Board board){
    int score = -1;
    int bestMove = -1;

    for(int i : getPossibleMoves(board)){
        Board copyBoard = new Board(board.getCells());
        copyBoard.setCell(i, mySymbol);
        int moveScore = minimax(copyBoard,false,mySymbol);

        if(moveScore >= score){
            score = moveScore;
            bestMove = i;
        }
    }

    return bestMove;
}


private int minimax(Board board, boolean maximizingPlayer, char symbol){
    Board copyBoard = new Board(board.getCells());
    char winner = copyBoard.checkWin();
    if(winner!='-' || copyBoard.checkDraw()){
        return score(winner);
    }


    if(maximizingPlayer){
        int bestValue = Integer.MIN_VALUE;
        for(Board b : simulatePossibleMoves(copyBoard,mySymbol)){
            int value = minimax(b,false,switchSymbol(mySymbol));
            if(bestValue < value){
                bestValue = value;
            }
        }
        return bestValue;
    }
    else{
        int bestValue = Integer.MAX_VALUE;
        for(Board b: simulatePossibleMoves(copyBoard, switchSymbol(mySymbol))){
            int value = minimax(b,true,mySymbol);
            if(bestValue > value){
                bestValue = value;
            }
        }
        return bestValue;
    }
}