我正在编写一个Gomoku的变体游戏。在一块巨大的木板上基本上是一个tic tac toe。
想知道是否有人知道游戏的良好人工智能策略。我目前的实现是非常愚蠢的,需要很长时间(O(n ^ 3),大约1-2秒才能移动):
-(void) moveAI {
//check if the enemy is trying to make a line horizontally, vertically, or diagonally
//O(n^3 * 3)
[self checkEnemies];
//check if we can make a line horizontally, vertically, or diagonally
//O(n^3 * 3)
[self checkIfWeCanMakeALine];
//otherwise just put the piece randomly
[self put randomly];
}
编辑:谢谢大家的反馈!我会尝试你的答案,让你们知道我是否可以做出任何改进。
答案 0 :(得分:20)
对于gomoku,已经找到了获胜策略。见本文:L. Victor Allis, H. J. van den Herik, M. P. H. Huntjens. Go-Moku and Threat-Space Search。当我写自己的程序时,它对我帮助很大。通过这种方式,你将能够编写出能够很好地攻击对手并找到胜利组合的程序。
答案 1 :(得分:14)
为这类游戏编写AI的传统且相当有效的策略是典型的树搜索策略。也就是说,每个板状态在图形中形成节点,并且在每个节点和可以由单个移动产生的状态之间放置有向边缘。以这种方式构建树,其中根板是空节点。然后,以一种巧妙的方式遍历树,找到看起来像“好”的状态。 “良好”状态通常通过使用一些聪明的启发式的评估函数来测量。显然你不想访问树中的所有节点 - 这将是很多工作!你只想要一些聪明的东西。
您可以添加预先计算的早期游戏和结束游戏以加速这些场景,然后依靠针对游戏中期的优化的树遍历启发式方法。
此类树遍历算法的实际名称是“Minimax”算法。在维基百科上寻找它,你会看到很多相当不错的材料。有一些方法可以提高算法的效率,其中最引人注目的是alpha-beta修剪,所以一定要看一下。您可能需要查看connect-four启发式方法,并决定如何将它们应用到游戏中。例如,用于评估电路板状态的可能良好的启发式方法是计算可连续的2次运行,3次运行和4次运行的数量,并将它们加权到分数中。 (例如,每次2次运行值1点,每次3次运行值10点,每次4次运行值1000点)
另一种优化策略是开发一种启发式算法,优先考虑极小极大算法应该搜索的位置 - 通常通过估计董事会评估函数的某种确定性。
通过这种策略,您应该能够在相同的时间内获得不那么愚蠢的AI。然而,真的,非常好的AI需要花费很多精力来构建,即使在这些“简单”的游戏中,它仍然可能需要超过10秒或更长时间才能让聪明的动作不受影响。另一方面,有一些聪明的编程技巧,例如在人类对手忙于思考时通过树预先计算遍历。嘿,人类可以在计算机的同时思考。公平公正!
希望我得到了一些帮助。祝好运!这是一个有趣的项目。
答案 2 :(得分:7)
我一直在尝试为同一个程序创建一个算法。
你当然是正确的,你的计划应该做的第一件事就是检查是否有办法形成5并获胜。如果没有,那么接下来应该检查你的对手是否可以做到这一点,如果有,那么就是防守。
你玩了多少自己的gomoku?你对基础知识的掌握程度如何?
好的,下一步是思考:我们如何才能获得能够获胜的位置?显然,要赢,我们必须连续四次。但我们只是连续四次形成:
__________
____XOOOO_
__________
然后对手可以关闭它。
但如果我们形成“开放四”,就像这样:
__________
____OOOO__
__________
然后对手无法关闭双方而你可以获胜。因此,形成一个开放的四是获胜的一种方式。现在问题是:我们怎样才能形成一个开放的四个?当然,如果我们形成“开放三”,就像这样:
__________
____OOO___
__________
然后对手可能阻止我们:
___________
____XOOO___
___________
我们回到了开始。
为了获胜,我们可以同时组成两个空位三分球:
____________
____OOO_____
_____O______
____O_______
现在如果对手阻挡其中一个,我们可以使用另一个来形成一个开放的四个:
____________
_______O____
___XOOO_____
_____O______
____O_______
____________
并赢了:
________O___
_______O____
___XOOO_____
_____O______
____O_______
___X________
在gomoku术语中,如果您同时打出两个开放三分球,则称为3x3。
请注意,两个三分球必须是开放的:你能理解为什么吗?
还有其他获胜方式:
4x3:你看到胜利的举动以及为什么赢了?
____________
__XOOO______
__XXXO______
____OX______
____________
4x4:看到获胜的举动?
____________
__XOOO______
__XXXO______
__OXOX______
___O________
__X_________
这些只是游戏的基础知识。了解策略有助于您思考如何构建AI,因此您可以对原则进行硬编码。
当然,这只是一个开始。如果你能尝试实现这一点然后给我反馈,我将不胜感激。
我一直在尝试用Java编写程序。你想看看我做过的代码吗?你可以玩游戏吗?它还不是很好,但你可以从中获得新的想法。虽然注释和变量名称是用爱沙尼亚语编写的,但可能很难理解。 :(
答案 3 :(得分:5)
我创造了一个gomoku播放器一次,使用alpha-beta修剪非常成功,每个位置的分数取决于每个玩家有多少半开放和完全开放的2s,3s和4s。
计算这不是n ^ 3。您只需检查最新的移动是否关闭任何对手线,如果它延伸了一些线,则相应地修改得分。
如果你需要它玩得更好,我会研究国际象棋电脑的一些技巧。例如,尝试“杀手移动”(记住哪些移动得分高或在其他位置直接获胜)首先搜索时会显着提高树搜索的效率。重要的是在alpha-beta修剪中首先尝试假定的最佳动作。
当你拥有你的玩家时,你应该尝试通过互相玩不同的版本来找出不同元素(2s,3s,4s,开放和半开放等)的得分最好。
答案 4 :(得分:5)
Gomoku已经解决了,但是当它打开位置和有限的资源时它没有被解决。
我是Hewer gomoku计划和Gomocup组织者的作者,我可以告诉您,编写好的Gomoku AI需要很长时间。 Renju要复杂得多。您可以使用Gomocup界面简化工作,并编写“仅”AI。
答案 5 :(得分:1)
我来迟了一点,但问题尚待解决,因此我将补充自己对Gomoku AI播放器的经验。也许有人会觉得它有用...
我也创建了Gomoku player。它不是完美的,但是它玩起来相当不错,而且肯定比我更好。无论如何,我发现:
因此,我的Gomoku播放器无需进行深度搜索即可评估所有棋盘位置。它将水平,垂直和对角线分成几串。然后在表中搜索那些字符串中的模式。对于黑人玩家,一些模式是:
X标记黑色玩家石头,O标记白色玩家石头,“-”标记空白位置。玩家将所有找到的图案加总,并找到得分最高的棋子。