?? activeboard.java
字號:
package org.acerge.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運(yùn)算快
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;//整個(gè)棋盤
// Zobrist Key and Lock
private long zobristKey, zobristLock;
// History MoveNodes,用來作為循環(huán)重復(fù)檢測
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;//所選的棋子是否是當(dāng)前Player的
}
Attack = squares[Move.dst];
if ((Attack & (player!=0 ? 32 : 16))!=0) {
return false;//所吃的棋子是否是對方的
}
switch (PIECE_TYPES[Piece] - (player!=0 ? 7 : 0)) {
case 5://炮,吃子時(shí)中間要有炮架
x = FILE[Move.src];
y = RANK[Move.src];
if (x == FILE[Move.dst]) {//進(jìn)退
BitWord = bitFiles[x];
if (Move.src < Move.dst) {//進(jìn)
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://車,吃子時(shí),中間不能有間隔
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;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -