题目背景
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\% $ |