题面

查看题面

题目背景

鸭棋是一种风靡鸭子界的棋类游戏。事实上,它与中国象棋有一些相似之处,但规则不尽相同。在这里,我们将为你介绍鸭棋的规则。

鸭棋在一个 \(10\times 9\)(\(10\) 行 \(9\) 列)的网格棋盘上进行,网格上的每个格点都可以有棋子停留。对弈双方一方执红(red)棋、另一方执蓝(blue)棋,双方轮流执行操作,轮到一位玩家操作时,他必须选择一枚自己的棋子,并按照规则进行一步移动。

鸭棋发明者鸭子德规定一局鸭棋由红方执先手,并设计了初始棋盘布局如下

棋子类型与走子规则

棋子分为 \(7\) 类,下面介绍了它们的名字以及它们的移动规则。介绍移动规则时,我们默认棋子所处位置为 \(\left( x,y\right)\)(表示第 \(x\) 行的第 \(y\) 列,下同),并列出它可以到达的位置:

  • captain):可达的位置共 \(4\) 个,包括 \(\left(x\pm 1,y\right)\) 及 \(\left(x,y\pm 1\right)\)。
  • guard):可达的位置共 \(4\) 个,包括 \(\left(x\pm 1,y\pm 1\right)\) 及 \(\left(x\pm 1,y\mp 1\right)\)。
  • elephant):可达的位置至多 \(4\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:
    • 如果位置 \(\left(x+s_x\times 1 ,y+ s_y\times 1\right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 2\right)\) 为一个可达的位置。
  • horse):可达的位置至多 \(8\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:
    • 如果位置 \(\left(x+s_x\times 1 ,y\right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 1\right)\) 为一个可达的位置。
    • 如果位置 \(\left(x ,y+ s_y \times 1 \right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 1,y+s_y \times 2\right)\) 为一个可达的位置。
  • car):可在不跨越其他棋子的前提下,到达同行或同列的所有其他位置。
  • duck):可达的位置至多 \(8\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:
    • 如果位置 \(\left(x+s_x\times 2 ,y+s_y \times 1\right),\left(x+s_x\times 1 ,y\right)\) 上均无任意一方的棋子停留,则 \(\left( x+s_x \times 3,y+s_y \times 2\right)\) 为一个可达的位置。
    • 如果位置 \(\left(x+s_x \times 1 ,y+ s_y \times 2 \right),\left(x ,y+ s_y \times 1 \right)\) 上均无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 3\right)\) 为一个可达的位置。
  • soldier):可达的位置共 \(8\) 个,包括 \(\left(x\pm 1,y\right)\) 及 \(\left(x,y\pm 1\right)\) 及 \(\left(x\pm 1,y\pm 1\right)\) 及 \(\left(x\pm 1,y\mp 1\right)\)。

除上面描述的规则之外,棋子移动还有如下额外规则:

  • 不能将棋子移动到棋盘外的某个位置。
  • 玩家不能将棋子移动到已经停留了己方棋子的位置。
  • 如果玩家将棋子移动到了一个已经停留了对方棋子的位置,那么原本停留在该位置上的这个对方棋子将被移出游戏。

胜利条件与将军局面

玩家在这个游戏中的目标是将对方的移出游戏。一旦一方的被移出游戏,则另一方立即宣告胜利。

对于一个棋盘的状态,如果存在一方有一步合法的操作能够将另一方的移出游戏,则我们说当前局面是一个将军的局面。需要友情提示的是,根据定义,将军局面的形成包括(但不限于)如下这些可能:

  1. 一方将一枚棋子移动到可以攻击对方的位置

  2. 在己方受到威胁时不采取措施躲避

  3. 主动将移动至会受到攻击的位置

除此之外,需要特别说明的是,游戏结束后,由于双方不可再操作,因此不可能出现将军局面,即便此时另一方王处于被「攻击」的位置。

题目描述

今年的 IDCC(International Duck Chess Competition,国际鸭棋大赛)正在如火如荼地进行着。你观摩了一场精彩绝伦的比赛,但你对对弈过程的记忆已经模糊不清了,只有系统留下的他们的操作序列,序列中的每个操作为当前操作者试图移动某个位置的棋子至另一个位置。你希望用这个序列,来复现出整局棋局的对弈过程。即,对于每步操作,你需要首先判其是否合法,若合法,则进一步求出

  1. 这步操作移动了哪个棋子。
  2. 这步操作后,是否存在棋子被移出游戏,如有则还需求出被移出游戏的棋子。
  3. 这步操作后,是否形成将军局面。
  4. 这步操作后,游戏是否结束。

可能包含的不合法情况如下:

  • 此步移动的初始位置无己方棋子停留。
  • 此步移动的初始位置有己方棋子停留,但移动不符合规则。
  • 游戏已经结束。

序列中的不合法操作是需要被忽略的。比如,如果轮到红方移动,此时序列中的当前操作恰好是不合法的,则这个操作将被忽略,序列中的下一步操作将成为红方这步的操作(如仍不合法则继续忽略,直至出现合法的操作)。

输入格式

第一行一个非负整数 \(Q\),表示操作序列的长度。接下来依次描述每个操作。

接下来 \(Q\) 行,每行 \(4\) 个整数 \(x_s, y_s, x_t, y_t\)(\(0\leq x_s,x_t < 10\),\(0\leq y_s,y_t < 9\)),描述一个欲将 \(\left(x_s,y_s\right)\) 处棋子移动到 \(\left(x_t,y_t\right)\) 的操作。在这里,我们规定左下角(即红方摆放的位置,图见「题目背景」)为 \(\left(0,0\right)\)。

保证 \(Q\leq 1000\)。

输出格式

输出 \(Q\) 行,对于每个操作依次输出复现结果。每行输出一个操作的结果:

  • 如果该操作为不合法操作,则请输出 Invalid command
  • 如果为合法操作,则依次回答「题目描述」中的问题 \(1\sim 4\):
    • 被移动的棋子用 [颜色] [类型](注意中间包含空格)来描述,请使用它们的英文名称(见「题目背景」)。如,红象为 red elephant,蓝王为 blue captain
    • 被移出游戏的棋子的描述方式与上面类似。特别地,如果无棋子被移出游戏,则该问题的答案为 NA
    • yesno 分别表示形成、不形成将军局面。
    • yesno 分别表示游戏结束、游戏不结束。
    • ;(分号)将所有问题的答案隔开。
    • 比如,四个问题的答案分别为:被移动的棋子是蓝车,无棋子被移出游戏,形成将军局面,游戏未结束。则该行应输出 blue car;NA;yes;no

版权信息

来自 THUPC(THU Programming Contest,清华大学程序设计竞赛)2019。

其他资源可在 Github 查看。

思路

大模拟。

棋子棋盘表示

棋子我们使用一个数字来表示:

棋子名 数字 棋子名 数字
红王 11 蓝王 21
红士 12 蓝士 22
红象 13 蓝象 23
红马 14 蓝马 24
红车 15 蓝车 25
红鸭 16 蓝鸭 26
红兵 17 蓝兵 27
(空) 0

这样子表示的优点如下:

  • 将十位数取出来就可以知道这个棋子是哪一方的。
  • 将个位数取出来就可以知道这个棋子是什么类型的(与哪一方的无关)。

然后需要写一个数字转英文棋子名的函数:

string get_name(int chs){
// 获得棋子英文名
string player,type;
if(chs/10==1) player="red";
if(chs/10==2) player="blue";
if(chs%10 == 1) type="captain";
if(chs%10 == 2) type="guard";
if(chs%10 == 3) type="elephant";
if(chs%10 == 4) type="horse";
if(chs%10 == 5) type="car";
if(chs%10 == 6) type="duck";
if(chs%10 == 7) type="soldier";
return player + " " + type;
}

棋盘简单的使用一个二维数组。不过要注意红方在上,黑方在下。

初始局面代码:

int board[10][9] = {
{15,14,13,12,11,12,13,14,15},
{00,00,00,00,00,00,00,00,00},
{16,00,00,00,00,00,00,00,16},
{17,00,17,00,17,00,17,00,17},
{00,00,00,00,00,00,00,00,00},
{00,00,00,00,00,00,00,00,00},
{27,00,27,00,27,00,27,00,27},
{26,00,00,00,00,00,00,00,26},
{00,00,00,00,00,00,00,00,00},
{25,24,23,22,21,22,23,24,25}
};// 棋盘

判断棋步(一)

现在我们来实现判断试图将一个坐标的棋子移到另一个坐标的行为是否合法。

首先我们先判断一个棋子是否可以落到棋盘上的某一个位置。这一点在鸭棋中可能用处不大,但在在中国象棋中尤为重要(象有不能过河、将士有不能出九宫的限制)。大致需要判断:

  • 是否出界
  • 落子的位置是否有己方的棋子。

代码:

int is_landing_legal(int chs,int dx,int dy){
// 棋子 chs 是否可以落到 (dx,dy) 返回 0:不可以 1:可以 2:可以且吃了子
if(dx<0||dx>=10||dy<0||dy>=9) return 0;// 出界
else if(board[dx][dy]==0) return 1;// 没有棋子自然可以放上去
else if(board[dx][dy]/10 != chs/10) return 2;// 有棋子但不同方可以吃
else return 0;// 有己方棋子不能走
}

然后就是主判断了。无论怎么样,我们都可以写出一个整体框架:

int is_moving_legal(int chs,int sx,int sy,int dx,int dy){
// 棋子 chs 从 (sx,sy) 走到 (dx,dy) 是否合法 0:不可以 1:可以 2:可以且吃了子
if(sx==dx && sy==dy) return 0;
if(chs==0) return 0;
int landing = is_landing_legal(chs,dx,dy);
if(!landing) return 0;
这里写生成棋子走法,看是不是可以找到走法
return 0;
}

判断棋步(二)

上一节我们实现了判断棋步是否合法的框架,这一节我们写具体判断逻辑。

  • captain):可达的位置共 \(4\) 个,包括 \(\left(x\pm 1,y\right)\) 及 \(\left(x,y\pm 1\right)\)。

由于王的移动比较简单,我们可以写一个偏移值数组 captain_delta

typedef vector<pair<int,int> > moves;

moves captain_delta = {{1,0},{0,1},{-1,0},{0,-1}};// 王的偏移值

然后遍历所有可能的偏移值,判断是否走的是这一步即可:

if(chs%10 == 1){// 王
for(pair<int,int> delta : captain_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}

  • guard):可达的位置共 \(4\) 个,包括 \(\left(x\pm 1,y\pm 1\right)\) 及 \(\left(x\pm 1,y\mp 1\right)\)。

由于士的移动也很简单,我们可以写一个偏移值数组 guard_delta

moves guard_delta = {{1,1},{1,-1},{-1,1},{-1,-1}};// 士的偏移值

然后遍历所有可能的偏移值,判断是否走的是这一步即可:

if(chs%10 == 2){// 士
for(pair<int,int> delta : guard_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}

  • elephant):可达的位置至多 \(4\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:

    • 如果位置 \(\left(x+s_x\times 1 ,y+ s_y\times 1\right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 2\right)\) 为一个可达的位置。

有人象也写了偏移值,不过这样又要写象眼的偏移值,非常麻烦,而且容易错。我们可以直接用题目给我们的定义,枚举 \(s_x,s_y\) 判断即可:

if(chs%10 == 3){// 象
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx][sy+_sy]!=0) continue;
if((sx+(_sx<<1))==dx && (sy+(_sy<<1))==dy){
return landing;
}
}
}
return 0;
}

  • horse):可达的位置至多 \(8\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:

    • 如果位置 \(\left(x+s_x\times 1 ,y\right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 1\right)\) 为一个可达的位置。
    • 如果位置 \(\left(x ,y+ s_y \times 1 \right)\) 上无任意一方的棋子停留,则 \(\left( x+s_x \times 1,y+s_y \times 2\right)\) 为一个可达的位置。

和象一样,我们也可以直接枚举 \(s_x,s_y\)。然后判断即可。记得判断蹩马腿的情况。

if(chs%10 == 4){// 马
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx][sy]==0){
if((sx+(_sx<<1))==dx && (sy+_sy)==dy){
return landing;
}
}
if(board[sx][sy+_sy]==0){
if((sx+_sx)==dx && (sy+(_sy<<1))==dy){
return landing;
}
}
}
}
return 0;
}

  • car):可在不跨越其他棋子的前提下,到达同行或同列的所有其他位置。

先判断是否在同一列或同一行,如果同一行,就固定行,看看这之间(记得不包括两边)有没有棋子。同一列同理。

if(chs%10 == 5){// 车
bool flag=0;
if(sx==dx){
for(int i=min(sy,dy)+1;i<max(sy,dy);i++){
if(board[sx][i]!=0){
flag=1;
break;
}
}
if(!flag) return landing;
else return 0;
}
else if(sy==dy){
for(int i=min(sx,dx)+1;i<max(sx,dx);i++){
if(board[i][sy]!=0) {
flag=1;
break;
}
}
if(!flag) return landing;
else return 0;
}
else return 0;
}

  • duck):可达的位置至多 \(8\) 个,对于任意 \(s_x,s_y\in \left\{ 1,-1\right\}\),分别有:

    • 如果位置 \(\left(x+s_x\times 2 ,y+s_y \times 1\right),\left(x+s_x\times 1 ,y\right)\) 上均无任意一方的棋子停留,则 \(\left( x+s_x \times 3,y+s_y \times 2\right)\) 为一个可达的位置。
    • 如果位置 \(\left(x+s_x \times 1 ,y+ s_y \times 2 \right),\left(x ,y+ s_y \times 1 \right)\) 上均无任意一方的棋子停留,则 \(\left( x+s_x \times 2,y+s_y \times 3\right)\) 为一个可达的位置。

使用象和马的方法即可,也是枚举 \(s_x,s_y\),然后记得判断鸭爪?

if(chs%10 == 6){// 鸭
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx*2][sy+_sy*1]==0 && board[sx+_sx][sy] == 0){
if((sx+(_sx*3))==dx && (sy+_sy*2)==dy){
return landing;
}
}
if(board[sx][sy+_sy]==0 && board[sx+_sx*1][sy+_sy*2] == 0){
if((sx+_sx*2)==dx && (sy+(_sy*3))==dy){
return landing;
}
}
}
}
return 0;
}

  • soldier):可达的位置共 \(8\) 个,包括 \(\left(x\pm 1,y\right)\) 及 \(\left(x,y\pm 1\right)\) 及 \(\left(x\pm 1,y\pm 1\right)\) 及 \(\left(x\pm 1,y\mp 1\right)\)。

兵的走法比较简单,使用偏移值法。

moves soldier_delta = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}};// 兵的偏移值

if(chs%10 == 7){// 兵
for(pair<int,int> delta : soldier_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}

判断将军

其实有更高效的方法,就是把王当成攻击子力,看能不能攻击到其他子。但这样判断 象眼/马腿/鸭爪 比较麻烦。

我们采用暴力的方法,先找到王的位置,然后暴力枚举所有棋子,看看走到王的位置是否合法。

bool is_checking(int player){
// 是否将军 player=1 红方被将 player=2 蓝方被将
int cx=-1,cy=-1;
for(int i=0;i<10&&(cx==-1);i++){
for(int j=0;j<9&&(cy==-1);j++){
if(board[i][j]==(player*10+1)){
cx=i;cy=j;
}
}
}
if(cx==-1&&cy==-1) return false;
for(int i=0;i<10;i++){
for(int j=0;j<9;j++){
if(i==cx&&j==cy) continue;
if(board[i][j]==0) continue;
if(is_moving_legal(board[i][j],i,j,cx,cy)){
return true;
}
}
}
return false;
}

判断结束

如果没有王,那么就结束了。可以暴力扫每一个位置看看是不是王,如果都不是就结束了。

bool is_finished(int player){
// 是否结束 player=1 蓝方胜利 player=2 红方胜利
int cx=-1,cy=-1;
for(int i=0;i<10&&(cx==-1);i++){
for(int j=0;j<9&&(cy==-1);j++){
if(board[i][j]==(player*10+1)){
cx=i;cy=j;
}
}
}
if(cx==-1&&cy==-1) return true;
else return false;
}

主程序

然后就是主程序了!其实主程序十分简单,只是要注意:

  • 结束后不能走棋。
  • 不合法的棋要忽略。
  • 记得一方下完后一定是另一方下,否则不合法。

代码:

bool finished = 0;
int nowmove = 1; signed main(){
int q;
cin>>q;
while(q--){
int sx,sy,dx,dy;
cin>>sx>>sy>>dx>>dy;
int moving = is_moving_legal(board[sx][sy],sx,sy,dx,dy);
if(!moving||finished||board[sx][sy]/10 != nowmove){cout<<"Invalid command\n";continue;}
string moved=get_name(board[sx][sy]),ate="NA",checking="no",finishing="no";
if(moving == 2) ate=get_name(board[dx][dy]);
board[dx][dy]=board[sx][sy];board[sx][sy]=0;
if(is_checking(1) || is_checking(2)) checking="yes";
if(is_finished(1) || is_finished(2)){finishing="yes";finished=1;}
cout<<moved<<';'<<ate<<';'<<checking<<';'<<finishing<<'\n';
if(nowmove == 1) nowmove = 2;
else nowmove = 1;
}
return 0;
}

代码

显示代码
#include <bits/stdc++.h>
#define int long long
using namespace std; // 十位 0:空 1:红 2:蓝
// 个位 王:1 士:2 象:3 马:4 车:5 鸭:6 兵:7 int board[10][9] = {
{15,14,13,12,11,12,13,14,15},
{00,00,00,00,00,00,00,00,00},
{16,00,00,00,00,00,00,00,16},
{17,00,17,00,17,00,17,00,17},
{00,00,00,00,00,00,00,00,00},
{00,00,00,00,00,00,00,00,00},
{27,00,27,00,27,00,27,00,27},
{26,00,00,00,00,00,00,00,26},
{00,00,00,00,00,00,00,00,00},
{25,24,23,22,21,22,23,24,25}
};// 棋盘 typedef vector<pair<int,int> > moves; moves captain_delta = {{1,0},{0,1},{-1,0},{0,-1}};// 王的偏移值
moves guard_delta = {{1,1},{1,-1},{-1,1},{-1,-1}};// 士的偏移值
moves soldier_delta = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}};// 兵的偏移值 int is_landing_legal(int chs,int dx,int dy){
// 棋子是否可以落到 (dx,dy) 返回 0:不可以 1:可以 2:可以且吃了子
if(dx<0||dx>=10||dy<0||dy>=9) return 0;// 出界
else if(board[dx][dy]==0) return 1;// 没有棋子自然可以放上去
else if(board[dx][dy]/10 != chs/10) return 2;// 有棋子但不同方可以吃
else return 0;// 有己方棋子不能走
} int is_moving_legal(int chs,int sx,int sy,int dx,int dy){
// 棋子 chs 从 (sx,sy) 走到 (dx,dy) 是否合法 0:不可以 1:可以 2:可以且吃了子
if(sx==dx && sy==dy) return 0;
if(chs==0) return 0;
int landing = is_landing_legal(chs,dx,dy);
if(!landing) return 0;
if(chs%10 == 1){// 王
for(pair<int,int> delta : captain_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}
if(chs%10 == 2){// 士
for(pair<int,int> delta : guard_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}
if(chs%10 == 3){// 象
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx][sy+_sy]!=0) continue;
if((sx+(_sx<<1))==dx && (sy+(_sy<<1))==dy){
return landing;
}
}
}
return 0;
}
if(chs%10 == 4){// 马
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx][sy]==0){
if((sx+(_sx<<1))==dx && (sy+_sy)==dy){
return landing;
}
}
if(board[sx][sy+_sy]==0){
if((sx+_sx)==dx && (sy+(_sy<<1))==dy){
return landing;
}
}
}
}
return 0;
}
if(chs%10 == 5){// 车
bool flag=0;
if(sx==dx){
for(int i=min(sy,dy)+1;i<max(sy,dy);i++){
if(board[sx][i]!=0){
flag=1;
break;
}
}
if(!flag) return landing;
else return 0;
}
else if(sy==dy){
for(int i=min(sx,dx)+1;i<max(sx,dx);i++){
if(board[i][sy]!=0) {
flag=1;
break;
}
}
if(!flag) return landing;
else return 0;
}
else return 0;
}
if(chs%10 == 6){// 鸭
for(int _sx : {1,-1}){
for(int _sy : {1,-1}){
if(board[sx+_sx*2][sy+_sy*1]==0 && board[sx+_sx][sy] == 0){
if((sx+(_sx*3))==dx && (sy+_sy*2)==dy){
return landing;
}
}
if(board[sx][sy+_sy]==0 && board[sx+_sx*1][sy+_sy*2] == 0){
if((sx+_sx*2)==dx && (sy+(_sy*3))==dy){
return landing;
}
}
}
}
return 0;
}
if(chs%10 == 7){// 兵
for(pair<int,int> delta : soldier_delta){
if(sx+delta.first==dx && sy+delta.second==dy){
return landing;
}
}
return 0;
}
return 0;
} bool is_checking(int player){
// 是否将军 player=1 红方被将 player=2 蓝方被将
int cx=-1,cy=-1;
for(int i=0;i<10&&(cx==-1);i++){
for(int j=0;j<9&&(cy==-1);j++){
if(board[i][j]==(player*10+1)){
cx=i;cy=j;
}
}
}
if(cx==-1&&cy==-1) return false;
for(int i=0;i<10;i++){
for(int j=0;j<9;j++){
if(i==cx&&j==cy) continue;
if(board[i][j]==0) continue;
if(is_moving_legal(board[i][j],i,j,cx,cy)){
return true;
}
}
}
return false;
} bool is_finished(int player){
// 是否结束 player=1 蓝方胜利 player=2 红方胜利
int cx=-1,cy=-1;
for(int i=0;i<10&&(cx==-1);i++){
for(int j=0;j<9&&(cy==-1);j++){
if(board[i][j]==(player*10+1)){
cx=i;cy=j;
}
}
}
if(cx==-1&&cy==-1) return true;
else return false;
} string get_name(int chs){
// 获得棋子英文名
string player,type;
if(chs/10==1) player="red";
if(chs/10==2) player="blue";
if(chs%10 == 1) type="captain";
if(chs%10 == 2) type="guard";
if(chs%10 == 3) type="elephant";
if(chs%10 == 4) type="horse";
if(chs%10 == 5) type="car";
if(chs%10 == 6) type="duck";
if(chs%10 == 7) type="soldier";
return player + " " + type;
} bool finished = 0;
int nowmove = 1; signed main(){
int q;
cin>>q;
while(q--){
int sx,sy,dx,dy;
cin>>sx>>sy>>dx>>dy;
int moving = is_moving_legal(board[sx][sy],sx,sy,dx,dy);
if(!moving||finished||board[sx][sy]/10 != nowmove){cout<<"Invalid command\n";continue;}
string moved=get_name(board[sx][sy]),ate="NA",checking="no",finishing="no";
if(moving == 2) ate=get_name(board[dx][dy]);
board[dx][dy]=board[sx][sy];board[sx][sy]=0;
if(is_checking(1) || is_checking(2)) checking="yes";
if(is_finished(1) || is_finished(2)){finishing="yes";finished=1;}
cout<<moved<<';'<<ate<<';'<<checking<<';'<<finishing<<'\n';
if(nowmove == 1) nowmove = 2;
else nowmove = 1;
}
return 0;
}

P5380 [THUPC2019]鸭棋的更多相关文章

  1. 题解 洛谷P5380 【[THUPC2019]鸭棋】

    就是一道大模拟. 首先,来解释一下复杂的题意: 给你一些棋子,每个棋都有不同的走法,开局是回归原位. 接下来,题目会给你一个虚拟的走子操作(注意不一定真实),你所需要判断当前操作是否正确.若不正确,输 ...

  2. thupc & cts & apio & thusc 游记 (北京17日游记)

    thupc & cts & apio & thusc 游记 (北京17日游记) Day 0 和隔壁校两人py了一下,六个人组了两队,(左哼哼)与(右哼哼),我和Camoufla ...

  3. 日记 + sb错误

    置顶消息cpdd 1.29 完了,文化课没了 我是废物 1.28 更新了自己的副标题 前副标题:Future never has to do with past time,but present ti ...

  4. THUPC2019/CTS2019/APIO2019/PKUSC2019游记

    THUPC2019/CTS2019/APIO2019/PKUSC2019游记 5.10 中铺,火车好晃啊 5.11 打了THUPC2019的练习赛,华容道好评(四个小兵,杠鸭!) 5.12 打了THU ...

  5. [CareerCup] 17.2 Tic Tac Toe 井字棋游戏

    17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...

  6. BZOJ 1076 & 撞鸭递推

    题意: 还是看原题题面好... 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随 机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决 ...

  7. 开源战棋 SLG 游戏框架设计思考(一)简介和游戏引擎

    战棋 SLG 游戏 SLG(Simulation Game)游戏是模拟游戏的简称.战棋类的SLG有两种:一种是 War Game 中的兵棋推演分支,常见的游戏有战争艺术3(TOAW3 — The Op ...

  8. 隔壁信概大作业xjb写——同化棋ATAXX

    话说泥萌北大信科啊,助教是有多懒...去年黑白棋今年同化棋,顺带打ai都不用自己写标程... 好吧..我知道泥萌重点在各种sb的辅助操作上..什么悲剧的可以随时暂停载入...有毒吧 [据说泥萌上课没讲 ...

  9. 原创跑酷小游戏《Cube Duck Run》 - - 方块鸭快跑

    自从unity5出来才开始关注unity,业余时间尝试做了个小游戏: <方块鸭快跑> (Cube Duck Run) 像素风,3d视角,色彩明快,有无尽和关卡两种模式. 应用连接: goo ...

随机推荐

  1. 深入浅出redis缓存应用

    0.1.索引 https://blog.waterflow.link/articles/1663169309611 1.只读缓存 只读缓存的流程是这样的: 当查询请求过来时,先从redis中查询数据, ...

  2. python基础之常用数据类型和字符串

    一.数据类型 在python3中有六大标准数据类型:Numbers(数字).String(字符串).List(列表).Tuple(元组).Sets(集合).Dictionaries(字典). 其中: ...

  3. Linux进程间通信(一)

    进程间通信 概念:进程是一个独立的资源分配单位,不同进程之间有关联,不能在一个进程中直接访问另一个进程的资源. 进程和进程之间的资源是相互独立的,一个进程不能直接访问另外一个进程的资源,但是进程和进程 ...

  4. 【JavaWeb】学习笔记——Tomcat集成

    简介 Tomcat是基于Java的一个开放源代码.运行servlet和JSP Web应用的Web应用软件容器,又称servlet容器 安装 官方网站:https://tomcat.apache.org ...

  5. Oracle数据泵导入dmp文件,报UDI-00013、UDI-00019错误原因

    这个问题挺简单,想了想,还是记录下吧. [root@ufdb165 bin]# ./impdp cwy_init0914/cwy_123456789@ufgovdb1 directory=DATA_P ...

  6. 常用Python库整理

    记录工作和学习中遇到和使用过的Python库. Target 四个Level 整理 Collect 学习 Learn 练习 Practice 掌握 Master 1. Python原生和功能增强 1. ...

  7. ES6高级编程(一)

    一.JavaScript概要 1.1.JavaScript组成 JavaScript主要由三部分构成,分别是ECMAScript.DOM与BOM ECMAScript定义了该语言的语法.类型.语句.关 ...

  8. mindxdl--common--utils.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common define co ...

  9. Java-(array)数组的基本概念 及 Java内存划分

    (array)数组的基本概念 数组的概念:是一种容器,可同时存放多个数据值 数组的特点: 1.数组是一种引用数据类型 2.数组当中的多个数据,类型必须统一 3.数组的长度在程序运行期间不可改变 数组的 ...

  10. C温故补缺(五):main函数的参数

    main()的参数 main()函数的参数,用于在外部执行时传入参数,类似windows的bat脚本或linux的sh脚本.在bat脚本中传入参数,用%接收.sh脚本的参数用$接收. c语言编译成可执 ...