最近做了五子棋,記錄下自己完成五子棋的人機對戰的思路。
首先,思路是這樣的:每當人手動下一顆棋子(黑子)的時候,應當遍歷它周圍棋子的情況,並賦予周圍棋子一定的權值,當在機器要下棋子(白子)守護之前,會遍歷整個棋盤的權值情況(棋盤的權值存在一個二維數組中),從中找出權值最大的點坐標,並下子(白子)。
這樣的話,問題就集中在兩個方面了,一個是:如何遍歷黑子周圍的棋子情況? 另一個是:如何設定權值?
首先,是設定權值。這個沒有固定的設定方案,可以先試着設定,然后,嘗試效果后(主要是白子的攻防情況是否合理),再調整。
以下是我的設定方案:
接着,是相對困難的部分,就是如何遍歷黑子周圍的棋子情況。 從之前權值方案中可以看到,設置權值的一個很重要的目的是為了進行防守,所以應當在連續黑子的兩端(下面圖中的橙色區域)設置權值,這樣就有利於白子填充在連續黑子的兩端,從而達到防守的目的,下面這張圖可以說明:
中心的黑子:表示當前所下的黑子,周圍的棋子表示是之前下的。
紅色箭頭:表示需要遍歷的八個方向,因為中心黑子的坐標(i, j)是已知的,所以很容易得到周圍的棋子坐標(i+n, j+m)。
橙色方框:表示連續黑子的末端,可能是空白(表示還沒有棋子填充),也可能是白子。
接着是算法思想:
首先,應當先判斷敵方棋子(黑子)第一次下的時候(敵方棋子先下),此時,周圍八個棋子都是空的,於是應當對周圍八個點賦予相同的權值(活一),當遍歷整個棋盤后,便在這八個點中隨機選擇一個(用隨機數),填上黑子。
接着,敵方繼續下子,如果敵方當前所下棋子與之前的棋子連續,則會構成活二或者眠二(以此類推,會構成活三眠三~~),這時,根據權值表,會賦予周圍棋子更大的權值(權值應當是累加的,也就是說,當前權值 += 之前權值),最后遍歷后,下白子。