这是我的第一个问题,如果我做错了,请告诉我......
我目前正在用Java制作草稿游戏。事实上,除了AI之外,一切都有效。 AI目前采用单线程,使用minimax和alpha-beta修剪。我认为这段代码非常有效,我只能深入到游戏树中。
情况就是这样,现在我有一些问题。 我想深入到我的游戏树中,因此我必须减少计算移动所需的时间。
有人可以帮我这个吗?
答案 0 :(得分:2)
1。 AI的可能移动值(例如AI可以选择的移动)始终为0,这是正常的吗?
听起来很奇怪。如果可能的移动次数为0,则该玩家无法轮到他。这应该不是很常见,或者我误解了什么?
如果您所指的值代表该移动的“得分”,那么显然“始终为0”表示所有移动都同样好,这显然不会成为非常好的AI算法。
2。我不知道它是否有用,但我如何将此递归转换为多线程递归。我认为这可以将工作时间划分为某个值......
我确信它非常有用,特别是考虑到目前大多数机器都有几个核心。
让它变得复杂的是你“尝试移动,记录,撤消,尝试下一步”的方法。这表明您正在使用可变数据结构,这使得对算法进行并行化非常复杂。
如果我是你,我会让bord / game状态由不可变数据结构表示。然后,您可以将每个递归调用视为单独的任务,并使用线程池来处理它们。您将接近CPU的最大利用率,同时大大简化代码(通过删除整个恢复到以前的状态代码)。
假设您的计算机上确实有多个核心,这可能会让您深入了解树。
答案 1 :(得分:1)
我强烈建议您阅读本书:
One Jump Ahead: Computer Perfection At Checkers
它将在Checkers游戏中为您提供有关计算机AI的深刻历史,并且可能会为您提供评估功能方面的帮助。
不是让评价函数只给出不同作品的1/0 / -1,而是为每一个普通作品给出100分,为国王作为200分。然后为片状结构提供奖励。例如,如果我的作品形成一个无法捕捉的安全结构,那么我会获得奖金。如果我的作品单独在棋盘中间,那么我会获得负面奖励。正是这种丰富的功能,可以让你的程序很好地运行。最终得分是两位球员的评价差异。
此外,您不应该以统一的深度停止搜索。静止搜索扩展搜索直到电路板“安静”。在Checkers的情况下,这意味着板上没有强制捕获。如果你不这样做,你的程序将会发挥得非常糟糕。
正如其他人所建议的那样,转置表可以很好地减少搜索树的大小,尽管程序运行速度稍慢。我还推荐历史启发式,它易于编程,并将大大改善树中移动的顺序。 (谷歌历史启发式以获取更多相关信息。)
最后,你的董事会代表可以产生很大的不同。快速实施搜索不会在每次应用移动时复制电路板,而是尝试快速修改电路板以应用和撤消移动。
答案 2 :(得分:0)
(我假设通过草稿你的意思是我们在美国所谓的跳棋。)
我不确定我是否理解游戏树中的评分系统。你是否得分,“如果球员比对手有更多的棋子,则得分为1分,如果球员的棋子数量相同,则得分为1分,如果他们的棋子数相同则为0分?”
如果是这样的话,那么你的算法可能只是对前五个动作进行捕获,或者事情正在发生,以便所有捕获都是平衡的。我对跳棋并不是很熟悉,但似乎不可能这样只有五次进入游戏。如果它只有5个 plies (其中一层是一个玩家的移动,而不是一整套相反的移动)也许它并不罕见。
你可能想要通过在一个你知道绝对正确答案的棋盘位置进行测试来测试这个问题,也许是在棋盘上只有两个棋子并且有一个可以捕获的位置。
但是,作为一般原则,董事会的评价功能并没有多大意义 - 它忽略了一件和一件冠冕之间的区别,它将三件式优势视为一件一块优势。