[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\) 分钟。

感觉鸭棋在大模拟里面算是最简单的一个了,游戏的规则很明确,实现的时候也不费力。

不错的鸭棋,鸭棋和模拟相互呼应,声光交融,指尖灵动,即使是我,也感到心潮澎湃。

posted @ 2025-12-18 09:35  Oken喵~  阅读(6)  评论(0)    收藏  举报