社区讨论
代码求调
P5380[THUPC 2019] 鸭棋参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @misuyeye
- 此快照首次捕获于
- 2025/12/05 20:45 2 个月前
- 此快照最后确认于
- 2025/12/06 09:08 2 个月前
CPP
#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
#define Debug cout<<endl<<endl<<endl
const int N=15;
int Q;
bool is_red=true;//现在是谁的回合(true为红方,false为蓝方)
bool is_end=false;//游戏是否结束
int xs,ys,xt,yt;
enum class piece
{
none=0,//空位
red_captain=1,//红方王
red_guard=2,//红方士
red_elephant=3,//红方象
red_horse=4,//红方马
red_car=5,//红方车
red_duck=6,//红方鸭
red_soldier=7,//红方卒
blue_captain=8,//蓝方王
blue_guard=9,//蓝方士
blue_elephant=10,//蓝方象
blue_horse=11,//蓝方马
blue_car=12,//蓝方车
blue_duck=13,//蓝方鸭
blue_soldier=14,//蓝方卒
};
piece mp[N][N]={
{piece::blue_car,piece::blue_horse,piece::blue_elephant,piece::blue_guard,piece::blue_captain,piece::blue_guard,piece::blue_elephant,piece::blue_horse,piece::blue_car},
{piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none},
{piece::blue_duck,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::blue_duck},
{piece::blue_soldier,piece::none,piece::blue_soldier,piece::none,piece::blue_soldier,piece::none,piece::blue_soldier,piece::none,piece::blue_soldier},
{piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none},
{piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none},
{piece::red_soldier,piece::none,piece::red_soldier,piece::none,piece::red_soldier,piece::none,piece::red_soldier,piece::none,piece::red_soldier},
{piece::red_duck,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::red_duck},
{piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none,piece::none},
{piece::red_car,piece::red_horse,piece::red_elephant,piece::red_guard,piece::red_captain,piece::red_guard,piece::red_elephant,piece::red_horse,piece::red_car}
};//初始化棋盘
//将输入的坐标转化为和数组下标对应的下标
void change(int &x,int &y)
{
x=9-x;
}
//获取棋子能够到达的位置
vector<pair<int,int> > get_possible_pos(piece type,int x,int y)
{
vector <pair<int,int> > pos;//存储能够到达的位置
//红方棋子
if(type==piece::red_captain)
{
if(mp[x][y+1]==piece::none || (mp[x][y+1]>=piece::blue_captain && mp[x][y+1]<=piece::blue_soldier))//为空或是蓝方棋子(吃子)
pos.push_back({x,y+1});
if(y-1>=0 && (mp[x][y-1]==piece::none || (mp[x][y-1]>=piece::blue_captain && mp[x][y-1]<=piece::blue_soldier)))//添加边界判断,避免访问下标-1的位置得到不确定的值
pos.push_back({x,y-1});
if(mp[x+1][y]==piece::none || (mp[x+1][y]>=piece::blue_captain && mp[x+1][y]<=piece::blue_soldier))
pos.push_back({x+1,y});
if(x-1>=0 && (mp[x-1][y]==piece::none || (mp[x-1][y]>=piece::blue_captain && mp[x-1][y]<=piece::blue_soldier)))
pos.push_back({x-1,y});
}
else if(type==piece::red_guard)
{
if(mp[x+1][y+1]==piece::none || (mp[x+1][y+1]>=piece::blue_captain && mp[x+1][y+1]<=piece::blue_soldier))
pos.push_back({x+1,y+1});
if((x-1>=0 && y-1>=0) && (mp[x-1][y-1]==piece::none || (mp[x-1][y-1]>=piece::blue_captain && mp[x-1][y-1]<=piece::blue_soldier)))
pos.push_back({x-1,y-1});
if(y-1>=0 && (mp[x+1][y-1]==piece::none || (mp[x+1][y-1]>=piece::blue_captain && mp[x+1][y-1]<=piece::blue_soldier)))
pos.push_back({x+1,y-1});
if(x-1>=0 && (mp[x-1][y+1]==piece::none || (mp[x-1][y+1]>=piece::blue_captain && mp[x-1][y+1]<=piece::blue_soldier)))
pos.push_back({x-1,y+1});
}
else if(type==piece::red_elephant)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)//sx和sy不能取0
continue;
if((x+sx>=0 && y+sy>=0) && (mp[x+sx][y+sy]==piece::none))//没有任意一方棋子停留
pos.push_back({x+2*sx,y+2*sy});
}
}
else if(type==piece::red_horse)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)
continue;
if(x+sx>=0 && mp[x+sx][y]==piece::none)//无任何一方棋子停留
pos.push_back({x+2*sx,y+sy});
if(y+sy>=0 && mp[x][y+sy]==piece::none)
pos.push_back({x+sx,y+2*sy});
}
}
else if(type==piece::red_car)
{
for(int i=x-1;i>=0;i--)//向上扩展(不包含当前棋子)
{
if(mp[i][y]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({i,y});
}
for(int i=x+1;i<10;i++)//向下扩展
{
if(mp[i][y]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({i,y});
}
for(int i=y-1;i>=0;i--)//向左扩展
{
if(mp[x][i]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({x,i});
}
for(int i=y+1;i<9;i++)//向右扩展
{
if(mp[x][i]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({x,i});
}
}
else if(type==piece::red_duck)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)
continue;
if((x+2*sx>=0 && y+sy>=0 && x+sx>=0) && (mp[x+2*sx][y+sy]==piece::none && mp[x+sx][y]==piece::none))
pos.push_back({x+3*sx,y+2*sy});
if((x+sx>=0 && y+2*sy>=0 && y+sy>=0) && (mp[x+sx][y+2*sy]==piece::none && mp[x][y+sy]==piece::none))
pos.push_back({x+2*sx,y+3*sy});
}
}
else if(type==piece::red_soldier)
{
if(mp[x+1][y]==piece::none || (mp[x+1][y]>=piece::blue_captain && mp[x+1][y]<=piece::blue_soldier))
pos.push_back({x+1,y});
if(x-1>=0 && (mp[x-1][y]==piece::none || (mp[x-1][y]>=piece::blue_captain && mp[x-1][y]<=piece::blue_soldier)))
pos.push_back({x-1,y});
if(mp[x][y+1]==piece::none || (mp[x][y+1]>=piece::blue_captain && mp[x][y+1]<=piece::blue_soldier))
pos.push_back({x,y+1});
if(y-1>=0 && (mp[x][y-1]==piece::none || (mp[x][y-1]>=piece::blue_captain && mp[x][y-1]<=piece::blue_soldier)))
pos.push_back({x,y-1});
if(mp[x+1][y+1]==piece::none || (mp[x+1][y+1]>=piece::blue_captain && mp[x+1][y+1]<=piece::blue_soldier))
pos.push_back({x+1,y+1});
if((x-1>=0 && y-1>=0) && (mp[x-1][y-1]==piece::none || (mp[x-1][y-1]>=piece::blue_captain && mp[x-1][y-1]<=piece::blue_soldier)))
pos.push_back({x-1,y-1});
if(y-1>=0 && (mp[x+1][y-1]==piece::none || (mp[x+1][y-1]>=piece::blue_captain && mp[x+1][y-1]<=piece::blue_soldier)))
pos.push_back({x+1,y-1});
if(x-1>=0 && (mp[x-1][y+1]==piece::none || (mp[x-1][y+1]>=piece::blue_captain && mp[x-1][y+1]<=piece::blue_soldier)))
pos.push_back({x-1,y+1});
}
//蓝方棋子
else if(type==piece::blue_captain)
{
if(mp[x][y+1]==piece::none || (mp[x][y+1]>=piece::red_captain && mp[x][y+1]<=piece::red_soldier))//为空或是红方棋子(吃子)
pos.push_back({x,y+1});
if(y-1>=0 && (mp[x][y-1]==piece::none || (mp[x][y-1]>=piece::red_captain && mp[x][y-1]<=piece::red_soldier)))
pos.push_back({x,y-1});
if(mp[x+1][y]==piece::none || (mp[x+1][y]>=piece::red_captain && mp[x+1][y]<=piece::red_soldier))
pos.push_back({x+1,y});
if(x-1>=0 && (mp[x-1][y]==piece::none || (mp[x-1][y]>=piece::red_captain && mp[x-1][y]<=piece::red_soldier)))
pos.push_back({x-1,y});
}
else if(type==piece::blue_guard)
{
if(mp[x+1][y+1]==piece::none || (mp[x+1][y+1]>=piece::red_captain && mp[x+1][y+1]<=piece::red_soldier))
pos.push_back({x+1,y+1});
if((x-1>=0 && y-1>=0) && (mp[x-1][y-1]==piece::none || (mp[x-1][y-1]>=piece::red_captain && mp[x-1][y-1]<=piece::red_soldier)))
pos.push_back({x-1,y-1});
if(y-1>=0 && (mp[x+1][y-1]==piece::none || (mp[x+1][y-1]>=piece::red_captain && mp[x+1][y-1]<=piece::red_soldier)))
pos.push_back({x+1,y-1});
if(x-1>=0 && (mp[x-1][y+1]==piece::none || (mp[x-1][y+1]>=piece::red_captain && mp[x-1][y+1]<=piece::red_soldier)))
pos.push_back({x-1,y+1});
}
else if(type==piece::blue_elephant)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)//sx和sy不能取0
continue;
if((x+sx>=0 && y+sy>=0) && (mp[x+sx][y+sy]==piece::none))//没有任意一方棋子停留
pos.push_back({x+2*sx,y+2*sy});
}
}
else if(type==piece::blue_horse)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)
continue;
if(x+sx>=0 && mp[x+sx][y]==piece::none)//无任何一方棋子停留
pos.push_back({x+2*sx,y+sy});
if(y+sy>=0 && mp[x][y+sy]==piece::none)
pos.push_back({x+sx,y+2*sy});
}
}
else if(type==piece::blue_car)
{
for(int i=x-1;i>=0;i--)//向上扩展
{
if(mp[i][y]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({i,y});
}
for(int i=x+1;i<10;i++)//向下扩展
{
if(mp[i][y]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({i,y});
}
for(int i=y-1;i>=0;i--)//向左扩展
{
if(mp[x][i]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({x,i});
}
for(int i=y+1;i<9;i++)//向右扩展
{
if(mp[x][i]!=piece::none)//遇到其他棋子阻挡
break;
pos.push_back({x,i});
}
}
else if(type==piece::blue_duck)
{
for(int sx=-1;sx<=1;sx++)
for(int sy=-1;sy<=1;sy++)
{
if(sx==0 || sy==0)
continue;
if((x+2*sx>=0 && y+sy>=0 && x+sx>=0) && (mp[x+2*sx][y+sy]==piece::none && mp[x+sx][y]==piece::none))
pos.push_back({x+3*sx,y+2*sy});
if((x+sx>=0 && y+2*sy>=0 && y+sy>=0) && (mp[x+sx][y+2*sy]==piece::none && mp[x][y+sy]==piece::none))
pos.push_back({x+2*sx,y+3*sy});
}
}
else if(type==piece::blue_soldier)
{
if(mp[x+1][y]==piece::none || (mp[x+1][y]>=piece::red_captain && mp[x+1][y]<=piece::red_soldier))
pos.push_back({x+1,y});
if(x-1>=0 && (mp[x-1][y]==piece::none || (mp[x-1][y]>=piece::red_captain && mp[x-1][y]<=piece::red_soldier)))
pos.push_back({x-1,y});
if(mp[x][y+1]==piece::none || (mp[x][y+1]>=piece::red_captain && mp[x][y+1]<=piece::red_soldier))
pos.push_back({x,y+1});
if(y-1>=0 && (mp[x][y-1]==piece::none || (mp[x][y-1]>=piece::red_captain && mp[x][y-1]<=piece::red_soldier)))
pos.push_back({x,y-1});
if(mp[x+1][y+1]==piece::none || (mp[x+1][y+1]>=piece::red_captain && mp[x+1][y+1]<=piece::red_soldier))
pos.push_back({x+1,y+1});
if((x-1>=0 && y-1>=0) && (mp[x-1][y-1]==piece::none || (mp[x-1][y-1]>=piece::red_captain && mp[x-1][y-1]<=piece::red_soldier)))
pos.push_back({x-1,y-1});
if(y-1>=0 && (mp[x+1][y-1]==piece::none || (mp[x+1][y-1]>=piece::red_captain && mp[x+1][y-1]<=piece::red_soldier)))
pos.push_back({x+1,y-1});
if(x-1>=0 && (mp[x-1][y+1]==piece::none || (mp[x-1][y+1]>=piece::red_captain && mp[x-1][y+1]<=piece::red_soldier)))
pos.push_back({x-1,y+1});
}
//剔除越界的位置(手动遍历,不能用for(auto p:pos),这样的话在删除元素后原迭代器可能失效)
for(auto it=pos.begin();it!=pos.end();)
if(it->first<0 || it->first>=10 || it->second<0 || it->second>=9)
it=pos.erase(it);
else
it++;
//剔除目标位置有己方棋子的位置
for(auto it=pos.begin();it!=pos.end();)
{
bool cur_is_red=(mp[x][y]>=piece::red_captain && mp[x][y]<=piece::red_soldier);
bool target_is_red=(mp[it->first][it->second]>=piece::red_captain && mp[it->first][it->second]<=piece::red_soldier);
if(!(cur_is_red^target_is_red))
it=pos.erase(it);
else
it++;
}
return pos;
}
//判断移动是否合法
bool check_move(piece type,int xs,int ys,int xt,int yt)
{
vector <pair<int,int> > pos=get_possible_pos(type,xs,ys);//获取当前棋子从当前位置出发能够到达的位置有哪些
for(auto p:pos)
if(p.first==xt && p.second==yt)
return true;//能够到达目标位置
return false;//不能到达目标位置
}
//判断本次行动是否合法
bool judge(int xs,int ys,int xt,int yt)
{
//判断游戏是否结束
if(is_end)//游戏结束后的操作都不合法
return false;
//判断当前位置有没有己方棋子停留
piece type=mp[xs][ys];//将要被移动的棋子是什么
if(type==piece::none)//没有棋子必然不合法
return false;
if((type>=piece::red_captain && type<=piece::red_soldier)^is_red)//红方只能移动红方的棋子,蓝方只能移动蓝方的棋子
return false;
//判断棋子移动是否合法
if(!check_move(type,xs,ys,xt,yt))//移动不合法
return false;
return true;
}
//移动棋子
void move(int xs,int ys,int xt,int yt)
{
mp[xt][yt]=mp[xs][ys];//将棋子移动到目标位置
mp[xs][ys]=piece::none;//将原位置清空
}
//输出棋子类型
void print_piece(piece type)
{
switch(type)
{
case piece::red_captain:
cout<<"red captain";
break;
case piece::red_guard:
cout<<"red guard";
break;
case piece::red_elephant:
cout<<"red elephant";
break;
case piece::red_horse:
cout<<"red horse";
break;
case piece::red_car:
cout<<"red car";
break;
case piece::red_duck:
cout<<"red duck";
break;
case piece::red_soldier:
cout<<"red soldier";
break;
case piece::blue_captain:
cout<<"blue captain";
break;
case piece::blue_guard:
cout<<"blue guard";
break;
case piece::blue_elephant:
cout<<"blue elephant";
break;
case piece::blue_horse:
cout<<"blue horse";
break;
case piece::blue_car:
cout<<"blue car";
break;
case piece::blue_duck:
cout<<"blue duck";
break;
case piece::blue_soldier:
cout<<"blue soldier";
break;
default:
break;
}
}
//判断游戏是否结束
bool check_end()
{
int cnt;//统计棋盘上王的个数
for(int i=0;i<10;i++)
for(int j=0;j<9;j++)
if(mp[i][j]==piece::red_captain || mp[i][j]==piece::blue_captain)
cnt++;
if(cnt==2)
return false;
is_end=true;//修改结束标记
return true;
}
//判断是否被将军
bool check_threat()
{
for(int i=0;i<10;i++)
{
for(int j=0;j<9;j++)
{
if(mp[i][j]==piece::none || mp[i][j]==piece::red_captain || mp[i][j]==piece::blue_captain)
continue;
vector <pair<int,int> > pos=get_possible_pos(mp[i][j],i,j);
for(auto p:pos)
{
if(mp[p.first][p.second]!=piece::red_captain || mp[p.first][p.second]!=piece::blue_captain)
continue;
return true;//将军了对手(因为在get_possible_pos函数中已经判断了不能下在己方棋子上,所以只要能够到达的王必然是对方的王)
}
}
}
return false;
}
//回答问题
void answer(int xs,int ys,int xt,int yt)
{
piece type=mp[xs][ys];//被移动的棋子是什么
//输出这次被移动的棋子
print_piece(type);
cout<<";";
//判断是否吃子
if(mp[xt][yt]!=piece::none && (mp[xs][ys]>=piece::red_captain && mp[xs][ys]<=piece::red_soldier)^(mp[xt][yt]>=piece::red_captain && mp[xt][yt]<=piece::red_soldier))//有棋子且棋子不同才能吃子
print_piece(mp[xt][yt]);
else
cout<<"NA";
cout<<";";
move(xs,ys,xt,yt);
check_end();//先更新游戏状态再判断将军
//判断是否被将军
if(check_threat())
cout<<"yes";
else
cout<<"no";
cout<<";";
//判断游戏是否结束
if(is_end)
cout<<"yes";
else
cout<<"no";
cout<<endl;
}
//主函数
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// for(int i=0;i<10;i++)
// {
// for(int j=0;j<9;j++)
// {
// if(mp[i][j]==piece::none)
// continue;
// cout<<"("<<i<<","<<j<<")"<<" ";
// print(mp[i][j]);
// cout<<endl;
// vector <pair<int,int> > pos=get_possible_pos(mp[i][j],i,j);
// for(auto p:pos)
// cout<<"("<<p.first<<","<<p.second<<")"<<endl;
// }
// cout<<endl<<endl<<endl;
// }
cin>>Q;
while(Q--)
{
cin>>xs>>ys>>xt>>yt;
change(xs,ys);
change(xt,yt);
//-----------------------------------------------------------------
// printf("(%d,%d) (%d,%d)\n",xs,ys,xt,yt);
// vector <pair<int,int> > pos=get_possible_pos(mp[xs][ys],xs,ys);
// for(auto p:pos)
// printf("(%d,%d)\n",p.first,p.second);
//-----------------------------------------------------------------
if(!judge(xs,ys,xt,yt))//操作不合法,跳过
{
cout<<"Invalid command"<<endl;
//-----
// Debug;
//-----
continue;
}
answer(xs,ys,xt,yt);//回答问题
move(xs,ys,xt,yt);//移动棋子
is_red=!is_red;//切换回合
//-----
// Debug;
//-----
}
return 0;
}
// //输出带颜色的棋盘
// void print(piece p)
// {
// switch(p)
// {
// case piece::none:
// cout << "\033[0m·";
// break;
// case piece::red_captain:
// cout << "\033[31m帥";
// break;
// case piece::red_guard:
// cout << "\033[31m仕";
// break;
// case piece::red_elephant:
// cout << "\033[31m相";
// break;
// case piece::red_horse:
// cout << "\033[31m馬";
// break;
// case piece::red_car:
// cout << "\033[31m車";
// break;
// case piece::red_duck:
// cout << "\033[31m鸭";
// break;
// case piece::red_soldier:
// cout << "\033[31m兵";
// break;
// case piece::blue_captain:
// cout << "\033[34m將";
// break;
// case piece::blue_guard:
// cout << "\033[34m士";
// break;
// case piece::blue_elephant:
// cout << "\033[34m象";
// break;
// case piece::blue_horse:
// cout << "\033[34m馬";
// break;
// case piece::blue_car:
// cout << "\033[34m車";
// break;
// case piece::blue_duck:
// cout << "\033[34m鸭";
// break;
// case piece::blue_soldier:
// cout << "\033[34m卒";
// break;
// }
// // 恢复默认颜色
// cout << "\033[0m";
// }
// void write()//打印棋盘
// {
// //控制使控制台输出字符为UTF-8编码
// #ifdef _WIN32
// system("chcp 65001");
// #endif
// for(int i=0;i<10;i++)
// {
// for(int j=0;j<9;j++)
// {
// print(mp[i][j]);
// cout<<" ";
// }
// cout<<endl;
// }
// }
代码如上。初步调试(输入数据为样例)发现在本应当输出
blue captain;NA;no;no这一行的时候,get_possible_pos函数似乎没有获取到蓝方王能够到达的位置(调试的时候没有输出),但并不知道原因是什么。回复
共 1 条回复,欢迎继续交流。
正在加载回复...