我知道这已被问了很多,而且我已经搜索了其他代码,但我所看到的大部分内容看起来并不完美(从不丢失),而且简单,优雅,高效。我无法确定哪种解决方案适合该描述。
我见过的解决方案是:
(1)使用minimax进行alpha-beta修剪。这对我来说似乎很复杂,对于这么简单的游戏可能没必要?它可能太复杂了吗?如果没有,我是否需要进行大量的硬编码或者我是否误解了算法?
(2)使用维基百科的伪代码策略编写代码......我不确定如何实现这一点。例如,它只是说"检查叉子"。大多数这些检查是通过拥有一系列的胜利线并检查它们是否被填写或类似的东西来完成的?如果没有,有人可以给我提示有关如何实现伪代码中提出的检查的数据结构或任何基本提示:http://en.wikipedia.org/wiki/Tic-tac-toe#Strategy。我也看到过算法可以为“X'”提供数值。广场和一个' O'广场,然后使用总和来决定胜利者,但我不明白为什么这特别有用。
任何其他合理的解决方案?
答案 0 :(得分:9)
老实说,在处理AI和启发式问题时,最简单的任务很快就会变得复杂。 minimax方法将为您提供最佳结果,考虑到您正在实施AI,这应该不会太困难。它是一个既定标准,拥有2个基于玩家回合制的游戏逻辑。
查看这个网站......它提供了对井字游戏AI和极小极大实现的一些很好的见解。
http://www.ntu.edu.sg/home/ehchua/programming/java/JavaGame_TicTacToe_AI.html
编辑:
注意到有人写了“蛮力”......这最终将成为实现极小极大所涉及的启发式的低效方式。基于其他玩家最后一次移动的每一个可能移动的迭代只是实现启发式的另一种方式..除了在我看来似乎更多的工作。 Minimax的实施将简单有效。
EDIT2:
“更简单的实现”有点相对。 Minimax是标准,正如我在评论中所说,您可以操纵启发式以适应您正在寻找的案例......
我希望我能告诉你最简单的方法,但是有很多变量依赖于代码中游戏的植入。
接受建议,看看你的游戏实施,然后看看最适合你的是什么!
对一个人来说简单的事情可能会让另一个人感到困惑。我只是想给你选择,而minimax非常可靠。也许尝试调整它以满足您的需求。
EDIT3:
如果您需要更多指导,请告诉我。我很乐意提供帮助。
答案 1 :(得分:3)
使用您选择的格式将this image“编码”为一组移动。人工智能将永远胜利或并列。
例如,您可以按如下方式对其进行编码:
var turns = {
"mefirst":{
"move":0,
"next":[
null,
{
"move":4,
"next":[
null,
null,
{"move":8}, // win
{"move":8}, // win
null,
{"move":8}, // win
{"move":8}, // win
{"move":8}, // win
{
"move":6,
"next":[
null,
null,
/* AND SO ON... */
]
}
};
然后你可以从:
开始if( ai_goes_first) {
game = turns.mefirst;
makeMove(game.move);
}
else game = turns.themfirst;
playerTurn();
playerTurn
类似于:
function playerTurn() {
when player clicks a valid squeare {
game = game.next[chosenSquare];
makeMove(game.move);
if( game.next) playerTurn();
}
}