當(dāng)前位置:首頁(yè) > IT技術(shù) > 編程語(yǔ)言 > 正文

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


前言

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

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

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

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

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

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

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

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

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

三、修改 mouseClicked() 方法

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

public void mouseClicked(MouseEvent e) {
System.out.println("點(diǎn)擊");
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;
// 當(dāng)前點(diǎn)擊的位置
getcr();// 獲得此時(shí)點(diǎn)擊處的位置
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) {// 如果此時(shí)點(diǎn)的地方?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();
}
}
}
}
}

在移動(dòng)的判斷上添加 i f w a l k ( ) ifwalk() ifwalk() 方法判斷是否可以移動(dòng)即可。

后記

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

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


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

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