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 分别为开始位置的行列数和点击位置的行列数,返回的 n u m b 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 即选中的棋子的编号,返回值 i f f l a g 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() 方法判断是否可以移动即可。

后记

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

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

猜你喜欢

转载自blog.csdn.net/weixin_44547562/article/details/103446237
今日推荐