【问题标题】:tic tac toe using alpha beta prunning in java在java中使用alpha beta修剪的tic tac toe
【发布时间】:2010-02-16 10:33:56
【问题描述】:

我正在尝试使用迭代 Alpha-Beta 修剪来玩井字游戏, 我有一秒钟的移动限制,但由于某种原因 效果不好。

我修改了常规的 alpha-beta 代码,而不是返回 alpha 或 beta,它返回一个状态(即下一步的棋盘)

每次我创建孩子时,我都会更新他们的深度。

但又出于某种原因,我一直在输球,我看到了 我的 alpha beta 没有看到最好的选择。

这是我的代码:

外循环:

while (watch.get_ElapsedMilliseconds() < 900 && d <= board.length * board[0].length - 1)
        {
            s = maxiMin(beginSt, d, watch);
            if (s.getNextMove().getIsWin() == true)
            {
                break;
            }
            d++;
        }
        return new location(s.getNextMove().getRow(), s.getNextMove().getCol());

alpha 测试版:

public State maxiMin(State s, int depth, Stopwatch timer)
    {
        if (s.getDepth() == 7)
        {
            Console.WriteLine();
        }
        if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
        {
            s.evaluationFunc(line_length, PlayerShape);
            s.setAlpha(s.getEvaluation());
            s.setBeta(s.getEvaluation());
            return s;
        }
        LinkedList<State> children = createChildren(s, true);
        // No winner, the board is full
        if (children.get_Count() == 0)
        {
            s.evaluationFunc(line_length, PlayerShape);
            s.setAlpha(s.getEvaluation());
            s.setBeta(s.getEvaluation());
            return s;
        }
        while (children.get_Count() > 0)
        {
            State firstChild = children.get_First().get_Value();
            children.RemoveFirst();
            State tmp = miniMax(firstChild, depth, timer);
            int value = tmp.getBeta();
            if (value > s.getAlpha())
            {
                s.setAlpha(value);
                s.setNextMove(tmp);
            }
            if (s.getAlpha() >= s.getBeta())
            {
                return s;
            }
        }
        return s;
    }

    public State miniMax(State s, int depth, Stopwatch timer)
    {
        if (s.getDepth() == 7)
        {
            Console.WriteLine();
        }
        if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
        {
            s.evaluationFunc(line_length, PlayerShape);
            s.setAlpha(s.getEvaluation());
            s.setBeta(s.getEvaluation());
            return s;
        }
        LinkedList<State> children = createChildren(s, false);
        // No winner, the board is full
        if (children.get_Count() == 0)
        {
            s.evaluationFunc(line_length, PlayerShape);
            s.setAlpha(s.getEvaluation());
            s.setBeta(s.getEvaluation());
            return s;
        }
        while (children.get_Count() > 0)
        {
            State firstChild = children.get_First().get_Value();
            children.RemoveFirst();
            State tmp = maxiMin(firstChild, depth, timer);
            int value = tmp.getAlpha();
            if (value < s.getBeta())
            {
                s.setBeta(value);
                s.setNextMove(tmp);
            }
            if (s.getAlpha() >= s.getBeta())
            {
                return s;
            }
        }
        return s;
    }

如果有人能告诉我是否有问题,将不胜感激。我怀疑也许 这与我返回“s”而不是常规的 alpha beta 有关 它返回评估,但我没有设法找到错误。

提前致谢,

莉娜

【问题讨论】:

  • 我认为你应该从 Minimax (en.wikipedia.org/wiki/Minimax) 开始,然后当你得到工作时添加 alpha beta。这将使调试变得更加容易。 Minimax 本质上是没有修剪的 alpha beta。 Minimax 将在几秒钟内轻松解决井字游戏。

标签: java artificial-intelligence evaluation tic-tac-toe


【解决方案1】:

首先,井字游戏是一个非常简单的游戏,我相信它可以用更简单的代码来解决,主要是因为我们知道总有一个平局选项并且状态总数少于 3^9 (包括对称和许多不可能的状态)。

至于您的代码,我认为您的问题之一是您似乎没有增加递归调用的深度。

你的代码也有很多风格不好的问题,你把 miniMax 和 MaxiMin 分成了两个函数,虽然它们本质上是一样的。您可以通过从中删除元素来迭代集合,而不是使用 for-each 或迭代器(甚至是 int 迭代器)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多