五子棋AI演算法(一)
之前說想寫一些比較大型的演算法,想了半天,還是覺得寫五子棋的AI比較合適。一則因為自己研究過這個,有一些基礎,二則儘管現在網上有很多五子棋AI演算法的資料,但是確實都有些晦澀難懂。就想著借這個機會,憑自己的理解,儘量的講通俗一些。然而,這個演算法確實有些複雜,想要通俗一些需要較大的篇幅,一篇部落格難以講完,這裡就分很多個章節,一點一點的深入探討。為了讓文章更加通俗一些,我會略去一部分很簡單但是佔用篇幅很長的程式碼,改為用幾行註釋說明。
框架的搭建
首先,我們計劃是做一個五子棋AI,也就是說讓玩家和這個AI對下。整個遊戲的框架是這樣的:
其中,棋盤是一個Object,存放當前的棋局情況,通知每個Player“輪到你下棋了”、“對方下了什麼棋”、“遊戲結束,XXX獲勝”等訊息,並且從每個Player那裡獲取他下了什麼棋。兩個Player分別是人類玩家和AI。Player的基類應該是一個interface,裡面只有三個方法。人類玩家和AI是它的子類,分別實現這三個方法。
public interface Player {
Point play();
void display(Point p);
void notifyWinner(int color);
}
public final class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {return "(" + x + "," + y + ")";}
}
解釋一下:
- play 方法,告知“輪到你下棋了”,並且返回一個Point,也就是下一步下的棋。對於人類玩家,則就是阻塞,等待玩家在介面上選取一個點,並且將這個點的座標返回。對於AI,則是直接開始用我們的AI演算法進行計算,並返回計算結果。
- void display(Point p) 方法,告知“對方下了什麼棋”。對於人類玩家,則就是將對方下了的棋在介面上顯示出來。對於AI,則是將對方下了的棋記在AI的快取中,以便後續的計算。
- void notifyWinner(int color) 方法,告知“遊戲結束,XXX玩家贏了”。對於人類玩家,則就是在介面上展示誰贏了的文字及特效,並且從此之後再點選棋盤就不再有反應了。對於AI,則是通知AI不要再計算了。
當然了,如果打算連續下多盤棋,可能還需要一個reset方法,通知人類玩家和AI清空當前棋盤。當然了,這個和我們的演算法關係不大就不列出來了。
然後,我們的interface Player需要兩個實現類,分別叫做HumanPlayer和RobotPlayer,這個RobotPlayer的play方法將是五子棋AI演算法的核心內容,後面會花費大量篇幅進行講解。
接下來就是我們的棋盤:
public abstract class Constant {
public static int MAX_LEN = 15;
}
public class ChessBoard {
private byte[][] board = new byte[Constant.MAX_LEN][Constant.MAX_LEN];
private Player[] players = new Player[2];
private int whoseTurn = 0;
private int count = 0;
private boolean isEnd = false;
private boolean checkForWin(Point p) {
/* 因為篇幅問題,此處省略十幾行程式碼 */
/* 這個函式就是在下完每一步棋時呼叫,只需要判斷以這步棋若形成五連珠即可判定獲勝 */
return false;
}
public void play() {
if (isEnd) return;
Point p = players[whoseTurn].play(); //呼叫Player的play方法,獲取下一步下的棋
if (board[p.y][p.x] != 0) //嚴謹,以防萬一
throw new IllegalArgumentException(p.toString() + board[p.y][p.x]);
board[p.y][p.x] = (byte) (whoseTurn + 1);
System.out.println((whoseTurn == 0 ? "黑" : "白") + p.toString()); //列印日誌
if (++count == Constant.MAX_LEN * Constant.MAX_LEN) //嚴謹,如果棋盤下滿了遊戲結束
isEnd = true;
if (checkForWin(p)) //如果下了這步棋後贏了,遊戲結束
isEnd = true;
whoseTurn = 1 - whoseTurn; //切換當前下棋的人
players[whoseTurn].display(p); //呼叫Player的display方法,告知他對方下了哪步棋
if (isEnd) { //如果下完這一步棋後有一方贏了,則呼叫Player的notifyWinner方法通知
players[0].notifyWinner(2 - whoseTurn);
players[1].notifyWinner(2 - whoseTurn);
}
}
public static void main(String[] args) {
ChessBoard b = new ChessBoard();
b.players[0] = new HumanPlayer(1); //這裡我從建構函式中傳入了顏色,例如1表示執黑,2表示執白
b.players[1] = new RobotPlayer(2);
while (b.getWinner() == null) {
b.play();
}
}
}
棋盤的程式碼確實很簡單易懂,也做了很多註釋,就不多介紹了。
接下來,就只剩下HumanPlayer和RobotPlayer的實現了。
人類玩家
人類玩家無非就是實現三個方法:
- play 方法,阻塞等待玩家點選棋盤上的一個點並返回這個點
- display 方法,將AI下的棋展示在介面上
- notifyWinner 方法,顯示一行字“你贏(輸)了”
這段程式碼與本文無關,就不貼出來了,我把我做的這個醜陋的介面貼出來展示一下,哈哈。
(不要吐槽我的介面,這不是重點。)
RobotPlayer
AI才是重點內容,涉及了大量的演算法和數學知識,博弈樹、評估函式、極大極小值搜尋、啟發式搜尋、α-β剪枝等等,將會佔用大量的篇幅。從下篇部落格開始,將對此逐一展開。
相關文章
- Java學習筆記(七):五子棋AI演算法Java筆記AI演算法
- python做一個人機對戰五子棋,AI版本PythonAI
- 用 go 寫的五子棋預測演算法Go演算法
- AI 演算法崗工資一覽AI演算法
- 五子棋AI:實現邏輯與相關背景探討(上)AI
- 五子棋AI:實現邏輯與相關背景探討(下)AI
- PyGame每日一練——五子棋小遊戲GAM遊戲
- 使用QT creator實現一個五子棋AI包括GUI實現(8K字超詳細)QTAIGUI
- 使用 AI 解決一道演算法題AI演算法
- 五子棋javaJava
- 實現一個質量過硬五子棋
- js五子棋效果JS
- 逆水寒五子棋怎麼玩?逆水寒五子棋玩法攻略
- python 五子棋原始碼Python原始碼
- 五子棋遊戲(Java)遊戲Java
- AI及其判別演算法AI演算法
- 遞推演算法,AI衍生演算法AI
- JS之五子棋遊戲JS遊戲
- AI演算法測評(二)--演算法測試流程AI演算法
- 深信服的AI平臺瞭解一下?看它如何助力AI演算法敏捷開發AI演算法敏捷
- 前端談談實現五子棋前端
- java簡單練習-五子棋Java
- C++物件導向五子棋C++物件
- AI演算法測試之淺談AI演算法
- AI美顏SDK演算法詳解AI演算法
- 基於Flutter製作的五子棋Flutter
- C語言五子棋小遊戲C語言遊戲
- python 五子棋原始碼 V2Python原始碼
- 安卓開發 五子棋遊戲安卓遊戲
- 演算法工程師眼中的AI崗位演算法工程師AI
- Python:遊戲:五子棋之人機對戰Python遊戲
- Java簡單實現無介面五子棋Java
- 類設計方法:以五子棋為例
- 基於 Blazor 開發五子棋⚫⚪小遊戲Blazor遊戲
- C語言實現小遊戲:五子棋C語言遊戲
- 米粿AI:AI動漫賽道頭部創業公司招聘AI演算法實習生/工程師AI創業演算法工程師
- 演算法金 | AI 基石,無處不在的樸素貝葉斯演算法演算法AI
- AI殺入影視圈:演算法再造李佳琦,中戲開招AI博士AI演算法