各个棋子的走子规则

javafx象棋 java象棋编写_javafx象棋

自己基本上写完了整个程序,可能会有小问题,没有时间也不准备看了。上传到了github的18845143731的用户里,需要的可以自己看看

下面是“兵”这个类里的重写的setLocation方法:

@Override
	public void setLocation(int setsimX, int setsimY) {
		// TODO Auto-generated method stub
		
		if((CurrentsimY<5 && (setsimY-CurrentsimY)==1) || 
		(CurrentsimY>=5 && ((setsimY-CurrentsimY)==1||(setsimX-CurrentsimX)==-1||(setsimX-CurrentsimX)==1))) {
			Data.panelArray[CurrentsimX][CurrentsimY] = 0;
			Data.panelArray[setsimX][setsimY] = 1;
			this.CurrentsimX = setsimX;
			this.CurrentsimY = setsimY;
			Data.selectPiece = null;
			Data.BorRRun = !Data.BorRRun;
			this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
		}
		else {
			this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
		}				
	}

判断语句中的条件,就是用来约束它的。“兵”在过河之前是不能左右走的,也不能后退,只能向前。以棋盘的左上角为原点,棋子当前的横坐标为CurrentX纵坐标为CurrentY。所以当Y<5时,也就是没过河时,只有setsimY-CurrentY==1时,也就是向前走一步时,才会执行下面的move操作。而当Y>=5时,也就是过河后,有(setsimY-CurrentsimY)==1||(setsimX-CurrentsimX)==-1||(setsimX-CurrentsimX)==1),也就是可以向前和向左向右。“兵”的判断操作也是类似额。

下面是“将”这个类里的重写的setLocation方法:

@Override
	public void setLocation(int setsimX, int setsimY) {
		// TODO Auto-generated method stub
		
		if(setsimX>2&&setsimX<6&&setsimY<3) {
			if(setsimX+setsimY-CurrentsimX-CurrentsimY == 1 || setsimX+setsimY-CurrentsimX-CurrentsimY == -1) {
				Data.panelArray[CurrentsimX][CurrentsimY] = 0;
				Data.panelArray[setsimX][setsimY] = 1;
				this.CurrentsimX = setsimX;
				this.CurrentsimY = setsimY;
				Data.selectPiece = null;
				Data.BorRRun = !Data.BorRRun;
				this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
			}
			else {
				this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
			}				
		}
	}

因为“将”不能出那个田字格,所以可以先加一个if(setsimX>2&&setsimX<6&&setsimY<3)来限制它。下面的那个if里面setsimX+setsimY-CurrentsimX-CurrentsimY == 1||...很容易理解嘛,就是只能走到邻近的一个格子的限制嘛。

下面是“士”这个类里的重写的setLocation方法:

if(setsimX>2&&setsimX<6&&setsimY<3) {
			if(setsimX==CurrentsimX-1&&setsimY==CurrentsimY+1 || setsimX==CurrentsimX+1&&setsimY==CurrentsimY+1
			  || setsimX==CurrentsimX+1&&setsimY==CurrentsimY-1 || setsimX==CurrentsimX-1&&setsimY==CurrentsimY-1) {
				Data.panelArray[CurrentsimX][CurrentsimY] = 0;
				Data.panelArray[setsimX][setsimY] = 1;
				this.CurrentsimX = setsimX;
				this.CurrentsimY = setsimY;
				Data.selectPiece = null;
				Data.BorRRun = !Data.BorRRun;
				this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
			}
			else {
				this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
			}				
		}
	}

“士”和将有点类似,先设置一下不能出那个田字格。然后把它向左上左下右上右下的四种情况用“或”连起来就好。

下面是“象”这个类里的重写的setLocation方法:

@Override
	public void setLocation(int setsimX, int setsimY) {
		
		// TODO Auto-generated method stub
		if(setsimY<5 && Data.panelArray[(CurrentsimX+setsimX)/2][(CurrentsimY+setsimY)/2]==0) {//别象脚和不能过河
			if(setsimX==CurrentsimX-2&&setsimY==CurrentsimY+2 || setsimX==CurrentsimX+2&&setsimY==CurrentsimY+2//象的走子规则
			  || setsimX==CurrentsimX+2&&setsimY==CurrentsimY-2 || setsimX==CurrentsimX-2&&setsimY==CurrentsimY-2) {
				Data.panelArray[CurrentsimX][CurrentsimY] = 0;
				Data.panelArray[setsimX][setsimY] = 1;
				this.CurrentsimX = setsimX;
				this.CurrentsimY = setsimY;
				Data.selectPiece = null;
				Data.BorRRun = !Data.BorRRun;
				this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
			}
		}
		else {
			this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
		}				
	}

“象”不可以过河,先用setsimY<5限制一下。再就是如果有别的棋子在“象”走的那个“田”子的中间的话,也是不可以的额,(我们叫塞象眼)。用Data.panelArray[(CurrentsimX+setsimX)/2][(CurrentsimY+setsimY)/2]==0就可以限制了。这里的Data.panelArray二维数组上次说过是记录整个棋盘各个地方有没有子的,有的话,那个地方的值被设为1,无则为0。(CurrentsimX+setsimX)/2就是“象”走的“田”求中间的那个地方的坐标额。再就是“象”走左上左下右上右下这几种情况,都列出来就好。

下面是“马”这个类里的重写的setLocation方法:

@Override
	public void setLocation(int setsimX, int setsimY) {
		// TODO Auto-generated method stub
		if(((setsimX-CurrentsimX==2 || setsimX-CurrentsimX==-2) && Data.panelArray[(CurrentsimX+setsimX)/2][CurrentsimY]==0)
		   ||((setsimY-CurrentsimY==2 || setsimY-CurrentsimY==-2) && Data.panelArray[CurrentsimX][(CurrentsimY+setsimY)/2]==0)) {
			if(setsimX==CurrentsimX+1&&setsimY==CurrentsimY+2 || setsimX==CurrentsimX+2&&setsimY==CurrentsimY+1
			  || setsimX==CurrentsimX-1&&setsimY==CurrentsimY-2 || setsimX==CurrentsimX-2&&setsimY==CurrentsimY-1
			  || setsimX==CurrentsimX-1&&setsimY==CurrentsimY+2 || setsimX==CurrentsimX-2&&setsimY==CurrentsimY+1
			  || setsimX==CurrentsimX+1&&setsimY==CurrentsimY-2 || setsimX==CurrentsimX+2&&setsimY==CurrentsimY-1) {
				Data.panelArray[CurrentsimX][CurrentsimY] = 0;
				Data.panelArray[setsimX][setsimY] = 1;
				this.CurrentsimX = setsimX;
				this.CurrentsimY = setsimY;
				Data.selectPiece = null;
				Data.BorRRun = !Data.BorRRun;
				this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
			}
		}
			else {
				this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
			}				
		
	}

本来因为觉得“马”可以过河,if里的限制应该可以简单点,但是好像不是这样的。外面的那一个if语句是别马腿(我就是这么叫的。。)的操作。分为横向走“日”和纵向走“日”的两种情况(setsimX-CurrentsimX==2 || setsimX-CurrentsimX==-2)就是判断它是横向走“日” 。Data.panelArray[(CurrentsimX+setsimX)/2][CurrentsimY]==0是判断“马腿”位置没有其他的棋子。
下面那个if语句是“马”的八种走子情况啦,可以自己数。感觉应该可以简化条件,太长了 。

下面是“车”这个类里的重写的setLocation方法:

public void setLocation(int setsimX, int setsimY) {
		// TODO Auto-generated method stub
			int BRflagX = 0;
			int BRflagY = 0;
			if(setsimX < CurrentsimX)
				for(int i=setsimX+1;i<CurrentsimX;i++)
					BRflagX = Data.panelArray[i][CurrentsimY] + BRflagX;
			else if(setsimX > CurrentsimX)
				for(int i=CurrentsimX+1;i<setsimX;i++)					
						BRflagX = Data.panelArray[i][CurrentsimY] + BRflagX;							
			if(setsimY < CurrentsimY)
				for(int i=setsimY+1;i<CurrentsimY;i++)
					BRflagY = Data.panelArray[CurrentsimX][i] + BRflagY;
			else if(setsimY > CurrentsimY)
				for(int i=CurrentsimY+1;i<setsimY;i++)
					BRflagY = Data.panelArray[CurrentsimX][i] + BRflagY;
			
			if(setsimX==CurrentsimX&&BRflagY==0 || setsimY==CurrentsimY&&BRflagX==0 ) {
				Data.panelArray[CurrentsimX][CurrentsimY] = 0;
				Data.panelArray[setsimX][setsimY] = 1;
				this.CurrentsimX = setsimX;
				this.CurrentsimY = setsimY;
				Data.selectPiece = null;
				Data.BorRRun = !Data.BorRRun;
				this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
			}
			else {
				this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
			}				

	}

这里“车”因为要判断走子起始位置和终点位置是否有其余的棋子,所以引入了BRflagX ``BRflagY两个量,分别对应“车”横着走和竖着走两种情况。先判断下起始位置和终点位置哪个坐标大,然后for循环把对应的Data.panelArray里面的数值加起来,如果中间没有其他棋子,BRflagX ``BRflagY就会等于0的。有其他子它们则不等于0。接下来用if(setsimX==CurrentsimX&&BRflagY==0 || setsimY==CurrentsimY&&BRflagX==0 )就既可以让“车”沿着直线走,又限制它在起点和终点有其他子的时候不可以走。下面的“炮”也有类似的限制。

下面是“炮”这个类里的重写的setLocation方法:

@Override
	public void setLocation(int setsimX, int setsimY) {
		// TODO Auto-generated method stub
		int BRflagX = 0;
		int BRflagY = 0;
		if(setsimX < CurrentsimX)//跟车的走子规则判断差不多,但是吃子的时候有点区别中间要隔一个子嘛
			for(int i=setsimX+1;i<CurrentsimX;i++)
				BRflagX = Data.panelArray[i][CurrentsimY] + BRflagX;
		else if(setsimX > CurrentsimX)
			for(int i=CurrentsimX+1;i<setsimX;i++)					
					BRflagX = Data.panelArray[i][CurrentsimY] + BRflagX;							
		if(setsimY < CurrentsimY)
			for(int i=setsimY+1;i<CurrentsimY;i++)
				BRflagY = Data.panelArray[CurrentsimX][i] + BRflagY;
		else if(setsimY > CurrentsimY)
			for(int i=CurrentsimY+1;i<setsimY;i++)
				BRflagY = Data.panelArray[CurrentsimX][i] + BRflagY;
			
		if((setsimX==CurrentsimX&&BRflagY==1 || setsimY==CurrentsimY&&BRflagX==1)&& Data.panelArray[setsimX][setsimY]==1 ) {//中间隔一个子时进行吃子操作
			Data.panelArray[CurrentsimX][CurrentsimY] = 0;
			Data.panelArray[setsimX][setsimY] = 1;
			this.CurrentsimX = setsimX;
			this.CurrentsimY = setsimY;
			Data.selectPiece = null;
			Data.BorRRun = !Data.BorRRun;
			this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
		}
		else if((setsimX==CurrentsimX&&BRflagY==0 || setsimY==CurrentsimY&&BRflagX==0)  && Data.panelArray[setsimX][setsimY]==0) {//中间没有子时代表正常的走子,panelArray=0时代表setXY没有子	
			Data.panelArray[CurrentsimX][CurrentsimY] = 0;
			Data.panelArray[setsimX][setsimY] = 1;
			this.CurrentsimX = setsimX;
			this.CurrentsimY = setsimY;
			Data.selectPiece = null;
			Data.BorRRun = !Data.BorRRun;
			this.move(Data.simnum2xy(setsimX),Data.simnum2xy(setsimY));
		}
		else {
			this.move(Data.simnum2xy(CurrentsimX),Data.simnum2xy(CurrentsimY));
		}				
		
	}

这个“炮”应该算是最复杂的了。最前面BRflagXBRflagY的操作与车一样。后面的分成了吃子和正常走子的两部分。因为吃敌方的子时,也只是把自己的子挪到了敌方子的位置上,然后把敌方的子设置成 不可见。所以吃子的时候也是会用到setLocation的方法的。
f((setsimX==CurrentsimX&&BRflagY==1 || setsimY==CurrentsimY&&BRflagX==1)&& Data.panelArray[setsimX][setsimY]==1 )BRflagX==1就是判断“炮”走的起始位置和终点位置相隔一个子,而Data.panelArray[setsimX][setsimY]==1是判断终点位置是有棋子的,不加这一句的话,炮可以直接隔着一个子跳到对面的地方。后面的正常的走子情况就是和“车”基本上一样了。