QOJ.ac

QOJ

總分: 100

#13463. 黑白棋

统计

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),這裡的 Taskidyourside 分別表示子任務編號和你是哪一方(yourside=0/1 分別表示你是黑/白棋)。你可以呼叫下面兩個函式與互動庫進行互動。

  1. MakeMove(position) 此函式要在輪到你下棋的時候呼叫,表明在 position 位置落子,你需要保證 $0\leq \texttt{position.first},\texttt{position.second}< 8$ 且落子合法,如果你沒有任何可走的位置請呼叫 MakeMove(make_pair(-1,-1)),如果棋局已經結束則你不應該再呼叫此函式,此函式沒有返回值。
  2. 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.cppreversi.htemplate-reversi.cppgamelauncher

其中 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\%$

或者逐个上传:

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.