當前位置:首頁 > IT技術(shù) > 編程語言 > 正文

java實現(xiàn)中國象棋3:走棋規(guī)則的實現(xiàn)
2021-12-01 23:07:31


前言

之前我們已經(jīng)實現(xiàn)了棋子的移動,但是可以發(fā)現(xiàn)棋子可以任意移動,不遵循中國象棋的規(guī)則,這篇博客便是為了實現(xiàn)中國象棋的走棋規(guī)則。在這里默認大家都已經(jīng)知道中國象棋走棋的規(guī)則,如果不知道請自行百度學習。

一、設(shè)計 findnumb() 方法

此方法用來找出開始位置和點擊位置在一條直線上時中間的棋子數(shù)目,用來判斷炮和車(車)是否可以移動。代碼如下:

// 找到某一起點到終點中含有的棋子數(shù)
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分別為開始位置的行列數(shù)和點擊位置的行列數(shù),返回的 n u m b numb numb為直線上的棋子數(shù)。

二、設(shè)計 ifwalk() 方法

ifwalk() 方法判斷選中的棋子是否可以移動到現(xiàn)在選擇的位置,根據(jù)中國象棋的走棋規(guī)則,可以很容易地寫出以下代碼。

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;
}

代碼里的注釋很詳細,很容易就可以看懂。

輸入的參數(shù) w h o who who即選中的棋子的編號,返回值 i f f l a g ifflag ifflag用來判斷是否可以移動,如果返回值為1,則可以移動;返回值為0,則不可以移動。

三、修改 mouseClicked() 方法

整個棋子移動的核心就在此方法上,因之前沒有考慮到移動規(guī)則,所以現(xiàn)在需要進行改動來使用之前寫好的方法。改動后的代碼如下

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) {// 如果此時點的地方?jīng)]有棋子,直接替換
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() 方法判斷是否可以移動即可。

后記

現(xiàn)在我們實現(xiàn)了遵循規(guī)則地移動棋子,下一篇博客將會實現(xiàn)悔棋的功能,敬請期待。

關(guān)注微信公眾號:圖靈完備,回復中國象棋即可獲得圖片及代碼資源。


本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >