Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 简单井字游戏_Javascript_Artificial Intelligence_Tic Tac Toe - Fatal编程技术网

Javascript 简单井字游戏

Javascript 简单井字游戏,javascript,artificial-intelligence,tic-tac-toe,Javascript,Artificial Intelligence,Tic Tac Toe,我知道这已经被问了很多,我也搜索过其他代码,但我所看到的大多数代码似乎都不是完美无缺的(从不丢失),简单、优雅、高效。我无法决定哪种解决方案适合这种描述 我看到的解决方案是: (1) 使用minimax和alpha-beta修剪。这对我来说似乎很复杂,对于这样一个简单的游戏来说可能没有必要?是不是太复杂了?如果不是,我需要做很多硬编码,还是我误解了算法 (2) 使用维基百科中的伪代码策略编写代码。。。我不太确定如何实现这一点。例如,它只是说“检查叉子”。这些检查中的大多数是通过拥有一个winni

我知道这已经被问了很多,我也搜索过其他代码,但我所看到的大多数代码似乎都不是完美无缺的(从不丢失),简单、优雅、高效。我无法决定哪种解决方案适合这种描述

我看到的解决方案是:

(1) 使用minimax和alpha-beta修剪。这对我来说似乎很复杂,对于这样一个简单的游戏来说可能没有必要?是不是太复杂了?如果不是,我需要做很多硬编码,还是我误解了算法

(2) 使用维基百科中的伪代码策略编写代码。。。我不太确定如何实现这一点。例如,它只是说“检查叉子”。这些检查中的大多数是通过拥有一个winningLines数组并检查它们是否被填写或类似的方式来完成的吗?如果没有,有人能给我一些关于什么数据结构的提示或者关于如何实现伪代码中的检查的基本提示吗:。我也看到过一些算法,它们给一个“X”平方和一个“O”平方赋予一个数值,然后用总和来决定胜利者,但我不明白为什么这特别有用


还有其他合理的解决方案吗?

老实说,在处理人工智能和启发式时,最简单的任务可能会很快变得复杂。minimax方法会给你最好的结果,考虑到你正在实现人工智能这一事实,它应该不会太难。这是一个基于2人回合的游戏逻辑的既定标准

查看此网站。。。它对tic-tac-toe人工智能和minimax实现提供了一些很好的见解

编辑:

注意到有人写了“蛮力”。。。这最终将成为一种低效的方法来实现涉及极大极小的启发式。根据其他玩家的最后一步,迭代每一个可能的动作,这只是实现启发式的另一种方式。。但在我看来,这似乎是更多的工作。极小极大实现将是简单而有效的

编辑2:

“更简单的实现”是相对的。Minimax是标准,正如我在评论中所说的,您可以操纵启发式以适合您正在寻找的情况

我希望我能告诉你最简单的方法,但有这么多的变量取决于你的游戏在代码中的植入

接受建议,看看你的游戏实现,然后看看什么最适合你

对一个人来说简单的事情对另一个人来说可能很复杂。我只是想给你一些选择,minimax是非常可靠的。也许可以试着调整它以适应你的需要

编辑3:


如果你需要更多的指导,请告诉我。我很乐意提供帮助。

使用您选择的格式“编码”到一组动作中。人工智能将永远获胜或平局

例如,您可以将其编码如下:

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();
    }
}

对于这样一个小游戏树,只需蛮力就可以了。模拟每一场可能的比赛根本不需要时间。看起来不是完美的(总是赢)=看起来很正常。我总是在井字游戏中获胜。或者最坏的情况是平局。任何聪明的人都会有同样的结果。这就是为什么没有人在10岁以后玩井字游戏。当没有人赢的时候,这一点都不好玩。当然,“永远赢”不是一个有效的要求(永远)。想象一下你的算法在和自己作对。然后你可能应该编辑你的问题。Minimax不必很复杂,对于这样一个小游戏,修剪也不是真的必要。例如,请看清楚,你是说minimax实际上比检查维基百科条目中的所有案例都简单,还是说它不太复杂,同时允许使用更高效和优雅的代码?我是说如果你想要动态播放,请使用minimax。在tic-tac-toe的案例中,使用维基上的案例,你可以硬编码这些选项,如果你愿意,可以用“暴力”的方式来遵循它们。在某些情况下,它可以很好地工作并保证获胜。我是说,如果你想要一个通用的启发式来处理案例,你可以用你的特定启发式来实现极小极大。您可以在启发式中包含那些“肯定赢”的案例,以确保它们被覆盖,然后在需要时使用更一般的选择。我认为一个混合的启发式方法,包括两者,将为你提供最好的服务。你所说的“保证在某些情况下获胜”是什么意思。这难道不能保证在所有情况下都能获胜吗?是的。对不起,我不是很清楚。语义学。。。