【问题标题】:Tic Tac Toe Alpha Beta Minimax井字游戏 Alpha Beta Minimax
【发布时间】:2015-08-29 06:32:18
【问题描述】:

为了更好地理解极小极大算法的工作原理,我一直在研究井字游戏。以下实现无法正常工作,因为计算机可能会丢失游戏。如果程序运行正常,那么理论上这应该是不可能的......

我在执行极小极大或获得最佳移动方面犯了错误吗?

我之前从未实现过算法:s

评价函数

public static int evaluate(char[] board, char turn) {
    if (isWinFor('x', board)) {
        return -1;
    } else if (isWinFor('o', board)) {
        return 1;
    } 
    return 0;
}

极小极大

public static int alphabeta(char[] board, int depth, char turn, int alpha, int beta) {
    if (depth == 0 || gameOver(board)) {
        return evaluate(board, turn);
    } else {
        for (int move : possibleMoves(board)) {
            makeMove(board, turn, move);
            turn = changeTurn(turn);
            int value = alphabeta(board, depth--, turn, alpha, beta);   
            makeMove(board, ' ', move);
            if (turn == 'o') {
                if (value > alpha) {
                    alpha = value;
                }
                if (alpha >= beta) {
                    return beta;
                }
            } else if (turn == 'x') {
                if (value < beta) {
                    beta = value;
                }
                if (beta <= alpha) {
                    return alpha;
                }
            }               
        }
        if (turn == 'o') {
            return  alpha;
        } else {
            return  beta;
        }             
    }
}

找到最佳动作

public static void getBestMove(char[] board, char turn) {
    Random random  = new Random();
    int bestValue = -10000;
    List<Integer> choices = new ArrayList<Integer>();
    for (int move : possibleMoves(board)) {
        makeMove(board, turn, move);
        turn = changeTurn(turn);
        int value = alphabeta(board, 3, turn, -10000, 10000);   
        makeMove(board, ' ', move);
        if (value > bestValue) {
            bestValue = value;
            //start code edit
            choices.clear();
            //end code edit
            choices.add(move);
        } else if (value == bestValue) {
            choices.add(move);
        }
    }
    makeMove(board, turn, choices.get(random.nextInt(choices.size())));
}

谢谢。

【问题讨论】:

    标签: java tic-tac-toe minimax alpha-beta-pruning


    【解决方案1】:

    这很简单:一个完美的玩家必须搜索整个树到最大深度(截止节点除外),但您将程序限制为只有 4 层!

    找到最佳移动有错误:

    int value = alphabeta(board, 3, turn, -10000, 10000);        
    

    改成

    int value = alphabeta(board, 8, turn, -10000, 10000);
    

    【讨论】:

    • 嗨 xXliolauXx,不幸的是,它仍然没有玩完美的游戏。
    【解决方案2】:

    除了上一个答案之外,我很确定您的 GetBestMove 是错误的:只要移动更好或等于您当前的最佳移动,您就会添加一个选择。但是当最佳值发生变化时,您实际上并没有清除列表。这意味着您的选择列表中会出现失败的动作。

    【讨论】:

    • 这肯定有所作为。当 value > bestValue 时,我在添加新动作之前添加了choices.clear()。现在,当我玩游戏时,如果我连续放置两个“x”,计算机现在会阻止我获胜(以前没有这样做),但是,如果我再连续放置两个“x”,它不会阻止第二次。在第二种情况下,它似乎更倾向于将它的两个“o”排成一排,而不是阻止我,这意味着我仍然可以获胜。评估()函数的分数有问题吗?
    • @user1334130 尝试调试,当 cp 出错时,您的选择列表是否正确? - 值是否正确?那我也许可以帮你。
    • 看看一切,玩了几场比赛,我能看到的如下。如果我正在玩游戏并且连续有两个“x”,则选择数组将存储阻止我获胜的动作,以及其他动作(我想它们一定被评为相同的分数),这意味着当计算机随机选择一个移动时,它有时会做出错误的选择并失败。理想情况下,如果计算机必须阻止我以防止获胜,这应该是唯一可用的动作。这是井字游戏代码pastebin.com/5RNmj5Pv和gui代码pastebin.com/BvwYThMA
    • @user1334130 感谢代码。到目前为止我还没有发现错误。我建议实现一个从文件加载位置的函数,然后让 CP 打印所有已放置 7 个 x/os 的位置的评估......你应该能够以这种方式调试它......跨度>
    猜你喜欢
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    相关资源
    最近更新 更多