Keep up your bright swords, for the dew will rust them. ——《Othello》
Othello 看著自己做過的一切,心中懊悔不已。他放下手中的劍,回顧自己一生的高低起伏、情海翻波。自己的嫉妒和猜忌最終毀掉了自己擁有的一切。
而誰又何嘗不是呢?塞翁失馬,焉知非福,福禍之間,相互轉化。現在的成功是過去一個又一個伏筆埋下的,而這有可能導致未來更多的可能。人生如棋,黑白之間,縱橫交錯——你曾經布下的棋子可能成為你路上的絆腳石。就像 Reversi 一樣(又稱 Othello),黑白之間,變換無常,只有真正目光長遠、統御全局的人才能在其中勝出。
題目敘述
Reversi,又稱 Othello、黑白棋,在一個 $8\times 8$ 的棋盤上進行,$(x,y)$ 表示第 $x$ 行第 $y$ 列($0$ 下標)。初始棋盤由四個交錯在中心的兩黑兩白構成——$(3,3)(4,4)$ 是白棋、$(3,4)(4,3)$ 是黑棋,雙方輪流下子,黑棋先手。新落下的棋子與棋盤上已有的同色棋子間,對方被夾住的所有棋子都要翻轉過來。可以是橫著夾,豎著夾,或是斜著夾。夾住的位置上必須全部是對手的棋子,不能有空格,且這一步必須至少夾住一個棋子,否則不合法。如果一個人的所有下法都是不合法的則跳過他的回合。一步棋可以在數個方向上翻棋,任何被夾住的棋子都必須被翻轉過來,棋手無權選擇不去翻某個棋子。如果一方至少有一步合法棋步可下,他就必須落子,不得棄權。棋局持續下去,直到棋盤填滿或者雙方都無合法棋步可下時,誰的子多誰贏。
實作細節
你不需要,也不應該實現主函式,你只需要實現函式 Play(Taskid,yourside),這裡的 Taskid 和 yourside 分別表示子任務編號和你是哪一方(yourside=0/1 分別表示你是黑/白棋)。你可以呼叫下面兩個函式與互動庫進行互動。
MakeMove(position)此函式要在輪到你下棋的時候呼叫,表明在position位置落子,你需要保證 $0\leq \texttt{position.first},\texttt{position.second}< 8$ 且落子合法,如果你沒有任何可走的位置請呼叫MakeMove(make_pair(-1,-1)),如果棋局已經結束則你不應該再呼叫此函式,此函式沒有返回值。ReceiveMove()此函式要在對手的回合呼叫,表明接收對手落子的位置,此函式將返回一個std::pair<int,int>類型的變數,表示對手落子的座標。如果得到 $(-1,-1)$ 表示對手這一步無法落子,你不應該在棋局結束後呼叫這個函式。
如果當前棋局已經結束,你應該從 Play 函式返回。
評測時,互動庫將呼叫 Play 恰好 $10$ 次。其中前 $5$ 次由你執黑,後 $5$ 次由你執白。所以你要注意在 Play 之後清空必要的變數。你的分數將由這 $10$ 局對局的非失敗(勝利或平局)場數決定。注意,如果你產生了非法操作,那麼將直接得到 $0$ 分。
保證互動庫使用的時間低於 $5\,\mathrm{s}$,空間低於 $10\,\mathrm{MB}$,這意味著你有至少 $5\,\mathrm{s}$ 的時間和 $502\,\mathrm{MB}$ 的空間可用。
如何除錯你的程式
本題只支援 C++。
將你的程式命名為 reversi.cpp。
請確保你的程式頭有 #include "reversi.h"。
你需要實現的介面如下:
void Play(int Taskid,bool yourside);
你可以呼叫的介面如下:
void MakeMove(std::pair<int,int> position);
std::pair<int,int> Receive();
如果你需要編譯你的程式,請在本題目錄下執行:
g++ grader.cpp reversi.cpp -o reversi -O2 -lm
下發的檔案包含 grader.cpp、reversi.h、template-reversi.cpp、gamelauncher。
其中 gamelauncher 是一個可供選手在電腦上的遊戲,規則與此題一樣,建議選手只用它來熟悉規則和玩耍,不要試圖透過各種方式以此程式為基礎獲得此題的分數(比如呼叫此程式來作為互動程式等)。由於平台問題,不保證程式和 UI 能正確地在所有平台上使用。另外,如果不能執行此程式,嘗試使用以下命令後再次執行:
chmod +x gamelauncher
評分方式
本題有四個子任務,分別由四個難度不同的 AI 與你進行互動。
AI(一)
此 AI 將會每次隨機挑選一個可以落子的位置(如果有的話),並進行落子。這部分是子任務一,價值 $10$ 分。
AI(二)
此 AI 將會在前期待機隨機落子,後期進行搜尋至遊戲結束來選擇最優策略。這部分是子任務二,價值 $20$ 分。
AI(三)
此 AI 會在前期待機搜尋一步的所有可能情況,按照某一個方式選擇下子,後期同 AI(二)。這部分是子任務三,價值 $30$ 分。
AI(四)
此 AI 是上帝的化身,自開天闢地之時便出現在這裡,非人力所為,本題的作者請它過來跟諸位對決。這部分是子任務四,價值 $40$ 分。
下發的互動庫使用了 AI(一),最終評測使用的互動庫與下發的互動庫實現方式有區別,請不要使用依賴互動庫的程式碼實現。注意:評測時使用的互動庫是帶有隨機性的,但下發的互動庫隨機種子是固定的,如果你想測試更多隨機的資料可以修改互動庫的 seed 變數來達到這個效果,你可以透過多次提交來提高分數。
你與 AI 對抗的得分如下表:
| 你輸掉的盤數 | AI1 | AI2 | AI3 | AI4 |
|---|---|---|---|---|
| $0$ | $100\%$ | $100\%$ | $100\%$ | $100\%$ |
| $1$ | $50\%$ | $80\%$ | $95\%$ | $100\%$ |
| $2$ | $30\%$ | $60\%$ | $90\%$ | $100\%$ |
| $3$ | $20\%$ | $40\%$ | $80\%$ | $98\%$ |
| $4$ | $10\%$ | $25\%$ | $70\%$ | $96\%$ |
| $5$ | $0\%$ | $10\%$ | $60\%$ | $92\%$ |
| $6$ | $0\%$ | $5\%$ | $40\%$ | $85\%$ |
| $7$ | $0\%$ | $0\%$ | $20\%$ | $70\%$ |
| $8$ | $0\%$ | $0\%$ | $10\%$ | $60\%$ |
| $9$ | $0\%$ | $0\%$ | $5\%$ | $40\%$ |
| $10$ | $0\%$ | $0\%$ | $0\%$ | $0\%$ |