2012-02-08 24 views
1

我有表和Generate_moves()等一些函数,但最低运算法则工作,我需要设置表的分数,使计算机选择最好的表。如何在井字游戏中设置表格的分数?

 public int Score() 
     { 
      if (Turn == "X") 
      { 
       if (gameWon("X")) return 100; 
       if (gameWon("O")) return -100; 
       if (gameDrawn()) return 0; 

       return n - canWin("X"); 
      } 

      if (Turn == "O") 
      { 
       if (gameWon("O")) return 100; 
       if (gameWon("X")) return -100; 
       if (gameDrawn()) return 0; 

       return n - canWin("O"); 
      } 

      return -1; 
     } 

canWin(string)返回一个数字,告诉我,我有多少两个X或O都在直线或列,但我怀疑这是一个伟大的,为什么要设置表的分数。

如果我有表:

X - X 
0 X 0 
- - 0 

比分应该是一样的

X - - 
0 - X 
0 0 X 

和应大于

X - X 
0 - - 
- 0 - 

而且我没有任何想法如何让分数功能告诉我不同​​的分数。我如何实现方法Score来告诉我这个?

编辑:

如果计算机是先用X和我带O

X - -  X - -  X - -  X - - 
- - - -> 0 - - -> 0 X - -> 0 X - 
- - -  - - -  - - -  - - 0 

现在我怎样才能使计算机选择下一个最好的选择是

X - X 
0 X - 
- - 0 
+1

我不明白。你能做的最好的事情是赢得比赛,抽签还是放松,不应该1分,0分和1分足够分数? – aioobe 2012-02-08 13:58:33

+0

我不确定我是否理解你如何尝试对此进行评分。在所有三个例子中,X是1次移动而O总是2次移动。他们有什么不同? – 2012-02-08 13:59:18

+0

我需要MinMax的Score函数。1 0 -1不够精确,因为在第一个X - X 0 X 0 - - 0我不能说0 1 -1,因为不适合所以它应该扩大 – Dementor 2012-02-08 14:03:25

回答

1

Tic- Tac-Toe对于电脑来说是一个相对容易的游戏 - 因为branch factor和可能性的数量相对较小,因此:最好是创建最简单的[计算]可能的音调抽象函数,并让minmax达到最深的水平,即游戏树的叶子,这些都是一定的胜利/损失/平局。

如果你还在寻找一个启发式的,你可以使用number of rows/cols/diagonals with exactly 2 "X"s and left square is empty

尽管如此,我仍然认为[这一特定问题]一个极小极大算法返回-1损失,1胜0所有其他可能性会更好 - 因为它可以更快地达到游戏的叶子,因此在任何启发式的情况下都会更加明了。

+0

没问题,但是当MinMax达到最深的水平时,会有10胜20平10负的胜利,我应该选择哪一个分支让我赢得胜利? – Dementor 2012-02-08 14:21:38

+0

@Dementor:minmax不处理平等 - 任何分支采取的决定是优化和超过minmax的启发式。如果你继续遵循minmax,你应该采取一个可以保证你的分支 - 你不会失去它。如果两条路径具有相同的分数,您可以进行额外优化:使用“决胜盘:大多数路径计算得到的路径胜利” – amit 2012-02-08 14:25:56

+0

@Dementor:p.s. minmax不处理这个,因为它“不关心” - 如果你和你的对手都遵循minmax,游戏的分数将**完全**由minmax返回的分数 – amit 2012-02-08 14:26:57

0

其中一种可能性... Score =剩余路数(仍然可以填充到获胜状态的行数,列数或对角数)为x获胜 - 每个状态不是叶子(最终状态) 对于叶子状态你只有分数= 1,0或-1

+0

我的问题与得分功能是,我需要得分功能为if(得分(移动)>得分(best_move)){ best_move < - 移动; } – Dementor 2012-02-08 14:17:34

+0

Winning = +无限,Losing = -infinite,Draw = 0,剩下的就是上面提到的差异。 – xyz 2012-02-08 14:21:28

1

我认为你是过于复杂的事情。有少40万可能井字棋游戏 - 事实上,井字棋是很简单的,你可以记下每一个可能的游戏中最好的移动在纸张

(complete tic-tic-toe map) - XKCD

单张纸

即使像minmax这样简单的算法也是矫枉过正的 - 只需通过蛮力检查所有可能的移动。现代PC上只需要几毫秒。

0

要回答你的第二个问题:

现在我怎么可以让电脑选择的下一个最好的选择是......

这是极大极小算法的任务。它偷看游戏树的最佳举动。对于井字游戏,您不需要非常复杂的评估功能,如果玩家赢得或0,则足以返回正面或负面价值。如果你愿意,你可以通过评估一名球员是否能在下一步中获胜来扩展它。更复杂的评估功能,您需要具有更大分支因子的游戏,并且游戏树可以更深入(不仅仅是9步)。
我的经验*是,在游戏树搜索中进一步深入到更好的结果比由于更聪明的评估函数而达不到此层(同一时间)更好。由于简单的评估,或者由于复杂的评估,因此不需要进行如此深入的搜索,因此区分深度搜索并不容易。 有很多其他显著增强了极大极小算法是有希望的,不要卡住首先想到的一个复杂的评估:

之后您仍然可以改进评估功能。对评估的一些其他想法:也许最好在函数makeMove中做一些工作,在这里你只需要检查一行(而不是全部)行,一列和一个或两个对角线。然后,在当前董事会旁边,保留从此检查中获得的信息。这些信息包括,如果这是一个胜利的举动(设置得分),或者如果从另一个玩家的下一个移动被迫(记住下一个玩家必须移动的移动,getMoves将只返回这个)。最后但并非最不重要的,如果一列/一排和一个对角线包含强制移动,则玩家以两步移动(保持得分)。

祝您好运,您的评估功能!

*前一段时间我的工作是评估Connect-Four-Game-Engine的功能。评估连接四块电路板的最佳方法是分析詹姆斯·D·艾伦(James D. Allen)的关键词Expert Play in Connect-Four的“威胁分析”一章中所描述的奇怪甚至威胁。该算法分析了主要和次要威胁。删除次要威胁分析部分后,alpha-beta搜索表现更好!

+0

我正在寻找分数评估,因为我想将井字形式3by3扩展到XbyX,因此分支工厂将是>> – Dementor 2012-02-09 07:34:44

+0

即使分支因子更高:保持简单,考虑其他增强功能(查看我的编辑)。 – 2012-02-09 22:44:55