# 國立屏東大學電腦五子棋 AI 程式競賽 - 參賽指引 <!--- ## Table of Contents - [Preliminary](#Preliminary) - [讀入棋盤](#讀入棋盤) - [黑子與白子](#黑子與白子) - [先手與後手](#先手與後手) --> 五子棋 AI 程式競賽是透過讓參賽作品進行對奕的方式,比較並判定棋力的高低。在進行一場對奕時,競賽平台會安排雙方程式擔任先攻的黑子或是後攻的白子,接著會依序輪流呼叫對奕的雙方程式進行多個回合,直到分出勝負(或是已無位置可下的平局)為止。在每個回合,競賽平台會傳入一個代表棋盤的二維陣列,再由參賽程式依棋盤內容決定下棋的位置(請注意,每個回合都是獨立的,這代表你的程式不需要保留過去棋盤的內容)。 所以一個參賽的作品主要的工作就是在對奕的過程中:(1)讀入棋盤內容、(2)。在這份參賽指引的文件中,我們將為你逐一說明如何完成上述兩個工作,並帶領你完成第一次的參賽上傳。 ## 讀入棋盤 一個五子棋的棋盤,是由縱橫交錯的 19 行與 19 列所構成的。競賽平台會在對奕進行的過程中,建立並維護一個代表棋盤狀態的文字檔案,並在對奕進行時,依序將這個文字檔案,使用 I/O redirect 的方式傳遞給對戰的雙方。這個檔案總共有 19 列,每列顯示 19 個位置;每個位置使用<mark>字元「0」代表白子,字元「1」代表黑子,至於還沒有下棋子的位置則以「.」表示</mark>,並在任意兩個相鄰位置裡安插一個空白字元加以分隔。為幫助同學理解,以下顯示了一個代表棋盤狀態的文字檔案內容如下: ```text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0 . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ``` 為了便利後續測試,建議同學可以依據上述內容建立一個文字檔案 chessboard.txt。 由於參賽作品必須要能夠正確地接收到競賽平台所傳遞的棋盤內容,所以必須要能夠以「<」(I/O redirect)的方式加以接收;至於所接收到的內容,則可以將其儲存到一個19x19的二維陣列裡,供後續計算下子位置之用。以下的程式`main.c`簡單示範了如何讀入透過I/O redirect所傳入的棋盤內容,並為了測試是否正確讀入,後續再使用迴圈來印出棋盤內容: ```c #include <stdio.h> int main(){ char chessboard[19][19]; int i = 0, j = 0; for(i=0; i<19; i++){ for(j=0; j<19; j++){ scanf(" %c", &chessboard[i][j]); } } printf(" A B C D E F G H I J K L M N O P Q R S\n"); for (i=0; i<19; i++){ printf("%2d ", i + 1); for(j=0; j<19; j++){ printf("%c ", chessboard[i][j]); } printf("\n"); } } ``` 請使用 `gcc main.c` 進行編譯並且執行 `./a.out < chessboard` 以測試是否正確讀入棋盤內容,其輸出結果應如下: ```text A B C D E F G H I J K L M N O P Q R S 1 . . . . . . . . . . . . . . . . . . . 2 . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . 6 . . . . . . . . . . . . . . . . . . . 7 . . . . . . . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . . 9 . . . . . . . . 0 . . . . . . . . . . 10 . . . . . . . . . 1 . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . 12 . . . . . . . . . . . . . . . . . . . 13 . . . . . . . . . . . . . . . . . . . 14 . . . . . . . . . . . . . . . . . . . 15 . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . 17 . . . . . . . . . . . . . . . . . . . 18 . . . . . . . . . . . . . . . . . . . 19 . . . . . . . . . . . . . . . . . . . ``` 太棒了!現在您的程式已經可以順利將棋盤讀入! ## 使用亂數下子 在這一個章節,我們會告訴您如何讓您的程式符合比賽的資格,但您的程式仍不具備基本的棋力。一開始,最簡單的一種做法就是透過亂數的方式,隨機地將棋子下在棋盤上的任一個位置。以下的範例採用時間函數的方式建立亂數種子(當然,你也可以利用某個變數的記憶體位址建立隨機亂數): ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main(){ char chessboard[19][19]; char letters[19] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S'}; int row = 0, col = 0; srand(time(NULL)); // 或是使用某個變數的記憶體位址建立隨機亂數 // srand((unsigned long int)&row); row = rand()%19; col = rand()%19; printf("%c, %d\n", letters[col], row+1); } ``` 編譯完成後輸入 `./a.out` 執行程式,您可以發現每一次輸出的內容都是不一樣的。以下為範例輸出: ```bash realtime@realtimedeMacBook-Pro Gomoku-Example % ./a.out R,▴6⏎ ``` ## 測試參賽作品 你可以在屏東大學資工系計算機網路中心的主機上,完成前述程式的開發後,再使用 ssh 連線到 ws2.csie2.nptu.edu.tw(e.g. `ssh ws2.csie2.nptu.edu.tw`),然後輸入語法 **gomoku | gomoku1 | gomoku2 yourProgram 棋子顏色**(e.g. `gomoku ./a.out Black`) 來測試您的程式是否可以正常運作,其中 gomoku、gomoku1、gomoku2 分別代表著不同棋力的AI對手,你可以先透過這些指令檢查你的程式是否符合參賽的規定。至於棋子顏色在此階段並不重要,因為目前的版本不論你擔任的是黑子或白子,都只是簡單地使用亂數來輸出所要下的位置而已。關於黑子、白子的進一步說明,請參考下一份教學文件。 ## gTurnin 參賽作品 接下來只要將你的程式碼透過 gturnin 指令上傳,就可以完成參賽。建議你可以將所有要上傳的檔案依下列架構加以準備: ```text . └── Gomoku_Project_Floder/ ├── main.c ├── function.c ├── function.h ├── Makefile └── photo.webp ``` | 檔案名稱 | 說明 | | -------------- | -----------------------------------------| | main.c | 主程式 | | function.c | 各項函式,當然您也可以建立多個檔案以管理不同函式 | | function.h | 函示標頭檔案,用於定義函式 | | Makefile | [Makefile](https://www.gnu.org/software/make/manual/make.html),產生以你學號為檔名的可執行檔 | | photo.webp | 大頭貼(正方形,解析度 >= 300*300),可以使用 [scp](https://linux.die.net/man/1/scp) 指令上傳到工作站後再 turnin 上競賽伺服器 | Makefile 範例檔: ```makefile all: main.c function.o cc -o cbb112000 main.c function.o function.o: function.c cc -c function.c clean: rm *.o a.out *.*~ ``` 欲參賽的同學必須先使用ssh連線到 ws2.csie2.nptu.edu.tw,並且使用gturnin上傳(gturnin code: gomoku2024-test) 例如參賽同學想上傳所有檔案,可參考以下指令: ```bash [19:38 cbb112000@gs]$ gturnin gomoku2024-test main.c funciton.c function.h Makefile photo.webp ``` **再次提醒同學,你可以自行決定所需要的檔案及其名稱,但「必須」提供 Makefile 以及確保編譯出的可執行檔檔名為你的系計中帳號(例如上例中的 cbb112000)** ## 前往對戰平台網站 完成 gturnin 後,就可以到[五子棋競賽網站](https://gomoku.csie.nptu.edu.tw/)登入,並檢查是否能夠由平台順利完成編譯。