计算跳棋中的最佳移动

时间:2013-04-06 14:24:02

标签: java

我创建了一个checkress游戏,我希望计算机计算最佳移动。 这是我到目前为止所做的:

public BoardS calcNextMove(BoardS bs)
{
    ArrayList<BoardS>options = calcPossibleOptions(bs);
    int max = -1;
    int temp;
    int bestMove = 0;

    for(int k=0;k<options.size();k++)
    {
        temp = calculateNextMove2(options.get(k));
        if(max<temp)
        {
            max = temp;
            bestMove = k;
        }
    }
    return options.get(bestMove);
}

public int calculateNextMove2(BoardS bs)
{
    int res = soWhoWon(bs);

    if(res == 2) //pc won(which is good so we return 1)
        return 1;
    if(res == 1)
        return 0;

    ArrayList<BoardS>options = calcPossibleOptions(bs);

    int sum = 0;
    for(int k=0;k<options.size();k++)
    {
        sum += calculateNextMove2(options.get(k));
    }
    return sum;
}

我一直在

  
    

线程“AWT-EventQueue-0”中的异常java.lang.StackOverflowError

  

calcPossibleOptions效果很好,它是一个返回所有可能选项的数组的函数。

BoardS是一个代表游戏板的clas。

我想我必须提高效率,怎么做?

2 个答案:

答案 0 :(得分:0)

你需要找到MinMax的替代品,即使最有可能使用alpha-beta修剪,因为电路板太大会导致太多可能的移动和反向移动。这会导致堆栈溢出。

我很惊讶地看到为Tic-Tac-Toe制作完整的决策树并没有让我自己溢出,但我担心我对人工智能规划或其他解决这些问题的算法不够了解,除此之外帮助你。

答案 1 :(得分:0)

“calculateNextMove2()”的递归运行得太深,这就是为什么你得到一个StackOverFlow。如果你期望游戏运行到最后(除非相对接近实际的胜利),这可能需要很长时间。像国际象棋一样(我有更多的经验)一个引擎可能会走20步之前,你可能会用它到目前为止发现的东西。如果你从国际象棋游戏开始运行它......它可以在当前的技术上运行100年(并且仍然无法说出获胜的第一步是什么)。也许只是尝试10或20个深度? (这仍将击败大多数人 - 并且仍然可能被归类为“最佳动作”)。与国际象棋一样,你很难评估一个位置是好还是坏的工作(通常计算为物质优势和位置优势的组合)。这是棘手的部分。注意:Project Chinook已经完成了你想要实现的目标 - 它已经“击败”了Checkers的游戏(国际象棋没有这样的东西存在编辑:Magnus Carslen已经为所有意图和目的“贬低”游戏:D)。

见:Alpha-beta pruning (这可能会有所帮助)

这里还有一篇关于这个主题的(旧)论文:

Graham Owen 1997 Search Algorithms and Game Playing (可能有用)

同时请注意,返回导致“胜利”的第一步是“天真” - 因为它可能是一个完全不可思议的移动线,如果他们不参加非常特别的比赛,对手将获得优势 - 例如为傻瓜交配伴侣或学者在国际象棋中交配...(快速但非常轻微)