【數字影象處理】帶AI的井字棋遊戲
老師看了Alpha狗和李世石的比賽,一拍大腿就把作業題給改了。。。也是醉
Ø 【作業要求】
寫一個matlab程式,完成一個人工智慧任務
例如:
數學邏輯(幻方,漢諾塔,海盜分金,各種過河問題…)
棋類博弈(井字棋,奧賽羅,五子棋,象棋,圍棋…)
文字遊戲(微軟小冰,吟詩作賦,對聯猜謎…)
……
基本要求:
突出程式的智慧特性(思考,推理,自學習…)
可以考慮簡化的遊戲規則(如小棋盤…)
如能和影象處理結合更佳…
總結策略的特色與不足…
Ø 【作業內容】
使用博弈樹上的Negmax演算法,加上Alpha-Beta剪枝,實現了井字棋遊戲的AI。
井字棋遊戲是一種簡單的棋類遊戲,在3*3的棋盤上,兩人輪流下子,誰的棋子先連成3顆一條直線(可以橫著、豎著、斜著),誰就贏了。
Ø 【作業思路】
一、 演算法介紹
(1) 博弈樹上的Negmax演算法
使用博弈樹搜尋時,有一個假設,就是博弈雙方都足夠聰明,每次都會選擇對自己最優的策略進行決策。
Negmax演算法是基於MinMax演算法進行的改進。MinMax演算法中,對每種棋盤局面都有一個估價函式,對A方有利的估價為正數,對B方有利的估價為負數。因此,當A方落子時,必然會選擇使得局面估價函式最大的一步,對應了Max;反之,當B方落子時,必然會選擇使得局面估價函式最大的一步,對應了Min。
而Negmax演算法是在博弈樹搜尋時,將每個子節點返回的估價值取相反數,再進行局面估價。這樣,對於A和B而言,都是選擇使得估價最大的一種取法,可以使得對於局面的處理方式保持統一。
(2) 估價函式
估價函式是演算法中非常重要的一部分。我採用的估價函式是將所有空著的格子填充成當前玩家的棋子,並計算所有的行、列、對角線有多少連成3個的棋子,並將這些棋子的總個數作為估價值。如果某一方在當前局面下已經勝利,那麼估價值設為無窮大(程式中使用一個很大的數值即可)。
(3) 視覺化
我使用了plot函式來繪製棋盤和棋子,並加上了滑鼠操作。
其中,棋盤是繪製了若干藍色的直線,棋子是繪製了圓形,通過填充顏色來區分白子和黑子,實現方法如下:
滑鼠的控制是在Userinput.m函式中實現的,我通過ginput()函式獲取滑鼠的座標位置,並據此判斷滑鼠當前落在哪一個棋盤格子內,從而獲取使用者的落子位置。實現方式如下:
其中,需要注意的是,外層套了一個while(true)的迴圈,並在迴圈內檢測滑鼠位置是否落在棋盤區域內。這樣可以保證使用者在隨意點選滑鼠時,不會被誤判為落子。
最後還有勝負和平局的判斷:
Ø 【總結】
博弈樹是很多二人對抗遊戲都可以採用的一種AI決策方式,但是整棵博弈樹的搜尋所產生的狀態空間是巨大的並且在時間和空間上難以承受的。
本次作業演算法的一個特點就是採用了Negmax和Alpha-Beta剪枝,這樣大大減少了博弈樹的狀態空間,可以使程式檢測更多的狀態,從而獲得更優的決策方案。經過測試,人幾乎贏不了這個井字棋的AI,也說明了該演算法在井字棋的規則下已經足夠優秀。
由於井字棋3*3的棋盤比較小,導致AI完全可以選擇非常優的策略,所以有一點不足就是這個遊戲的趣味性就會有些欠缺。如果擴大棋盤,或者改變一下規則,比如連成4子才算勝利等,可能會更有趣。