[THUPC 2019] 鸭棋
[THUPC 2019] 鸭棋
锻炼代码能力!
当然如果我写错了的话,请在评论区指出谢谢喵!
初始化棋盘,注意由于 C++ 定义数组和题目中的棋盘不一样,需要上下翻转:
/*
name rule:10x+y
x=1:red x=2:blue
y=1:captain y=2:guard y=3:elephant y=4:horse y=5:car y=6:duck y=7:soldier
example:23=blue elephant
*/
const int n=10,m=9;
int chess_board[n][m]={
{15,14,13,12,11,12,13,14,15},
{0,0,0,0,0,0,0,0,0},
{16,0,0,0,0,0,0,0,16},
{17,0,17,0,17,0,17,0,17},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{27,0,27,0,27,0,27,0,27},
{26,0,0,0,0,0,0,0,26},
{0,0,0,0,0,0,0,0,0},
{25,24,23,22,21,22,23,24,25}
};
接下来为了输出,我们需要实现数字到名称的转换:
string belong_name[3]={"NA","red","blue"};
string piece_name[8]={"NA","captain","guard","elephant","horse","car","duck","soldier"};
string num_to_name(int num){
if(num==0) return "NA";
int belong_num=num/10,piece_num=num%10;
return belong_name[belong_num]+" "+piece_name[piece_num];
}
接下来你就可以输出棋盘了,这一步是为了以后的调试:
void debug_print_num(){
printf("Chess board:\n\n");
for(int i=2*n;i>=0;i--){
if(i%2==0){
printf(" ");
for(int j=0;j<=3*m;j++){
if(j%3==0){
printf("+");
}
else{
printf("-");
}
}
}
else{
printf("%2d ",i/2);
for(int j=0;j<=2*m;j++){
if(j%2==0){
printf("|");
}
else{
printf("%2d",chess_board[i/2][j/2]);
}
}
}
printf("\n");
}
printf(" ");
for(int j=0;j<=2*m;j++){
if(j%2==0){
printf(" ");
}
else{
printf("%2d",j/2);
}
}
printf("\n\n");
}
首先实现 main 函数,也就是套一层壳:
int main(){
int q;
scanf("%d",&q);
while(q--){
int xs,ys,xt,yt;
scanf("%d %d %d %d",&xs,&ys,&xt,&yt);
work_move(xs,ys,xt,yt);
}
return 0;
}
接下来开始实现 work_move 函数,我们首先需要判断移动是否合法:
bool GAME_END=false;
bool check_move(int xs,int ys,int xt,int yt){
if(GAME_END){
return false;
}
if(!check_self(xs,ys) || check_self(xt,yt)){
return false;
}
if(!able_move(xs,ys,xt,yt)){
return false;
}
return true;
}
实现 check_self 函数,即判断当前位置是否是己方棋子:
int pre_player=1;
bool check_self(int x,int y){
int belong_num=chess_board[x][y]/10;
return belong_num==pre_player;
}
实现 able_move 函数,这里我们拆成 \(7\) 个函数。
bool able_move(int xs,int ys,int xt,int yt){
int piece_num=chess_board[xs][ys]%10;
if(piece_num==1){
return check_move_captain(xs,ys,xt,yt);
}
if(piece_num==2){
return check_move_guard(xs,ys,xt,yt);
}
if(piece_num==3){
return check_move_elephant(xs,ys,xt,yt);
}
if(piece_num==4){
return check_move_horse(xs,ys,xt,yt);
}
if(piece_num==5){
return check_move_car(xs,ys,xt,yt);
}
if(piece_num==6){
return check_move_duck(xs,ys,xt,yt);
}
if(piece_num==7){
return check_move_soldier(xs,ys,xt,yt);
}
}
check_move_captain:
bool check_move_captain(int xs,int ys,int xt,int yt){
if(xs==xt && ys+1==yt){
return true;
}
if(xs==xt && ys-1==yt){
return true;
}
if(xs+1==xt && ys==yt){
return true;
}
if(xs-1==xt && ys==yt){
return true;
}
return false;
}
check_move_guard:
bool check_move_guard(int xs,int ys,int xt,int yt){
if(xs+1==xt && ys+1==yt){
return true;
}
if(xs+1==xt && ys-1==yt){
return true;
}
if(xs-1==xt && ys+1==yt){
return true;
}
if(xs-1==xt && ys-1==yt){
return true;
}
return false;
}
check_move_elephant:
bool check_move_elephant(int xs,int ys,int xt,int yt){
if(xs+2==xt && ys+2==yt){
int mid=chess_board[xs+1][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-2==yt){
int mid=chess_board[xs+1][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+2==yt){
int mid=chess_board[xs-1][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-2==yt){
int mid=chess_board[xs-1][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
return false;
}
check_move_horse:
bool check_move_horse(int xs,int ys,int xt,int yt){
if(xs+1==xt && ys+2==yt){
int mid=chess_board[xs][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-1==xt && ys+2==yt){
int mid=chess_board[xs][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+1==xt && ys-2==yt){
int mid=chess_board[xs][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-1==xt && ys-2==yt){
int mid=chess_board[xs][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys+1==yt){
int mid=chess_board[xs+1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-1==yt){
int mid=chess_board[xs+1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+1==yt){
int mid=chess_board[xs-1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-1==yt){
int mid=chess_board[xs-1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
return false;
}
check_move_car:
bool check_move_car(int xs,int ys,int xt,int yt){
if(xs==xt && ys<yt){
for(int y=ys+1;y<=yt-1;y++){
if(chess_board[xs][y]){
return false;
}
}
return true;
}
if(xs==xt && ys>yt){
for(int y=ys-1;y>=yt+1;y--){
if(chess_board[xs][y]){
return false;
}
}
return true;
}
if(xs<xt && ys==yt){
for(int x=xs+1;x<=xt-1;x++){
if(chess_board[x][ys]){
return false;
}
}
return true;
}
if(xs>xt && ys==yt){
for(int x=xs-1;x>=xt+1;x--){
if(chess_board[x][ys]){
return false;
}
}
return true;
}
return false;
}
check_move_duck:
bool check_move_duck(int xs,int ys,int xt,int yt){
if(xs+2==xt && ys+3==yt){
int mid1=chess_board[xs][ys+1],mid2=chess_board[xs+1][ys+2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+3==yt){
int mid1=chess_board[xs][ys+1],mid2=chess_board[xs-1][ys+2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-3==yt){
int mid1=chess_board[xs][ys-1],mid2=chess_board[xs+1][ys-2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-3==yt){
int mid1=chess_board[xs][ys-1],mid2=chess_board[xs-1][ys-2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+3==xt && ys+2==yt){
int mid1=chess_board[xs+1][ys],mid2=chess_board[xs+2][ys+1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+3==xt && ys-2==yt){
int mid1=chess_board[xs+1][ys],mid2=chess_board[xs+2][ys-1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-3==xt && ys+2==yt){
int mid1=chess_board[xs-1][ys],mid2=chess_board[xs-2][ys+1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-3==xt && ys-2==yt){
int mid1=chess_board[xs-1][ys],mid2=chess_board[xs-2][ys-1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
return false;
}
check_move_soldier:
bool check_move_soldier(int xs,int ys,int xt,int yt){
if(xs==xt && ys+1==yt){
return true;
}
if(xs==xt && ys-1==yt){
return true;
}
if(xs+1==xt && ys==yt){
return true;
}
if(xs-1==xt && ys==yt){
return true;
}
if(xs+1==xt && ys+1==yt){
return true;
}
if(xs+1==xt && ys-1==yt){
return true;
}
if(xs-1==xt && ys+1==yt){
return true;
}
if(xs-1==xt && ys-1==yt){
return true;
}
return false;
}
接下来你就可以判断将军了:
bool captain_will_die(int xs,int ys,int xt,int yt){
if(GAME_END){
return false;
}
int red_x,red_y,blue_x,blue_y;
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if(chess_board[x][y]==11){
red_x=x;
red_y=y;
}
if(chess_board[x][y]==21){
blue_x=x;
blue_y=y;
}
}
}
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
int pre=chess_board[x][y];
if(pre/10==1){
if(able_move(x,y,blue_x,blue_y)){
return true;
}
}
if(pre/10==2){
if(able_move(x,y,red_x,red_y)){
return true;
}
}
}
}
return false;
}
最后一块拼图,实现 work_move:
void work_move(int xs,int ys,int xt,int yt){
if(!check_move(xs,ys,xt,yt)){
printf("Invalid command\n");
return ;
}
int s=chess_board[xs][ys],t=chess_board[xt][yt];
cout<<num_to_name(s)<<";"<<num_to_name(t)<<";";
chess_board[xt][yt]=chess_board[xs][ys];
chess_board[xs][ys]=0;
if(t%10==1){
printf("no;yes\n");
GAME_END=true;
}
else{
if(captain_will_die()){
printf("yes;no\n");
}
else{
printf("no;no\n");
}
}
pre_player=3-pre_player;
}
妈妈,我写的大模拟一遍就过了!
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
/*
name rule:10x+y
x=1:red x=2:blue
y=1:captain y=2:guard y=3:elephant y=4:horse y=5:car y=6:duck y=7:soldier
example:23=blue elephant
*/
const int n=10,m=9;
int chess_board[n][m]={
{15,14,13,12,11,12,13,14,15},
{0,0,0,0,0,0,0,0,0},
{16,0,0,0,0,0,0,0,16},
{17,0,17,0,17,0,17,0,17},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{27,0,27,0,27,0,27,0,27},
{26,0,0,0,0,0,0,0,26},
{0,0,0,0,0,0,0,0,0},
{25,24,23,22,21,22,23,24,25}
};
string belong_name[3]={"NA","red","blue"};
string piece_name[8]={"NA","captain","guard","elephant","horse","car","duck","soldier"};
string num_to_name(int num){
if(num==0) return "NA";
int belong_num=num/10,piece_num=num%10;
return belong_name[belong_num]+" "+piece_name[piece_num];
}
void debug_print_num(){
printf("Chess board:\n\n");
for(int i=2*n;i>=0;i--){
if(i%2==0){
printf(" ");
for(int j=0;j<=3*m;j++){
if(j%3==0){
printf("+");
}
else{
printf("-");
}
}
}
else{
printf("%2d ",i/2);
for(int j=0;j<=2*m;j++){
if(j%2==0){
printf("|");
}
else{
printf("%2d",chess_board[i/2][j/2]);
}
}
}
printf("\n");
}
printf(" ");
for(int j=0;j<=2*m;j++){
if(j%2==0){
printf(" ");
}
else{
printf("%2d",j/2);
}
}
printf("\n\n");
}
int pre_player=1;
bool check_self(int x,int y){
int belong_num=chess_board[x][y]/10;
return belong_num==pre_player;
}
bool check_move_captain(int xs,int ys,int xt,int yt){
if(xs==xt && ys+1==yt){
return true;
}
if(xs==xt && ys-1==yt){
return true;
}
if(xs+1==xt && ys==yt){
return true;
}
if(xs-1==xt && ys==yt){
return true;
}
return false;
}
bool check_move_guard(int xs,int ys,int xt,int yt){
if(xs+1==xt && ys+1==yt){
return true;
}
if(xs+1==xt && ys-1==yt){
return true;
}
if(xs-1==xt && ys+1==yt){
return true;
}
if(xs-1==xt && ys-1==yt){
return true;
}
return false;
}
bool check_move_elephant(int xs,int ys,int xt,int yt){
if(xs+2==xt && ys+2==yt){
int mid=chess_board[xs+1][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-2==yt){
int mid=chess_board[xs+1][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+2==yt){
int mid=chess_board[xs-1][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-2==yt){
int mid=chess_board[xs-1][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
return false;
}
bool check_move_horse(int xs,int ys,int xt,int yt){
if(xs+1==xt && ys+2==yt){
int mid=chess_board[xs][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-1==xt && ys+2==yt){
int mid=chess_board[xs][ys+1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+1==xt && ys-2==yt){
int mid=chess_board[xs][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-1==xt && ys-2==yt){
int mid=chess_board[xs][ys-1];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys+1==yt){
int mid=chess_board[xs+1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-1==yt){
int mid=chess_board[xs+1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+1==yt){
int mid=chess_board[xs-1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-1==yt){
int mid=chess_board[xs-1][ys];
if(!mid){
return true;
}
else{
return false;
}
}
return false;
}
bool check_move_car(int xs,int ys,int xt,int yt){
if(xs==xt && ys<yt){
for(int y=ys+1;y<=yt-1;y++){
if(chess_board[xs][y]){
return false;
}
}
return true;
}
if(xs==xt && ys>yt){
for(int y=ys-1;y>=yt+1;y--){
if(chess_board[xs][y]){
return false;
}
}
return true;
}
if(xs<xt && ys==yt){
for(int x=xs+1;x<=xt-1;x++){
if(chess_board[x][ys]){
return false;
}
}
return true;
}
if(xs>xt && ys==yt){
for(int x=xs-1;x>=xt+1;x--){
if(chess_board[x][ys]){
return false;
}
}
return true;
}
return false;
}
bool check_move_duck(int xs,int ys,int xt,int yt){
if(xs+2==xt && ys+3==yt){
int mid1=chess_board[xs][ys+1],mid2=chess_board[xs+1][ys+2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys+3==yt){
int mid1=chess_board[xs][ys+1],mid2=chess_board[xs-1][ys+2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+2==xt && ys-3==yt){
int mid1=chess_board[xs][ys-1],mid2=chess_board[xs+1][ys-2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-2==xt && ys-3==yt){
int mid1=chess_board[xs][ys-1],mid2=chess_board[xs-1][ys-2];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+3==xt && ys+2==yt){
int mid1=chess_board[xs+1][ys],mid2=chess_board[xs+2][ys+1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs+3==xt && ys-2==yt){
int mid1=chess_board[xs+1][ys],mid2=chess_board[xs+2][ys-1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-3==xt && ys+2==yt){
int mid1=chess_board[xs-1][ys],mid2=chess_board[xs-2][ys+1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
if(xs-3==xt && ys-2==yt){
int mid1=chess_board[xs-1][ys],mid2=chess_board[xs-2][ys-1];
if(!mid1 && !mid2){
return true;
}
else{
return false;
}
}
return false;
}
bool check_move_soldier(int xs,int ys,int xt,int yt){
if(xs==xt && ys+1==yt){
return true;
}
if(xs==xt && ys-1==yt){
return true;
}
if(xs+1==xt && ys==yt){
return true;
}
if(xs-1==xt && ys==yt){
return true;
}
if(xs+1==xt && ys+1==yt){
return true;
}
if(xs+1==xt && ys-1==yt){
return true;
}
if(xs-1==xt && ys+1==yt){
return true;
}
if(xs-1==xt && ys-1==yt){
return true;
}
return false;
}
bool able_move(int xs,int ys,int xt,int yt){
int piece_num=chess_board[xs][ys]%10;
if(piece_num==1){
return check_move_captain(xs,ys,xt,yt);
}
if(piece_num==2){
return check_move_guard(xs,ys,xt,yt);
}
if(piece_num==3){
return check_move_elephant(xs,ys,xt,yt);
}
if(piece_num==4){
return check_move_horse(xs,ys,xt,yt);
}
if(piece_num==5){
return check_move_car(xs,ys,xt,yt);
}
if(piece_num==6){
return check_move_duck(xs,ys,xt,yt);
}
if(piece_num==7){
return check_move_soldier(xs,ys,xt,yt);
}
}
bool GAME_END=false;
bool check_move(int xs,int ys,int xt,int yt){
if(GAME_END){
return false;
}
if(!check_self(xs,ys) || check_self(xt,yt)){
return false;
}
if(!able_move(xs,ys,xt,yt)){
return false;
}
return true;
}
bool captain_will_die(){
if(GAME_END){
return false;
}
int red_x,red_y,blue_x,blue_y;
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if(chess_board[x][y]==11){
red_x=x;
red_y=y;
}
if(chess_board[x][y]==21){
blue_x=x;
blue_y=y;
}
}
}
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
int pre=chess_board[x][y];
if(pre/10==1){
if(able_move(x,y,blue_x,blue_y)){
return true;
}
}
if(pre/10==2){
if(able_move(x,y,red_x,red_y)){
return true;
}
}
}
}
return false;
}
void work_move(int xs,int ys,int xt,int yt){
if(!check_move(xs,ys,xt,yt)){
printf("Invalid command\n");
return ;
}
int s=chess_board[xs][ys],t=chess_board[xt][yt];
cout<<num_to_name(s)<<";"<<num_to_name(t)<<";";
chess_board[xt][yt]=chess_board[xs][ys];
chess_board[xs][ys]=0;
if(t%10==1){
printf("no;yes\n");
GAME_END=true;
}
else{
if(captain_will_die()){
printf("yes;no\n");
}
else{
printf("no;no\n");
}
}
pre_player=3-pre_player;
}
int main(){
int q;
scanf("%d",&q);
while(q--){
int xs,ys,xt,yt;
scanf("%d %d %d %d",&xs,&ys,&xt,&yt);
work_move(xs,ys,xt,yt);
}
return 0;
}
萌新做的第一道大模拟,总用时 \(100\) 分钟。
感觉鸭棋在大模拟里面算是最简单的一个了,游戏的规则很明确,实现的时候也不费力。
不错的鸭棋,鸭棋和模拟相互呼应,声光交融,指尖灵动,即使是我,也感到心潮澎湃。

浙公网安备 33010602011771号