要求:
在象棋棋盘中,只布局了红方的棋子,不断输入要移动棋子的位置及目的位置,设计程序判断走棋是否符合规则并动态显示出棋盘布局。
程序更够完美实现要求的内容。
代码正文:
//#include "pch.h"
#include <iostream>
#include <cstring>
#include "string.h"
#include "math.h"
using namespace std;
#define M 10
#define N 9
#define G (M-1)//M-1
//Castle //車 10 11
//Knight //马 20 21
//Bishop //象 30 31
//Mandarin //士 40 41
//king //将 50
//Cannon //炮 60 61
//pawn //卒 70 71 72 73 74
// 0 1 2 3 4 5 6 7 8
// 9 + + + + + + + + +
// 8 + + + + + + + + +
// 7 + + + + + + + + +
// 6 + + + + + + + + +
// 5 - - - - - - - - -
// 4 - - - - - - - - -
// 3 卒 + 卒 + 卒 + 卒 + 卒
// 2 + 炮 + + + + + 炮 +
// 1 + + + + + + + + +
// 0 車 马 象 士 将 士 象 马 車
// 0 1 2 3 4 5 6 7 8
class ChineseChess
{
public:
int a[M][N];
// char b[] = "車马象士将炮卒"; //車1马2象3士4将5炮6卒7
//char cn[7][9] = { "Castle", "Knight", "Bishop", "Mandarin", "king", "Cannon", "pawn" };
ChineseChess(void);
int move(int x1, int y1, int x2, int y2);
int print(void);
void menu(void);
int is_empty(int x, int y);
int is_in_range(int x, int y);
int is_piece_in_route(int x1, int y1, int x2, int y2);
int is_same(int x1, int y1, int x2, int y2);
int restore() ;
int Castle_Cannon(int x1, int y1, int x2, int y2);
int Knight(int x1, int y1, int x2, int y2);
int Bishop(int x1, int y1, int x2, int y2);
int Mandarin(int x1, int y1, int x2, int y2);
int King(int x1, int y1, int x2, int y2);
int Pawn(int x1, int y1, int x2, int y2);
};
int main() {
ChineseChess mych;
// printf("┐ ┌ ┬ ├ ┤ ┘ └ ┴ ");
mych.menu();
return 0;
}
ChineseChess::ChineseChess(void)
{
memset(a, 0, sizeof(a));
// 0层
a[0][0] = 10;
a[0][1] = 20;
a[0][2] = 30;
a[0][3] = 40;
a[0][4] = 50;
a[0][5] = 41;
a[0][6] = 31;
a[0][7] = 21;
a[0][8] = 11;
// 1层
for (int i = 0; i < N; i++)
{
a[1][0] = 0;
}
// 2层
for (int i = 0; i < N; i++)
{
a[2][0] = 0;
}
a[2][1] = 60;
a[2][7] = 61;
// 3层
a[3][0] = 70;
a[3][2] = 71;
a[3][4] = 72;
a[3][6] = 73;
a[3][8] = 74;
}
int ChineseChess::print(void)
{
int i, j;
// printf("%d %d", 10,9);
printf("\n ");
for (j = 0; j < N; j++) {
printf("%3d ", j);
}
for (i = G; i >= 0; i--) {
printf("\n%4d", i);
for (j = 0; j < N; j++) {
switch (a[i][j] / 10)
{
case -1:
printf(" ● ");
break;
case 0:
if (i == 4 || i == 5)
cout << " - ";
// else if((i==9&&j==5)||(i==2&&j==5))
// printf(" ┐ ");
// else if((i==9&&j==3)||(i==2&&j==3))
// printf(" ┌ ");
// else if( (i==2&&j==4) )
// printf(" ┬ ");
// else if( (i==7&&j==4) )
// printf(" ┴ ");
// else if((i==8&&j==3)||(i==1&&j==3))
printf(" ├ ");
// printf(" | ");
// else if((i==8&&j==5)||(i==1&&j==5))
printf(" ┤ ");
// printf(" ┃ ");
// else if((i==7&&j==5)||(i==0&&j==5))
// printf(" ┘ ");
// else if((i==7&&j==3)||(i==0&&j==3))
// printf(" └ ");
else
printf(" + ");
break;
case 1:
printf(" 車 ");
break;
case 2:
printf(" 马 ");
break;
case 3:
printf(" 象 ");
break;
case 4:
printf(" 仕 ");
break;
case 5:
printf(" 将 ");
break;
case 6:
printf(" 炮 ");
break;
case 7:
printf(" 卒 ");
break;
default:
cout << endl << "<<menu运行错误" << endl;
exit(0);
}
//printf("%4d", a[i][j]);
}
if(i==5)
cout<<endl<<" 楚 河 汉 界";
}
printf("\n ");
for (j = 0; j < N; j++) {
printf("%3d ", j);
}
cout << endl<<endl;
return 0;
}
void ChineseChess::menu(void)
{
int x1,y1,x2,y2;
int res;
print();
while (1) {
cout << "<<请输入源坐标与目的坐标,格式为x1 y1回车x2 y2回车,输入-1 -1回车结束移动" << endl<<">>";
cin >> x1 >> y1;
if (x1 == -1 || y1 == -1)
{
break;
}
cout << ">>";
cin >> x2 >> y2;
res = move(x1, y1, x2, y2);
switch(res)
{
case 0:
cout << "<<移动成功" << endl;
print();
break;
case -1:
cout << "<<源坐标和目标坐标坐标相同" << endl;
break;
case -2:
cout << "<<源坐标或目标坐标不在范围内" << endl;
break;
case -3:
cout << "<<源坐标为空或目标坐标非空" << endl;
break;
case -4:
cout << "<<违背棋子规则" << endl;
break;
default:
cout << endl << "<<menu运行错误" << endl;
exit(0);
break;
}
}
}
//-1源坐标和目标坐标坐标相同
//-2源坐标或目标坐标不在范围内
//-3源坐标为空或目标坐标非空
//-4违背棋子规则
int ChineseChess::move(int x1, int y1, int x2, int y2)
{
int res;
if (is_same(x1, y1, x2, y2))
return -1;
if (!is_in_range(x1, y1) || !is_in_range(x2, y2))
return -2;
if (is_empty(x1, y1) || !is_empty(x2, y2))
return -3;
switch (a[x1][y1] / 10)
{
case 1://車
res = Castle_Cannon(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 2://马
res = Knight(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 3://象
res = Bishop(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 4://士
res = Mandarin(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 5://将
res = King(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 6://炮
res = Castle_Cannon(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 7://卒
res = Pawn(x1, y1, x2, y2);
if (res != 0)
return res;
break;
case 0:
default:
cout << endl << "<<move运行错误" << endl;
exit(0);
break;
}
return 0;
}
//为空返回1
//非空返回0
int ChineseChess::is_empty(int x, int y)
{
if (a[x][y] == 0)
return 1;
else
return 0;
}
int ChineseChess::is_in_range(int x, int y)
{
if ((x >= 0) && (x <= G) && (y >= 0) && (y < N))
return 1;
else
return 0;
}
int ChineseChess::is_piece_in_route(int x1, int y1, int x2, int y2)
{
int i;
if (x1 == x2)
{
if (y1 > y2)
{
for (i = y2 + 1; i < y1; i++)
{
if (a[x1][i] != 0)
return -2;
}
}
else
{
for (i = y1 + 1; i < y2; i++)
{
if (a[x1][i] != 0)
return -2;
}
}
}
else if (y1 == y2)
{
if (x1 > x2)
{
for (i = x2 + 1; i < x1; i++)
{
if (a[i][y1] != 0)
return -2;
}
}
else
{
for (i = x1 + 1; i < x2; i++)
{
if (a[i][y1] != 0)
return -2;
}
}
}
else
{
return -1;
}
return 0;
}
int ChineseChess::is_same(int x1, int y1, int x2, int y2)
{
if (x1 == x2 && y1 == y2)
return 1;
else
return 0;
}
//删除上一颗☆
int ChineseChess::restore()
{
int i, j;
for (i = G; i >= 0; i--)
for (j = 0; j < N; j++)
if(a[i][j] / 10==-1)
a[i][j]=0;
return 0;
}
//車炮
int ChineseChess::Castle_Cannon(int x1, int y1, int x2, int y2)
{
if (x1 != x2 && y1 != y2)
{
return -4;
}
//cout << is_piece_in_route(x1, y1, x2, y2)<< endl;
if (is_piece_in_route(x1, y1, x2, y2))
{
return -4;
}
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}
//马
int ChineseChess::Knight(int x1, int y1, int x2, int y2)
{
if(abs(x2-x1)==0){
return -4;
}
else if(abs(x2-x1)==1){
//非日
if(abs(y2-y1)!=2)
return -4;
//蹩马腿
if(!is_empty(x1,(y1+y2)/2))
return -4;
}
else if(abs(x2-x1)==2){
//非日
if(abs(y2-y1)!=1)
return -4;
//蹩马腿
if(!is_empty((x1+x2)/2,y1))
return -4;
}
else{
return -4;
}
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}
//象
int ChineseChess::Bishop(int x1, int y1, int x2, int y2)
{
// if( !( (x2==0&&y2==2)||
// (x2==2&&y2==0)||
// (x2==4&&y2==2)||
// (x2==2&&y2==4)||
// (x2==0&&y2==6)||
// (x2==2&&y2==8)||
// (x2==4&&y2==6) )
// )
// return -4;
//过河了
if(x2>4)
return -4;
//没走田字
if(!(abs(x2-x1)==2&&abs(y2-y1)==2))
return -4;
//蹩象腿
if(!is_empty((x1+x2)/2,(y1+y2)/2))
return -4;
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}
//士
int ChineseChess::Mandarin(int x1, int y1, int x2, int y2)
{
if(!(x2>=0&&x2<=2&&y2>=3&&y2<=5) )
return -4;
if(!(abs(x2-x1)==1&&abs(y2-y1)==1))
return -4;
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}
//将
int ChineseChess::King(int x1, int y1, int x2, int y2)
{
if(!(x2>=0&&x2<=2&&y2>=3&&y2<=5) )
return -4;
if(abs(x2-x1)+abs(y2-y1)!=1)
return -4;
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}
//卒
int ChineseChess::Pawn(int x1, int y1, int x2, int y2)
{
//横竖方向步伐大于1
if( abs(x2-x1)+abs(y2-y1) != 1 )
return -4;
//没过河左右走
if( x1<=4 && abs(y2-y1)!=0 )
return -4;
if( x2-x1 == -1)
return -4;
a[x2][y2] = a[x1][y1];
restore();
a[x1][y1] = -11;
return 0;
}