2012-02-08 25 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