關於五子棋電腦AI演算法的一些思考
這個部分是一個重點,也是一個難點,也是一個隊伍最有可能出彩的一部分。我看了一些資料,但是現在我有了新的想法。
大部分演算法中,都要進行兩步。第一步是優先順序的計算,然後是打分。但是我在想能不能通過某種數學模式把這兩種計算融合在一起。也就是說,我們能夠從所打的分中間識別出優先順序。這使我想到了數學十進位制中的位。反正我最主要是從四個方向進行判定,所以某些優先順序低的,我們在給其打分的時候,就將它的分數設為處在其優先順序之上的十分之一。其實我覺得這裡只要大於其分數的八倍就可以,因為我最後選取最優位置的方法是累加法,算出分數和最高的位置,這樣的話,即使在四個方向上某較低優先順序都出現了,但是即使全加起來也不會超過較高優先順序的分數,這樣的話,如果出現優先順序較高的情況,那麼我們計算的結果必然是優先順序較高的分數最高。這樣,變省去了一些不必要的分類,使得演算法更直接,更容易理解。
首先我們先來看一下置棋時的優先順序分佈以及我為其所指定的打分方案:
首先宣告的是,對於已經五子相連的情況,我們在此部分演算法中不再實現,因為這個時候勝負已經分出,我們呼叫checkboard類的judge的方法便可以了。這只不過是在電腦AI後再將judge的程式碼複製過去罷了。
我們的目的是給棋盤上的空位進行打分,進而算出分數最高的位置。那麼我在這裡想運用試探法,因為我覺得這樣的話程式碼比較好寫。所謂試探法就是,我們找出棋盤上的所有空位,然後我們假設這個空位上放置的是白棋,然後看看相連的情況,然後打分,並將分數加至儲存該空位分數的變數;再假設這個空位上放置的是黑棋,然後再看相連的情況,然後打分,並將分數加至儲存該空位分數的變數;這樣遍歷完所有的空位的時候,我們便完成了打分工作,然後再比較空位的分數,選出分數最高的空位,該位置即為最優的位置。
下面是一些情況的優先順序排列:(假設我們是白棋)下列情況均為在該空位置棋之後:
在實現的時候,我們還需要定義兩個臨時的Checker指標變數,用來儲存相連的一串棋子前後的位置的狀態。color用來儲存棋子的顏色,count用來儲存相連的棋子的個數,temptr1與temptr2用來儲存兩端的棋子指標。文中的我們是電腦哦!
情況 |
所打分數 |
color=1&&count=5我們先贏,贏了再說 |
100 000 0000 |
Color=0&&count=5對方要贏,如果我們不能先贏,那麼一定得先阻攔 |
10 000 0000 |
Color=1&&count=4&&!temptr1&&!temptr2雙方均不會贏,如果我們能成活四,那麼敵方必輸,所以要先置棋 |
1 000 0000 |
Color=1&&count=4&&((!temptr1&&temptr2)||((temptr1)&&!temptr2))雙方均不會贏,那麼如果我們能成衝四,則要先置棋,牽著敵方的鼻子走,因為下過本步棋之後敵方一定會來阻止我們 |
100 0000 |
Color=0&&count=4&&!temptr1&&!temptr2雙方均不會贏,如果對方能成活四,那麼我們一定要優先阻攔,否則便會輸棋 |
10 0000 |
Color=1&&count=3&&!temptr1&&!temptr2雙方均不會贏,如果我們能成活三,則要優先這個位置 |
1 0000 |
Color=0&&count=4&&((!temptr1&&temptr2)||((temptr1)&&!temptr2))雙方均不會贏,如果敵方能成衝四,那麼我們要盡力阻攔 |
1 000 |
Color=1&&count=3&&((!temptr1&&temptr2)||((temptr1)&&!temptr2))雙方均不會贏,如果我們能成衝三,那麼要優先這個位置 |
1 00 |
Color=1&&count=2&&!temptr1&&!temptr2雙方均不會贏,如果我們能成活二,則要優先這個位置 |
1 0 |
Color=1&&count=2&&((!temptr1&&temptr2)||((temptr1)&&!temptr2))雙方均不會贏,如果我們能成衝二,那麼要優先這個位置 |
1 |
其他情況 |
0 |
這個演算法的主要思想是,對於敵方構不成威脅的情況,(即活四以下,但是這裡我們把衝四也算進來了,並賦予了較高的優先順序),我們暫不理會,而是一心想著自己怎麼能贏。這裡我們只能分成這麼多情況,因為假設我們的分數是long型的,那麼它的長度是32位,轉換成十進位制,位數也就是10位,因而我選了最大的分數為1000 000 000,這樣剛好能滿足要求。
但是這裡有個小小的問題,就是在剛開始落子的時候,怎麼落?我想這個時候我們可以事先設定某個空位的分值為髙值,落棋之後分數便置為0了。當對方先下的時候,我們就將第一個棋子放在對方棋子的周圍,啟動AI,這樣接下來問題便簡單了,因為一定會出現衝二,進而便是對方的活四,然後再防守,這樣一步步,便展開了。
相關文章
- 關於尋路演算法的一些思考(12):AI 技術演算法AI
- 關於尋路演算法的一些思考(1):A*演算法介紹演算法
- 關於CodeReview的一些思考View
- 關於 Masonry 的一些思考(下)
- 關於 教育孩子的 一些思考
- 關於程式碼的一些思考
- 關於尋路演算法的一些思考(4):A* 演算法的變體演算法
- 關於尋路演算法的一些思考(3):A*演算法的實現演算法
- 關於尋路演算法的一些思考(2):Heuristics 函式演算法函式
- 關於尋路演算法的一些思考(7):地圖表示演算法地圖
- 關於目標的一些思考
- 關於賬號安全的一些思考
- 關於電腦(window)後門檢視的一些總結
- 關於電梯阻塞原因的小思考
- 關於微服務劃分的一些思考微服務
- 關於Code Review的一些思考總結View
- 關於RxJava在業務上的一些思考RxJava
- 關於近源滲透的一些思考
- 關於伺服器效能的一些思考伺服器
- 關於效率、程式與生活的一些思考
- 【原】關於AdaBoost的一些再思考
- 關於設計評審的一些思考
- Chris Dixon:關於移動的一些思考
- 關於REACT正規化的一些思考React
- 關於作業系統的一些思考作業系統
- 關於尋路演算法的一些思考(11):尋路演算法的其他應用演算法
- 五子棋AI演算法(一)AI演算法
- 關於多層架構一些思考架構
- 關於模擬經營遊戲的一些思考遊戲
- 關於React中動畫不生效的一些思考React動畫
- 關於研發規範化的一些思考
- 近期關於快取設計的一些思考快取
- 關於效率的一些思考:節點創新
- 關於 `storage:link` Artisan 命令的一些思考
- 關於不完全恢復的一些思考
- 關於許可權系統的一些思考
- 關於以太坊 "雷電網路" 的思考
- 關於尋路演算法的一些思考(9):尋路者的移動成本演算法