1. 程式人生 > >五子棋 AI(AIpha-beta算法)

五子棋 AI(AIpha-beta算法)

sun 大於 不同的 遍歷 abcde 兩個 ive min 是不是

博弈樹

下過五子棋的人都應該知道,越厲害的人,對棋面的預測程度越深。換句話講,就是當你下完一步棋,我就能在我的腦海裏假設把我所有可能下的地方都下一遍,然後考慮我下完之後你又會下在哪裏,最後我根據每次預測的局勢好壞來判斷我的下一步棋放哪最合適。當然這只是想了一層,一個專業的棋手思考的層數會多得多。

作為一個難度較大的 AI,勢必也需要能夠對棋局進行深入分析,然而五子棋的棋盤大小一般是 15 * 15,可以落子的地方太多,在這種情況下,電腦的性能有限,我們需要滿足 AI “思考”的層數不能太低,同時算法的效率要高。

以三子棋為例,AI 思考的過程就如同下面這課樹一樣,我們用圓圈代表玩家,叉號代表 AI,根節點是用戶的落子。

技術分享圖片

如果繼續畫下一層,那麽下一層就是玩家下一步的落子,這也就是 AI 思考的層數又多了一層。

有了這棵樹,我們就需要得出每個節點的得分是多少,以判斷哪一步是最優的。

得分

要考慮這一步棋是不是最優的,我們需要給每一步棋都設定一個得分,然後找出最憂的。當前棋面的得分多少,需要同時考慮玩家和 AI 分別的得分。

以三子棋為例,當玩家下在左上角的時候,我們考慮 AI 下在正中間時的得分。得分的計算方法是將棋面的空白地方用棋子填滿,然後得出連成三個的個數有多少。(如果是五子棋,應該只需找出當前棋面上所有連子,然後根據每種連子的權重來計算得分)

技術分享圖片

如圖,玩家一共有 4 個成三,而 AI 一共有 5 個,所以總得分是 5 - 4 = 1

這裏需要指出的是,在博弈樹中,一個節點的得分是取決於他的子節點的,也就是說,當 AI 只思考一層,也就是上圖這樣,這棵樹的末尾就是只有兩個棋子,那麽這個節點的得分就是這樣計算,而如果這個節點下還有子節點,那麽我們只會計算葉子節點的得分,然後從葉子節點開始,一步步倒推出父節點的得分。下面來進行解釋倒推的過程。

博弈

當 AI 下棋時,我們必定要讓 AI 下在得分最高的位置,這毋庸置疑。但是以 AI 的角度來考慮玩家的落子,我們需要假設玩家是“聰明的”,他會下在對自己最有利的地方,也就是得分最低的地方(因為得分 = AI 分數 - 玩家分數)。

這就造成每一層的性質是不同的,在玩家落子的層裏,我們要選取得分最低的;在 AI 落子的層裏,我們要選取得分最高的。所以我們稱玩家層為 MIN 層,AI 層為 MAX 層。

極大極小搜索

上面提到了,計算出葉子節點之後,我們需要倒推出父節點的得分,倒推的原則其實就是上面說的:MAX
層中的節點會從子節點中挑選最大得分的節點作為它的得分,MIN 層的節點會從子節點中挑選最小得分的節點作為它的得分。

以下圖舉例:

技術分享圖片

因為我們是根據子節點的得分來倒推父節點的得分的,所以我們是用深度優先來遍歷博弈樹的,在上面這棵樹中,遍歷順序是 ABCDEFGHIJ,賦值過程如下:

  1. 遍歷完 A B,因為 C 是 MIN 層,所以選取 AB 中最小的,即 8 作為 C 的得分
  2. 遍歷完 D E,F 的得分為 6
  3. 遍歷完 G H,I 的得分為 5
  4. 因為 J 在 MAX 層,所以選取 C F I 中得分最大的,即 8 作為 I 的得分

alpha-beta 剪枝

從上面可以想到,像五子棋這種可能性很多的情況,這棵樹會變得非常大,當層數增加的時候,計算量也會越來越大,如果不采取一些方法,我們只能靠犧牲層數來換取運行時間。

那麽 alpha-beta 剪枝就是一種行之有效的方法,顧名思義,采用這種方法,我們會剪去一些不必要的樹枝,也就減少了運行的時間。

alpha-beta 剪枝的定義很繞口,但是原理很簡單,還是以上面那課樹為例:

技術分享圖片

當遍歷到 C 的時候,計算出 C 的得分是 8,因為 J 的得分是 C、F、I 之中最大的,所以此時可以得出 J >= 8

接下來遍歷到 D,D 的值為 6,因為 F 的值是 D 和 E 之中最小的,所以即使現在還沒有遍歷完 F 的子節點也可以得出 F <= 6,那麽既然 J 已經大於等於 8 了,所以繼續遍歷 F 已經沒有意義了,那麽我們就將 F 這條枝剪掉。

同理,當 G 為 5 時,遍歷 I 已經沒有意義了,因為 I 不可能再大於 5,所以直接得出 J 為 8

可以看出,當節點很多的情況下,使用 alpha-beta 剪枝是能在一定程度上提高運行效率的。

原文地址:http://sunhengzhe.com/2016/07/31/five-in-a-row-game/

五子棋 AI(AIpha-beta算法)