前言
之前我们已经实现了棋子的移动,但是可以发现棋子可以任意移动,不遵循中国象棋的规则,这篇博客便是为了实现中国象棋的走棋规则。在这里默认大家都已经知道中国象棋走棋的规则,如果不知道请自行百度学习。
一、设计 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() 方法判断是否可以移动即可。
后记
现在我们实现了遵循规则地移动棋子,下一篇博客将会实现悔棋的功能,敬请期待。
关注微信公众号:图灵完备,回复中国象棋即可获得图片及代码资源。