栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java游戏实战chess-3.Piece类之knight

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java游戏实战chess-3.Piece类之knight

一.Piece类

Piece代表棋子类,每一枚棋子都有对应的位置坐标和对应的阵营(Alliance)(黑子或者白子)。
我们需要限制棋子的移动位置,限制因素有很多,比如它所属阵营,它的本身属性,移动的位置处是否有其他子占用等等。所以我们需要定义棋子的合法移动抽象方法(calculateLegalMoves)来计算合法移动。

public class abstract Piece{
	protected final int piecePosition;
	protected final Alliance pieceAlliance; //导入枚举类型Alliance
	Piece(final int piecePosition, final ALLiance pieceAlliance) {
		this.pieceAlliance = pieceAlliance;
		this.piecePosition = piecePosition;
	}
	public Alliance getPieceAlliance(){
		return this.pieceAlliance;
	}
	public abstract List calculateLegalMoves(final Board board);
}
public enum Alliance {
	WHITE,
	BLACK;
}
二.Knight类

Knight是骑士,即为棋子马。它的走法规则如图所示:

例如这个棋盘,骑士的位置在棋盘的位置坐标是d4。它的合法位置分别是c6,e6,b5,f5,b3,c2,e2,f3,一共八个坐标。我们的算法是将棋盘映射到格子编号,第一行从左往右数分别是0,1,2,3,4,5,6,7,对应的骑士位置即为35,其中合法位置f5即为29。但是我们还需要考虑两种情况:第一种是合法位置被敌方占据从而变成不合法位置,第二种合法位置超出棋盘范围(例如骑士在b8,它的合法位置只有一个为d7。考虑到整个棋盘的对称性,我们把当前骑士的位置编号记为0,从右向左编号依次增大。所有的合法位置编号即为:-17,-15,-10,-6,6,10,15,17。
然后循环遍历所有偏移位置,候选目的地坐标等于当前位置加上偏移量。循环过程中需要加入判断,除去那些不在棋盘内的候选目的地坐标,还需判断候选目的地坐标受否被其他棋子占用。
最后我们需要考虑边缘情况,

public class Knight extends Piece {
	private final static int[] CANDIDATE_MOVE_COORDINATES = {-17,-15,-10,-6,6,10,15,17}//候选的合法位置编号列表(编号为相对于当前位置的偏移量)
	Knight(final int piecePosition, final Alliance pieceAlliance){
		super(piecePosition,pieceAlliance);
	}
	@Override
	public ListcalculateLegalMoves(Board board){
		int candidateDestinationCoorainate; //候选目的地坐标
		final List legalMoves = new ArratList<>();
		for(final int currentCandidate : CANDIDATE_MOVE_COORDINATES) { //for循环依次筛选列表中的位置是否真正合法
			candidateDestinationCoorainate = this.piecePosition + currentCandidate; //目标位置是当前位置加上偏移量
			//如果是有效的位置
			if(isValidTileCoordinate(candidateDestination)){
				final Tile candidateDestinationTile = board.getTile(candidateDestinationCoordinate);//目标位置和所选的位置一致
				if(!candidateDestinationTile.isTileOccupied()){//所选的位置没有被棋子占领
					legalMoves.add(new Move());//Move类,后续会提到
				}
				//如果选中的位置被占领
				else{
					final Piece pieceAtDestination = candidateDestinationTile.getPiece();
					final Alliance pieceAlliance = pieceAtDestination.getPieceAlliance();
					if(this.pieceAlliance != pieceAlliance){//判断是否为敌方占领该位置
						legalMoves.add(new Move());
					}
				}
			}
		}
		return ImmutableList.copyOf(legalMoves);
	}

将判断是否超出棋盘范围重构到BoardUtils类中:

public class BoardUtils{
	public static final boolean[] FIRST_COLUMN = null;
	//抛出运行时异常,防止被实例化
	private BoardUtils(){
		throw new 
	private boolean isValidTileCoordinate(int coordinate){ //是否超出棋盘
		return coordinate >=0 && coordinate < 64;
	}
}

判断骑士的合法位置这种算法其实可以用到所有棋子上,只需要按照游戏的规则将不同编号的格子放到列表中。需要充分考虑边界合法问题以及是否被其他棋子占领,若敌方棋子占领需要考虑是否进行攻击吃掉对方棋子自己独自占领目标位置。
由于代码量比较多,只是放了部分关键代码,后期还会不断完善修正。

原视频出处

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/736547.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号