java实现中国象棋3:走棋规则的实现

前言

之前我们已经实现了棋子的移动,但是可以发现棋子可以任意移动,不遵循中国象棋的规则,这篇博客便是为了实现中国象棋的走棋规则。在这里默认大家都已经知道中国象棋走棋的规则,如果不知道请自行百度学习。

一、设计 findnumb() 方法

此方法用来找出开始位置和点击位置在一条直线上时中间的棋子数目,用来判断炮和车(車)是否可以移动。代码如下:

	// 找到某一起点到终点中含有的棋子数
	public int findnumb(int r1, int c1, int r2, int c2) {
		int numb = 0;
		if (r1 == r2) {
			for (int i = Math.min(c1, c2) + 1; i < Math.max(c1, c2); i++) {
				if (flag[r1][i] > 0) {
					numb++;
				}
			}
		} else if (c1 == c2) {
			for (int i = Math.min(r1, r2) + 1; i < Math.max(r1, r2); i++) {
				if (flag[i][c1] > 0) {
					numb++;
				}
			}
		}
		return numb;
	}

其中 r 1 , c 1 , r 2 , c 2 r1,c1,r2,c2 r1,c1,r2,c2分别为开始位置的行列数和点击位置的行列数,返回的 n u m b numb numb为直线上的棋子数。

二、设计 ifwalk() 方法

ifwalk() 方法判断选中的棋子是否可以移动到现在选择的位置,根据中国象棋的走棋规则,可以很容易地写出以下代码。

	public int ifwalk(int who) {
		int ifflag = 0;
		// 将的走法
		if (who == 5) {
			if (r < 3 & c < 6 & c > 2) {
				if (beforechess[0] == curchess[0] & Math.abs(beforechess[1] - curchess[1]) == 1
						| beforechess[1] == curchess[1] & Math.abs(beforechess[0] - curchess[0]) == 1) {
					ifflag = 1;
				}
			}
		}
		// 帅的走法
		else if (who == 55) {
			if (r > 6 & c < 6 & c > 2) {
				if (beforechess[0] == curchess[0] & Math.abs(beforechess[1] - curchess[1]) == 1
						| beforechess[1] == curchess[1] & Math.abs(beforechess[0] - curchess[0]) == 1) {
					ifflag = 1;
				}
			}
		}
		// 車的走法
		else if (who == 1 | who == 11) {
			if (beforechess[0] == curchess[0] | beforechess[1] == curchess[1]) {
				if (findnumb(beforechess[0], beforechess[1], curchess[0], curchess[1]) == 0) {
					ifflag = 1;
				}
			}
		}
		// 马的走法
		else if (who == 2 | who == 22) {
			if(beforechess[0] > 0) {
				if (beforechess[0] - curchess[0] == 2 & Math.abs(beforechess[1] - curchess[1]) == 1
						& flag[beforechess[0] - 1][beforechess[1]] == 0) {
					ifflag = 1;// 向上走日
				}
			}
			if(beforechess[0] < 9) {
				if (beforechess[0] - curchess[0] == -2 & Math.abs(beforechess[1] - curchess[1]) == 1
						& flag[beforechess[0] + 1][beforechess[1]] == 0) {
					ifflag = 1;// 向下走日
				}
			}
			if(beforechess[1] < 8) {
				if (beforechess[1] - curchess[1] == -2 & Math.abs(beforechess[0] - curchess[0]) == 1
						& flag[beforechess[0]][beforechess[1] + 1] == 0) {
					ifflag = 1;// 向右走日
				}
			}
			if(beforechess[1] > 0) {
				if (beforechess[1] - curchess[1] == 2 & Math.abs(beforechess[0] - curchess[0]) == 1
						& flag[beforechess[0]][beforechess[1] - 1] == 0) {
					ifflag = 1;// 向左走日
				}
			}
		}
		// 象的走法
		else if (who == 3 | who == 33) {
			if(beforechess[0] > 0&beforechess[1] > 0) {
				if (beforechess[0] - curchess[0] == 2 & beforechess[1] - curchess[1] == 2
						& flag[beforechess[0] - 1][beforechess[1] - 1] == 0) {
					ifflag = 1;// 向左上角走田
				}
			}
			if(beforechess[0] < 9&beforechess[1]  > 0) {
				if (beforechess[0] - curchess[0] == -2 & beforechess[1] - curchess[1] == 2
						& flag[beforechess[0] + 1][beforechess[1] - 1] == 0) {
					ifflag = 1;// 向左下角走田
				}
			}
			if(beforechess[0] > 0&beforechess[1] < 8) {
				if (beforechess[0] - curchess[0] == 2 & beforechess[1] - curchess[1] == -2
						& flag[beforechess[0] - 1][beforechess[1] + 1] == 0) {
					ifflag = 1;// 向右上角走田
				}
			}
			if(beforechess[0] < 9&beforechess[1] < 8) {
				if (beforechess[0] - curchess[0] == -2 & beforechess[1] - curchess[1] == -2
						& flag[beforechess[0] + 1][beforechess[1] + 1] == 0) {
					ifflag = 1;// 向右下角走田
				}
			}
		}
		// 士的走法
		else if (who == 4) {
			if (r < 3 & c < 6 & c > 2) {
				if(Math.abs(beforechess[1] - curchess[1])==1 & Math.abs(beforechess[0] - curchess[0])==1) {
					ifflag = 1;
				}
			}
		}
		// 仕的走法
		else if(who == 44) {
			if (r > 6 & c < 6 & c > 2) {
				if(Math.abs(beforechess[1] - curchess[1])==1 & Math.abs(beforechess[0] - curchess[0])==1) {
					ifflag = 1;
				}
			}
		}
		// 炮的走法
		else if(who == 6|who == 66) {
			if (beforechess[0] == curchess[0] | beforechess[1] == curchess[1]) {
				if (findnumb(beforechess[0], beforechess[1], curchess[0], curchess[1]) == 1&curchess[2]!=0|findnumb(beforechess[0], beforechess[1], curchess[0], curchess[1]) == 0&curchess[2]==0) {
					ifflag = 1;
				}
			}
		}
		// 卒的走法
		else if(who == 7) {
			if(beforechess[0]<5&beforechess[1]==curchess[1]&beforechess[0]-curchess[0]==-1|beforechess[0]>4&beforechess[1]==curchess[1]&beforechess[0]-curchess[0]==-1|beforechess[0]>4&beforechess[0]==curchess[0]&Math.abs(beforechess[1]-curchess[1])==1) {
				ifflag = 1;	
			}
		}
		// 兵的走法
		else if(who == 77) {
			if(beforechess[0]>4&beforechess[1]==curchess[1]&beforechess[0]-curchess[0]==1|beforechess[0]<5&beforechess[1]==curchess[1]&beforechess[0]-curchess[0]==1|beforechess[0]<5&beforechess[0]==curchess[0]&Math.abs(beforechess[1]-curchess[1])==1) {
				ifflag = 1;	
			}
		}
		System.out.println("ifflag="+ifflag);
		return ifflag;
	}

代码里的注释很详细,很容易就可以看懂。
输入的参数 w h o who who即选中的棋子的编号,返回值 i f f l a g ifflag ifflag用来判断是否可以移动,如果返回值为1,则可以移动;返回值为0,则不可以移动。

三、修改 mouseClicked() 方法

整个棋子移动的核心就在此方法上,因之前没有考虑到移动规则,所以现在需要进行改动来使用之前写好的方法。改动后的代码如下

	public void mouseClicked(MouseEvent e) {
		System.out.println("点击");
		x1 = e.getX();
		y1 = e.getY();
		if (x1 > init.x0 - init.size / 2 && y1 > init.y0 - init.size / 2
				&& x1 < init.x0 + init.size / 2 + init.column * init.size
				&& y1 < init.y0 + init.row * init.size + init.size / 2) {
			x2 = ((x1 - init.x0 + init.size / 2) / init.size) * init.size + init.x0;
			y2 = ((y1 - init.y0 + init.size / 2) / init.size) * init.size + init.y0;
			// 当前点击的位置
			getcr();// 获得此时点击处的位置
			System.out.println("grtcr"+flag[r][c]);
			
			rebec();// 更新前一颗棋子
			ui.repaint();
			recurchess();
			if (r != -1) {
				if (curchess[2] == 0 & chessflag == 1 & beforechess[2] > 10 & ifwalk(beforechess[2]) == 1
						| curchess[2] == 0 & chessflag == 2 & beforechess[2] < 10 & ifwalk(beforechess[2]) == 1) {// 如果此时点的地方没有棋子,直接替换
					System.out.println("走空位");
					walk();
				} else if (beforechess[2] > 10 & curchess[2] < 10 & chessflag == 1 & flag[r][c] < 10
						& ifwalk(beforechess[2]) == 1) {
					if (curchess[2] != 0) {// 如果手中有棋子
						System.out.println("红棋吃黑棋");
						walk();
					}
				} else if (beforechess[2] < 10 & curchess[2] > 10 & beforechess[2] > 0 & chessflag == 2
						& flag[r][c] > 10 & ifwalk(beforechess[2]) == 1) {
					if (curchess[2] != 0) {// 如果手中有棋子
						System.out.println("黑棋吃红棋");
						walk();
					}
				}
			}
		}
	}

在移动的判断上添加 i f w a l k ( ) ifwalk() ifwalk() 方法判断是否可以移动即可。

后记

现在我们实现了遵循规则地移动棋子,下一篇博客将会实现悔棋的功能,敬请期待。

关注微信公众号:图灵完备,回复中国象棋即可获得图片及代码资源。

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的JAVA实现中国象棋的代码示例: ```java //定义棋子类 class ChessPiece { String name; // 棋子名称 int x, y; // 棋子坐标 public ChessPiece(String name, int x, int y) { this.name = name; this.x = x; this.y = y; } public String toString() { return name + " (" + x + "," + y + ")"; } } //定义棋盘类 class ChessBoard { ChessPiece[][] board; public ChessBoard() { board = new ChessPiece[10][9]; } // 初始化棋盘 public void init() { // 初始化黑方 board[0][0] = new ChessPiece("車", 0, 0); board[0][1] = new ChessPiece("馬", 0, 1); board[0][2] = new ChessPiece("象", 0, 2); board[0][3] = new ChessPiece("士", 0, 3); board[0][4] = new ChessPiece("將", 0, 4); board[0][5] = new ChessPiece("士", 0, 5); board[0][6] = new ChessPiece("象", 0, 6); board[0][7] = new ChessPiece("馬", 0, 7); board[0][8] = new ChessPiece("車", 0, 8); board[2][1] = new ChessPiece("炮", 2, 1); board[2][7] = new ChessPiece("炮", 2, 7); board[3][0] = new ChessPiece("卒", 3, 0); board[3][2] = new ChessPiece("卒", 3, 2); board[3][4] = new ChessPiece("卒", 3, 4); board[3][6] = new ChessPiece("卒", 3, 6); board[3][8] = new ChessPiece("卒", 3, 8); // 初始化红方 board[9][0] = new ChessPiece("車", 9, 0); board[9][1] = new ChessPiece("馬", 9, 1); board[9][2] = new ChessPiece("象", 9, 2); board[9][3] = new ChessPiece("士", 9, 3); board[9][4] = new ChessPiece("帥", 9, 4); board[9][5] = new ChessPiece("士", 9, 5); board[9][6] = new ChessPiece("象", 9, 6); board[9][7] = new ChessPiece("馬", 9, 7); board[9][8] = new ChessPiece("車", 9, 8); board[7][1] = new ChessPiece("炮", 7, 1); board[7][7] = new ChessPiece("炮", 7, 7); board[6][0] = new ChessPiece("兵", 6, 0); board[6][2] = new ChessPiece("兵", 6, 2); board[6][4] = new ChessPiece("兵", 6, 4); board[6][6] = new ChessPiece("兵", 6, 6); board[6][8] = new ChessPiece("兵", 6, 8); } // 打印棋盘 public void print() { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { if (board[i][j] != null) { System.out.print(board[i][j] + "\t"); } else { System.out.print("\t"); } } System.out.println(""); } } // 移动棋子 public void move(int startX, int startY, int endX, int endY) { ChessPiece piece = board[startX][startY]; board[startX][startY] = null; board[endX][endY] = piece; piece.x = endX; piece.y = endY; } } //测试类 public class ChessTest { public static void main(String[] args) { ChessBoard board = new ChessBoard(); board.init(); board.print(); board.move(3, 0, 4, 0); board.print(); } } ``` 以上代码是一个简单的实现,具体规则和完整实现可以根据需求进行扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值