专栏文章

机房五人一晚上整出的双人象棋

科技·工程参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miohho09
此快照首次捕获于
2025/12/02 19:17
3 个月前
此快照最后确认于
2025/12/02 19:17
3 个月前
查看原文
CPP
#include<bits/stdc++.h>
#include<windows.h>
#include<Windows.h>
#define color(a) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a)
const int N=55,n=19,m=17,boundd=60;
using namespace std;
struct Chess{string name; int zy;}chess[N][N];
bool hef(int x,int y){
	return (1<=x && x<=n) & (1<=y && y<=m);
}
void clear(int x,int y){chess[x][y].name="  ";chess[x][y].zy=2;}
bool turn;//阵营0红1黑2环境 
int step,eatc,pec;
double w1,w2;
void init(){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)chess[i][j].name="  ",chess[i][j].zy=2;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==10)continue;
			if(!(j&1)&&i&1)chess[i][j].name="一",chess[i][j].zy=2;
			if(!(i&1)&&j&1)chess[i][j].name="丨",chess[i][j].zy=2;
		}
	}
	for(int j=1;j<=m;j++)
		if(j%4==1)chess[7][j].name="兵",chess[7][j].zy=0;
	chess[1][1].name=chess[1][17].name="俥",chess[1][1].zy=0,chess[1][17].zy=0;
	chess[1][3].name=chess[1][15].name="馬",chess[1][3].zy=0,chess[1][15].zy=0;
	chess[1][5].name=chess[1][13].name="相",chess[1][5].zy=0,chess[1][13].zy=0;
	chess[1][7].name=chess[1][11].name="仕",chess[1][7].zy=0,chess[1][11].zy=0;
	chess[5][3].name=chess[5][15].name="砲",chess[5][3].zy=0,chess[5][15].zy=0;
	chess[1][9].name="帅",chess[1][9].zy=0;
	for(int j=1;j<=m;j++)
		if(j%4==1)chess[13][j].name="卒",chess[13][j].zy=1;
	chess[19][1].name=chess[19][17].name="車",chess[19][1].zy=1,chess[19][17].zy=1;
	chess[19][3].name=chess[19][15].name="马",chess[19][3].zy=1,chess[19][15].zy=1;
	chess[19][5].name=chess[19][13].name="象",chess[19][5].zy=1,chess[19][13].zy=1;
	chess[19][7].name=chess[19][11].name="士",chess[19][7].zy=1,chess[19][11].zy=1;
	chess[15][3].name=chess[15][15].name="炮",chess[15][3].zy=1,chess[15][15].zy=1;
	chess[19][9].name="将",chess[19][9].zy=1;
}
pair<int,int> hashh(int o){//0防御 1进攻 
	int cnt1=0,cnt2=0;
	int px1=0,py1=0,px2=0,py2=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(chess[i][j].name=="帅"){
				px1=i;
				py1=j; 
			}
			if(chess[i][j].name=="将"){
				px2=i;
				py2=j; 
			}
		}
	} 
	if(o){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				double dis1=sqrt((px1-i)*(px1-i)+(py1-j)*(py1-j)),dis2=sqrt((px2-i)*(px2-i)+(py2-j)*(py2-j)),bl1=1/sqrt(dis1),bl2=1/sqrt(dis2);
				if(chess[i][j].name=="俥") cnt1+=100*bl2;
				else if(chess[i][j].name=="車") cnt2+=100*bl1;
				else if(chess[i][j].name=="馬"){
					if(step<=40) cnt1+=70*bl2;
					else if(step<=80) cnt1+=80*bl2;
					else cnt1+=85*bl2;
				}
				else if(chess[i][j].name=="马"){
					if(step<=40) cnt2+=70*bl1;
					else if(step<=80) cnt2+=80*bl1;
					else cnt2+=85*bl1;
				}
				else if(chess[i][j].name=="砲"){
					if(step<=40) cnt1+=85*bl2;
					else if(step<=80) cnt1+=75*bl2;
					else cnt1+=50*bl2;
				}
				else if(chess[i][j].name=="炮"){
					if(step<=40) cnt2+=85*bl1;
					else if(step<=80) cnt2+=75*bl1;
					else cnt2+=50*bl1;
				}
				else if(chess[i][j].name=="兵"){
					if(step<=40) cnt1+=10*bl2;
					else if(step<=80) cnt1+=15*bl2;
					else{
						if(i>=11) cnt1+=30*bl2;
						else cnt1+=15*bl2;
					}
				}
				else if(chess[i][j].name=="卒"){
					if(step<=40) cnt2+=10*bl1;
					else if(step<=80) cnt2+=15*bl1;
					else{
						if(i<=9) cnt2+=30*bl1;
						else cnt2+=15*bl1;
					}
				}
			}
		}
	}
	else{
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				double dis1=sqrt((px1-i)*(px1-i)+(py1-j)*(py1-j)),dis2=sqrt((px2-i)*(px2-i)+(py2-j)*(py2-j)),bl1=1/dis1,bl2=1/dis2;
				if(chess[i][j].name=="俥"){
					if(step<=40) cnt1+=30*bl1;
					else cnt1+=40*bl1;
				}
				else if(chess[i][j].name=="車"){
					if(step<=40) cnt2+=30*bl2;
					else cnt2+=40*bl2;
				}
				else if(chess[i][j].name=="馬"){
					if(step<=40) cnt1+=30*bl1;
					else if(step<=80) cnt1+=40*bl1;
					else cnt1+=45*bl1;
				}
				else if(chess[i][j].name=="马"){
					if(step<=40) cnt2+=30*bl2;
					else if(step<=80) cnt2+=40*bl2;
					else cnt2+=45*bl2;
				}
				else if(chess[i][j].name=="砲"){
					if(step<=40) cnt1+=15*bl1;
					else if(step<=80) cnt1+=10*bl1;
					else cnt1+=5*bl1;
				}
				else if(chess[i][j].name=="炮"){
					if(step<=40) cnt2+=15*bl2;
					else if(step<=80) cnt2+=10*bl2;
					else cnt2+=5*bl2; 
				}
				else if(chess[i][j].name=="仕"){
					if(step<=40) cnt1+=40;
					else if(step<=80) cnt1+=50;
					else cnt1+=60;
				}
				else if(chess[i][j].name=="士"){
					if(step<=40) cnt2+=40;
					else if(step<=60) cnt2+=50;
					else cnt2+=60;
				}
				else if(chess[i][j].name=="相"){
					if(step<=80) cnt1+=30*bl1;
					else cnt1+=35*bl1;
				}
				else if(chess[i][j].name=="象"){
					if(step<=80) cnt2+=30*bl2;
					else cnt2+=35*bl2; 
				}
			}
		}
	}
	return make_pair(cnt1,cnt2);
}
int checkline(int x,int y,int _y){
	if(y>_y) swap(y,_y);
	int cnt=0;
	for(int i=y+1; i<=_y-1; i++){
		if(chess[i][x].zy<=1) cnt++;
	}
	return cnt;
}
int checkrow(int y,int x,int _x){
	if(x>_x) swap(x,_x);
	int cnt=0;
	for(int i=x+1; i<=_x-1; i++){
		if(chess[y][i].zy<=1) cnt++;
	}
	return cnt;
}
bool can_move(string name,int x,int y,int _x,int _y){
	swap(x,y),swap(_x,_y);
	if(!hef(_y,_x) && !hef(y,x)) return 0;
	if(chess[y][x].zy!=turn) return 0;
	if(x==_x && y==_y) return 0;
	if(chess[y][x].zy==chess[_y][_x].zy) return 0; 
	if(name=="俥" || name=="車"){
		if(x==_x && !checkline(x,y,_y)) 
			return 1;
		else if(y==_y && !checkrow(y,x,_x)) 
			return 1;
		return 0;
	} else if(name=="砲" || name=="炮"){
		if(x==_x && checkline(x,y,_y)==0 && chess[_y][_x].zy==2) 
			return 1;
		else if(y==_y && checkrow(y,x,_x)==0 && chess[_y][_x].zy==2) 
			return 1;
		else if(x==_x && checkline(x,y,_y)==1 && chess[_y][_x].zy+chess[y][x].zy==1)
			return 1;
		else if(y==_y && checkrow(y,x,_x)==1 && chess[_y][_x].zy+chess[y][x].zy==1)
			return 1; 
		else return 0;
	}else if(name=="马" || name=="馬"){
		bool f1=0,f2=1;
		int dx=abs(x-_x),dy=abs(y-_y);
		if(dx&1 || dy&1) return 0;
		if(dx+dy==6 && dx && dy)
			f1=1;
		if(dx==4 && chess[y][(x+_x)/2].zy<=1) //别马腿 
			f2=0;
		if(dy==4 && chess[(y+_y)/2][x].zy<=1) //别马腿 
			f2=0;
		return f1&f2;
	}
	else if(name=="相" || name=="象"){
		bool f1=0,f2=1;
		if(name=="相" && _y>=11) return 0;
		if(name=="象" && _y<=9) return 0;
		int dx=abs(x-_x),dy=abs(y-_y);
		if(dx&1 || dy&1) return 0;
		if(dx+dy==8 && dx==dy)
			f1=1;
		if(chess[(y+_y)/2][(x+_x)/2].zy<=1) //塞象眼 
			f2=0;
		return f1&f2;
	}else if(name=="兵" || name=="卒"){
		int dx=abs(x-_x),dy=abs(y-_y);
		if(name=="兵"){
			if(_y>=11)
				if(dx+dy==2 && (_y-y==2 || dx==2)) return 1;
			if(_y-y==2) return 1;
			return 0;
		} 
		if(name=="卒"){
			if(_y<=9)
				if(dx+dy==2 && (_y-y==-2 || dx==2)) return 1;
			if(_y-y==-2) return 1;
			return 0;
		}
	} else if(name=="士" || name=="仕"){
		int dx=abs(x-_x),dy=abs(y-_y);
		if(name=="仕"){
			if(_y>5 || _x>11 || _x<7) return 0;
			if(dx!=2 || dy!=2) return 0;
			return 1;
		} 
		if(name=="士"){
			if(_y<15 || _x>11 || _x<7) return 0;
			if(dx!=2 || dy!=2) return 0;
			return 1;
		}
	}else if(name=="帅" || name=="将"){
		int dx=abs(x-_x),dy=abs(y-_y);
		if(name=="帅"){
			if(_y>5 || _x>11 || _x<7) return 0;
			if(dx==2 && !dy || dy==2 && !dx) return 1;
			return 0;
		} 
		if(name=="将"){
			if(_y<15 || _x>11 || _x<7) return 0;
			if(dx==2 && !dy || dy==2 && !dx) return 1;
			return 0;
		}
	}
}
bool ftf(){
	int pos_x=0,pos_y=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(chess[i][j].name=="将"){
				pos_x=i;
				pos_y=j;
				break;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(chess[i][j].name=="帅"){
				if(j==pos_y){
					if(checkline(j,i,pos_x)==0){
						return 1;
					}
				}
			}
		}
	}
	return 0;
}
int ckjiangjun(){//判断将军 1車 2炮 3马 4 兵卒 
	
	int lst=turn^1;
	int pos_x=0,pos_y=0;//将的坐标 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if((turn==1&&chess[i][j].name=="帅")||(turn==0&&chess[i][j].name=="将")){
				pos_x=i;
				pos_y=j;
				break;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if((chess[i][j].name=="俥"&&turn==0)||(chess[i][j].name=="車"&&turn==1)){
				if(i==pos_x){
					int cnt=0;
					for(int k=min(j,pos_y)+1;k<max(j,pos_y);k++){
						if(chess[i][k].zy!=2){
							cnt++;
						}
					}
					if(cnt==0){
						return 1;
					}
				}
				else if(j==pos_y){
					int cnt=0;
					for(int k=min(i,pos_x)+1;k<max(i,pos_x);k++){
						if(chess[k][j].zy!=2){
							cnt++;
						}
					}
					if(cnt==0){
						return 1;
					}
				}
			}
			else if((chess[i][j].name=="砲"&&turn==0)||(chess[i][j].name=="炮"&&turn==1)){
				if(i==pos_x){
					int cnt=0;
					for(int k=min(j,pos_y)+1;k<max(j,pos_y);k++){
						if(chess[i][k].zy!=2){
							cnt++;
						}
					}
					if(cnt==1){
						return 2;
					}
				}
				else if(j==pos_y){
					int cnt=0;
					for(int k=min(i,pos_x)+1;k<max(i,pos_x);k++){
						if(chess[k][j].zy!=2){
							cnt++;
						}
					}
					if(cnt==1){
						return 2;
					}
				}
			}
			else if((chess[i][j].name=="馬"&&turn==0)||(chess[i][j].name=="马"&&turn==1)){
				if(i+2==pos_x&&j+4==pos_y&&chess[i][j+2].zy==2){
					return 3;
				}
				else if(i+2==pos_x&&j-4==pos_y&&chess[i][j-2].zy==2){
					return 3;
				}
				else if(i-2==pos_x&&j+4==pos_y&&chess[i][j+2].zy==2){
					return 3;
				}
				else if(i-2==pos_x&&j-4==pos_y&&chess[i][j-2].zy==2){
					return 3;
				}
				else if(i+4==pos_x&&j+2==pos_y&&chess[i+2][j].zy==2){
					return 3; 
				}
				else if(i+4==pos_x&&j-2==pos_y&&chess[i+2][j].zy==2){
					return 3;
				}
				else if(i-4==pos_x&&j+2==pos_y&&chess[i-2][j].zy==2){
					return 3;
				}
				else if(i-4==pos_x&&j-2==pos_y&&chess[i-2][j].zy==2){
					return 3;
				}
			}
			else if(chess[i][j].name=="兵"&&turn==0){
				if(i>=11){//过河兵 
					if(i==pos_x&&j-2==pos_y){
						return 4;
					}
					else if(abs(i-pos_x)+abs(j-pos_y)==2){
						return 4;
					}
				}
			}
			else if(chess[i][j].name=="卒"&&turn==1){
				if(i<=10){//过河卒 
					if(i==pos_x&&j+2==pos_y){
						return 4;
					}
					else if(abs(i-pos_x)+abs(j-pos_y)==2){
						return 4;
					}
				}
			}
		}
	}
	return 0;
}
void print(int x,int y){
//	cout<<x<<" "<<y<<endl;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==x&&j==y) color(8);
			else if(chess[i][j].zy==0) color(12);
			else if(chess[i][j].zy==1) color(10);
			else color(15);
			cout<<chess[i][j].name;
			if(i==x&&j==y){
				chess[i][j].name="  ";
			}
			color(15);
		}
		if(i&1) printf("%2d\n",(i+1)/2);
		else printf("\n");
	}
	for(int i=1;i<=m;i++){
		if(i&1) printf("%2d",(i+1)/2);
		else printf("  ");
	}
}
bool ckover(){
	bool f=1;
	turn^=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			Chess c=chess[i][j];
			if(c.zy!=turn || c.zy==2) continue;
			for(int _x=1; _x<=n; _x++){
				for(int _y=1; _y<=m; _y++){
					if(_x%2==0 || _y%2==0) continue;
					Chess pre=chess[_x][_y];
					if(!can_move(c.name,i,j,_x,_y)) continue;
					swap(chess[i][j],chess[_x][_y]);
					clear(i,j);
					turn^=1;
					if(!ckjiangjun()&&!ftf()){
						f=0;
					}
					turn^=1;
					swap(chess[i][j],chess[_x][_y]);
					chess[_x][_y]=pre;
					if(!f) {
						turn^=1;
						return f;
					}
				}
			}		
		}
	turn^=1;
	return 1;
}
bool peace(){
	if(step<=60) return 0;
	if(eatc<=8) return 0;
	pair<int,int> int4399=hashh(1),wch666=hashh(0);
	int atkr=int4399.first,atkb=int4399.second,prtr=wch666.first,prtb=wch666.second;
	if(!(abs(atkr-atkb)<=20 &&  abs(prtr-prtb)<=20)) return 0;
	return 1;
} 
int main(){
	init();
	print(0,0);
	string red_black[2]={"红","黑"}; 
	while(1){
		cout<<endl<<" "<<hashh(0).first<<" "<<hashh(0).second<<" "<<hashh(1).first<<" "<<hashh(1).second<<endl;
		cout<<"\n\n轮到"<<red_black[turn]<<"方移动\n";
		cout<<"请输入要移动棋子的横纵坐标及移动后的横纵坐标\n";
		cout<<"右边的是纵坐标,下方的是横坐标\n";
		int x1,y1,x2,y2;
		cin>>y1>>x1>>y2>>x2;
		x1=2*x1-1,y1=2*y1-1,x2=2*x2-1,y2=2*y2-1;
		bool joker=0;
		bool ck=0;
		if(can_move(chess[x1][y1].name,x1,y1,x2,y2)){
			Chess tmp=chess[x2][y2];
			if(chess[x2][y2].zy<=1 && chess[x2][y2].zy!=chess[x1][y1].zy){
				chess[x2][y2]=(Chess){"  ",2};
				joker=1;
			}
			swap(chess[x1][y1],chess[x2][y2]);
			if(ftf()){
				system("cls");
				swap(chess[x1][y1],chess[x2][y2]);
				chess[x2][y2]=tmp;
				print(0,0);
				cout<<"\n\n移动不合法,请重新移动\n";
				continue;
			}
			turn^=1;
			if(ckjiangjun()){
				swap(chess[x1][y1],chess[x2][y2]);
				chess[x2][y2]=tmp;
				system("cls");
				print(0,0);
				cout<<"\n\n禁止送将,请重新移动\n";
				turn^=1;
				continue;
			}
			turn^=1;
			system("cls");
			chess[x1][y1].name=chess[x2][y2].name;
			chess[x1][y1].zy=2;
			print(x1,y1);
			if(ckover()){
				cout<<"\n\n      绝杀\n";
				break;
			}
			if(ckjiangjun()){ 
			
				cout<<"\n\n将军\n";
				ck=1;
			}
			else{
				turn^=1;
				if(ckjiangjun()){
					ck=1;
					eatc=0;
					cout<<"\n\n将军\n";
				}
				turn^=1;
				
			}
			if(joker && !ck){
				eatc=0;
				cout<<"\n\n吃"; 
			}
		}else{
			system("cls");	
			print(0,0); 
			cout<<"\n\n移动不合法,请重新移动\n";
			continue;
		}
		int f1=0,f2=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(chess[i][j].name=="帅"){
					f1=1;
				}
				if(chess[i][j].name=="将"){
					f2=1;
				}
			}
		}
		if(!f1||!f2){
			break;
		}
		if(peace() && pec>=10){
			pec=0;
			cout<<"\n\n局势已进入僵局,是否和棋?双方均输入 1 则和棋\n\n";
			int pr,pb;
			cin>>pr>>pb;
			if(pr==1 && pb==1){
				cout<<"\n  和棋\n";
				return 0; 
			}
		}
		turn^=1;
		pec++;
		eatc++; 
		step++;
	}
	cout<<"\n"<<red_black[turn]<<"方获胜\n";
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...