⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 activeboard.java

📁 用jav语言开发的基于J2SE平台的中国象棋.供大家参考和学习
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package chinesechess.engine;

import java.io.Serializable;
import java.util.ArrayList;

public class ActiveBoard implements Serializable{
	//Rank[x],File[x],Bottom[x] 比 x % 10,x / 10,x * 10运算快
	public static final int[] RANK = {// File[19]=1,Rank[19]=9;
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9
	};

	public static final int FILE[] = {// File[12]=1,Rank[12]=2;
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
		4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
		5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
		6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
		7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
		8, 8, 8, 8, 8, 8, 8, 8, 8, 8
	};

	public static final int[] BOTTOM = {
		0, 10, 20, 30, 40, 50, 60, 70, 80
	};

	public static final int[] HORSE_LEG_TABLE = {//int 
		-10,  0,-10,  0,  0,  0,  0,  0,  0, -1,  0,  
		  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,
		  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,
		  1,  0,  0,  0,  0,  0,  0,	10,  0, 10
		//Move.Dst - Move.Src={-21,-19,-12,-8,8,12,19,21}
		//HorseLeg[Dst-Src+21]={-10,-10,-1,1,-1,,1,10,10}:蹩马腿的增量
		//Legal Move: return Squares[Move.Src + HorseLegTab[Move.Dst - Move.Src + 21]]==0
	};

	public static final int[] PIECE_TYPES = {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6,
		7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 13
	};
	public final static int MAX_MOVE_NUM = 256;
	public final static int LOOP_HASH_MASK = 0x3ff;
	public final static int MAX_CONSECUTIVE_MOVES = 200;

	private int player; // 0 = Red(White) and 1 = Black
	private int[] evalue;//int[2]Total Value of Red(0)/Black(1) Pieces
	private int[] squares;//int[90]Piece Indexes of each square, Squares[i] = 0:Unoccupied, 16-31:Red, 32-47 = Black
	private int[] pieces;//int[48]Square Indexes of each piece, -1 = Captured//被吃了
	// Square[x]=y(y: index of PieceTypes in Square[x]),
	// Pieces[y]=x(y is the pieceType, x represent pieceType Y in Square 5),
	// x:index of location in board(0~89)
	private int[] bitFiles;//[9]方便按行位纵线查询BitFiles[1]表示第1列(b纵线)上的棋子
	private int[] bitRanks;//[10]方便按列位横线查询
	private BitBoard[] pieceBits;//[14]分兵种及红黑的棋子位棋盘
	private BitBoard allPieces;//整个棋盘

	// Zobrist Key and Lock
	private long zobristKey, zobristLock;
	
	// History MoveNodes,用来作为循环重复检测
	private int moveNum;
	MoveNode[] moveList;//[ChessStruct.MaxMoveNum];
	char[] loopHash;//[LoopHashMask + 1];
	
	public ActiveBoard() {
		int i;
		player = 0;
		evalue = new int[2];
		evalue[0] = evalue[1] = 0;
		squares = new int[90];
		for (i = 0; i < 90; i ++) {
			squares[i] = 0;
		}
		pieces = new int[48];
		for (i = 16; i < 48; i ++) {
			pieces[i] = -1;
		}
		bitFiles = new int[9];
		for (i = 0; i < 9; i ++) {
			bitFiles[i] = 0;
		}
		bitRanks = new int[10];
		for (i = 0; i < 10; i ++) {
			bitRanks[i] = 0;
		}
		pieceBits = new BitBoard[14];
		for (i = 0; i < 14; i ++) {
			pieceBits[i] = new BitBoard(0);
		}
		allPieces = new BitBoard(0);
		zobristKey = zobristLock = 0;
		moveNum = 1;
		moveList = new MoveNode[MAX_MOVE_NUM];
		for (i = 0;i< MAX_MOVE_NUM;i++){
			moveList[i]=new MoveNode();
		}
		loopHash=new char[LOOP_HASH_MASK+1];
		for (i = 0; i < LOOP_HASH_MASK+1; i ++) {
			loopHash[i] = 0;
		}
	}
	private void changeSide() {
		player = 1 - player;
		zobristKey ^= PreMoveNodesGen.ZobristKeyPlayer;
		zobristLock ^= PreMoveNodesGen.ZobristLockPlayer;
	}
	private void clearSquare(int Square) {
		int Piece;
		Piece = squares[Square];
		squares[Square] = 0;
		pieces[Piece] = -1;
		changePiece(Square, Piece);
	}
	private void clearPiece(int Piece) {
		int Square;
		Square = pieces[Piece];
		squares[Square] = 0;
		pieces[Piece] = -1;
		changePiece(Square, Piece);
	}
	private void setPiece(int Square, int Piece) {
		squares[Square] = Piece;
		pieces[Piece] = Square;
		changePiece(Square, Piece, true);
	}
	public void nullMove() {
		MoveNode ThisMove=new MoveNode();
		changeSide();
		ThisMove.src = ThisMove.dst = ThisMove.cap = -1;
		ThisMove.chk = false;
		moveList[moveNum] = ThisMove;
		moveNum ++;
	}
	public void undoNull() {
		moveNum --;
		changeSide();
	}
	// Move Detection Procedures
	public boolean narrowCap(MoveNode Move){
		return narrowCap(Move,false);
	}
	public boolean narrowCap(MoveNode Move, boolean AdvisorBishop){//是否吃子
		int Captured;
		//Move.Dst=00010001 or 00010010:red仕相
		//Move.Dst=00100010 or 00100010:black士象
		//>00010010 or >00100010:其他棋子
		Captured = squares[Move.dst] & 0xf;
		if (Captured > 10) {
			Captured = RANK[Move.dst];
			return (player!=0) ? (Captured >= 5) : (Captured <= 4);
		} else {
			return AdvisorBishop || Captured > 4;
		}
	}
	public MoveNode lastMove(){
		return moveList[moveNum - 1];
	}
	public int evaluation() {
		return evalue[player] - evalue[1 - player];
	}
	private void changePiece(int Square, int Piece){
		changePiece(Square,Piece,false);
	}
	private void changePiece(int Square, int Piece, boolean IsAdd) {
		int x, y, PieceType, Side, Value;
		allPieces.assignXor(PreMoveNodesGen.BitMask[Square]);
		x = FILE[Square];
		y = RANK[Square];
		bitFiles[x] ^= 1 << y;
		bitRanks[y] ^= 1 << x;
		PieceType = PIECE_TYPES[Piece];
		pieceBits[PieceType].assignXor(PreMoveNodesGen.BitMask[Square]);
		zobristKey ^= PreMoveNodesGen.ZobristKeyTable[PieceType][Square];
		zobristLock ^= PreMoveNodesGen.ZobristLockTable[PieceType][Square];
		if (PieceType < 7) {
			Side = 0;
			Value = CCEvalue.BasicValues[PieceType] + CCEvalue.PosValues[PieceType][Square];
		} else {
			Side = 1;
			Value = CCEvalue.BasicValues[PieceType - 7] + CCEvalue.PosValues[PieceType - 7][89 - Square];
		}
		if (IsAdd) {
			evalue[Side] += Value;
		} else {
			evalue[Side] -= Value;
		}
	}
	public boolean movePiece(MoveNode Move){
		int Moved, Captured;
		MoveNode ThisMove;
		long OldZobristKey;
		if (Move.src<0 || Move.dst<0) return false;//add for search function
		OldZobristKey = zobristKey;
		Moved = squares[Move.src];
		Captured = squares[Move.dst];
		if (Captured!=0) {
			clearSquare(Move.dst);
		}
		clearSquare(Move.src);
		setPiece(Move.dst, Moved);
		if (checked(player)) {
			Moved = squares[Move.dst];
			clearSquare(Move.dst);
			setPiece(Move.src, Moved);
			if (Captured!=0) {
				setPiece(Move.dst, Captured);
			}
			return false;
		} else {
			if (loopHash[(int) (OldZobristKey & LOOP_HASH_MASK)]==0) {
				loopHash[(int) (OldZobristKey & LOOP_HASH_MASK)] = (char) moveNum;
			}
			changeSide();
			ThisMove = Move;
			ThisMove.cap = Captured;
			ThisMove.chk = checked(player);
			moveList[moveNum] = ThisMove;
			moveNum ++;
			return true;
		}
	}
	public void undoMove() {
		int Moved;
		MoveNode ThisMove;
		moveNum --;
		ThisMove = moveList[moveNum];
		Moved = squares[ThisMove.dst];
		clearSquare(ThisMove.dst);
		setPiece(ThisMove.src, Moved);
		if (ThisMove.cap!=0) {
			setPiece(ThisMove.dst, ThisMove.cap);
		}
		changeSide();
		if (loopHash[(int) (zobristKey & LOOP_HASH_MASK)] == moveNum) {
			loopHash[(int) (zobristKey & LOOP_HASH_MASK)] = 0;
		}
	}

	//	Leagal Move Detection Procedures
	public boolean leagalMove(MoveNode Move){
		int Piece, Attack, x, y, BitWord;
		Piece = squares[Move.src];
		if ((Piece & (player!=0 ? 32 : 16))==0) {
			return false;//所选的棋子是否是当前Player的
		}
		Attack = squares[Move.dst];
		if ((Attack & (player!=0 ? 32 : 16))!=0) {
			return false;//所吃的棋子是否是对方的
		}
		switch (PIECE_TYPES[Piece] - (player!=0 ? 7 : 0)) {
		case 5://炮,吃子时中间要有炮架
			x = FILE[Move.src];
			y = RANK[Move.src];
			if (x == FILE[Move.dst]) {//进退
				BitWord = bitFiles[x];
				if (Move.src < Move.dst) {//进
					if ((Attack & (player!=0 ? 16 : 32))!=0) {//吃子
						return Move.dst == PreMoveNodesGen.FileCannonCapMax[y][BitWord] + BOTTOM[x];
					} else {//不吃子
						return Move.dst <= PreMoveNodesGen.FileNonCapMax[y][BitWord] + BOTTOM[x];
					}
				} else {//Move.Src > Move.Dst,退
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.FileCannonCapMin[y][BitWord] + BOTTOM[x];
					} else {
						return Move.dst >= PreMoveNodesGen.FileNonCapMin[y][BitWord] + BOTTOM[x];
					}
				}
			} else {//平
				BitWord = bitRanks[y];
				if (Move.src < Move.dst) {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.RankCannonCapMax[x][BitWord] + y;
					} else {
						return Move.dst <= PreMoveNodesGen.RankNonCapMax[x][BitWord] + y;
					}
				} else {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.RankCannonCapMin[x][BitWord] + y;
					} else {
						return Move.dst >= PreMoveNodesGen.RankNonCapMin[x][BitWord] + y;
					}
				}
			}
		case 4://车,吃子时,中间不能有间隔
			x = FILE[Move.src];
			y = RANK[Move.src];
			if (x == FILE[Move.dst]) {
				BitWord = bitFiles[x];
				if (Move.src < Move.dst) {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.FileRookCapMax[y][BitWord] + BOTTOM[x];
					} else {
						return Move.dst <= PreMoveNodesGen.FileNonCapMax[y][BitWord] + BOTTOM[x];
					}
				} else {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.FileRookCapMin[y][BitWord] + BOTTOM[x];
					} else {
						return Move.dst >= PreMoveNodesGen.FileNonCapMin[y][BitWord] + BOTTOM[x];
					}
				}
			} else {
				BitWord = bitRanks[y];
				if (Move.src < Move.dst) {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.RankRookCapMax[x][BitWord] + y;
					} else {
						return Move.dst <= PreMoveNodesGen.RankNonCapMax[x][BitWord] + y;
					}
				} else {
					if ((Attack & (player!=0 ? 16 : 32))!=0) {
						return Move.dst == PreMoveNodesGen.RankRookCapMin[x][BitWord] + y;
					} else {
						return Move.dst >= PreMoveNodesGen.RankNonCapMin[x][BitWord] + y;
					}
				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -