五子棋 AI 程式競賽是讓參賽作品透過對奕的方式,比較並判定棋力的高低。在進行一場對奕時,競賽平台會安排雙方程式輪流擔任先攻的黑子以及是後攻的白子,依序呼叫雙方程式進行十個回合的競賽,若無法分出勝負責由程式執行時間較少的一方勝出。在每個回合,競賽平台會傳入一個代表棋盤的二維陣列,再由參賽程式依棋盤內容決定下棋的位置(請注意,每個回合都是獨立的,這代表你的程式不需要保留過去棋盤的內容)。
所以一個參賽的作品主要的工作就是在對奕的過程中:一、讀入棋盤內容;二、選擇最佳落子位置並輸出。在這份參賽指引文件中,我們將逐一說明如何完成上述兩個工作,並帶領你完成第一次的參賽作品上傳。
一個五子棋的棋盤,是由縱橫交錯的 19 行與 19 列所構成的。競賽平台會在對奕進行的過程中,建立並維護一個代表棋盤狀態的字元陣列,並在對奕進行時,依序將這個字元陣列,使用標準輸入流的方式傳遞給對戰的雙方。這個檔案總共有 19 列,每列顯示 19 個位置;每個位置使用字元「0」代表白子,字元「1」代表黑子,至於還沒有下棋子的位置則以「.」表示。為幫助同學理解,我們每一行中間安插一個空白字元,並在每一列後面換行。以下是一個範例陣列:
【/home/stu/public/gomoku/chessboard.txt】
為了便利後續測試,建議同學可以依據上述內容建立一個文字檔案 chessboard.txt。或者也可以從ws上的/home/stu/public/gomoku/裡複製取得chessboard.txt檔案用以測試。
由於參賽作品要能夠正確地接收到競賽平台所傳遞的棋盤內容,必須要能夠正確的讀取標準輸入流;至於所接收到的內容,則可以將其儲存到一個 19x19 的二維陣列裡,供後續計算落子位置之用。以下的程式 main.c
簡單示範了如何讀取棋盤內容,並為了測試是否正確讀入,再使用迴圈來印出棋盤內容:
【/home/stu/public/gomoku/main.c】
以上檔案已存放於ws上的/home/stu/public/gomoku/main.c,同學亦可自行複製取得。
請使用 gcc main.c
進行編譯並且執行 ./a.out < chessboard.txt
以測試是否正確讀入棋盤內容,其輸出結果應如下:
太棒了!現在您的程式已經可以順利將棋盤讀入!
在這一個章節,我們會告訴您如何讓您的程式符合比賽的資格,但您的程式仍不具備基本的棋力。一開始,最簡單的一種做法就是透過亂數的方式,隨機地將棋子下在棋盤上的任一個位置。以下的範例採用時間函數的方式建立亂數種子(當然,你也可以利用某個變數的記憶體位作為亂數種子):
【/home/stu/public/gomoku/rand.c】
編譯完成後輸入 ./a.out
執行程式,您可以發現每一次輸出的內容都是不一樣的。以下為範例輸出:
您的程式每次啟動時都會收到兩個命令列引數,其中argv[1] 的內容為字串「Black」或「White」,分別代表程式目前應該要下黑子或是白子。
賽場測試中,發現問題請洽 TA 或是 SA
你可以在屏東大學資工系計算機網路中心的主機(ssh <username>@ws.csie2.nptu.edu.tw
)上,完成前述程式的開發。
接下來只要將你的程式碼透過 turnin 指令上傳,就可以完成參賽。建議你可以將所有要上傳的檔案依下列架構加以準備:
檔案名稱 | 說明 |
---|---|
main.c | 主程式 |
function.c | 各項函式,當然您也可以建立多個檔案以管理不同函式 |
function.h | 函示標頭檔案,用於定義函式 |
Makefile | Makefile,產生以你學號為檔名的可執行檔 |
<系計中帳號>.webp | 大頭貼(正方形,解析度 >= 300*300,WebP 格式,可以使用 scp指令或filezilla 上傳到工作站後再 turnin 到競賽伺服器上 |
Makefile 範例檔:
欲參賽的同學必須先使用 ssh 連線到 ws.csie2.nptu.edu.tw,並且使用 turnin上傳(turnin code:gomoku2025)例如參賽同學cbb113000想上傳上述的所有檔案,使用以下指令:
再次提醒同學,你可以自行決定所需要的檔案及其名稱,但「必須」提供 Makefile 以及確保編譯出的可執行檔檔名為你的系計中帳號(例如上例中的 cbb113000)
目前2024年起,新版的競賽平台啟用後,有一些與過往不同的地方,請同學們注意:
<系計中帳號>.webp
。你可以在網路上找到轉換器或是使用 FFmpeg 手動轉換。過去的參賽作品已自動完成此步驟。完成 turnin 後,就可以到五子棋競賽網站登入,並檢查是否能夠由平台順利完成編譯。