📄 position.java
字号:
moves ++;
}
break;
}
sqDst += delta;
}
}
break;
case PIECE_ROOK:
for (int i = 0; i < 4; i ++) {
int delta = ROOK_DELTA[i];
int sqDst = sqSrc + delta;
while (IN_BOARD(sqDst)) {
int pcDst = squares[sqDst];
if (pcDst == 0) {
if (vls == null) {
mvs[moves] = MOVE(sqSrc, sqDst);
moves ++;
}
} else {
if ((pcDst & pcOppSide) != 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
if (vls != null) {
vls[moves] = MVV_LVA(pcDst, 5);
}
moves ++;
}
break;
}
sqDst += delta;
}
}
break;
case PIECE_BISHOP:
for (int i = 0; i < 4; i ++) {
int delta = BISHOP_DELTA[i];
int sqDst = sqSrc + delta;
while (IN_BOARD(sqDst)) {
int pcDst = squares[sqDst];
if (pcDst == 0) {
if (vls == null) {
mvs[moves] = MOVE(sqSrc, sqDst);
moves ++;
}
} else {
if ((pcDst & pcOppSide) != 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
if (vls != null) {
vls[moves] = MVV_LVA(pcDst, 3);
}
moves ++;
}
break;
}
sqDst += delta;
}
}
break;
case PIECE_KNIGHT:
for (int i = 0; i < 8; i ++) {
int sqDst = sqSrc + KNIGHT_DELTA[i];
if (!IN_BOARD(sqDst)) {
continue;
}
int pcDst = squares[sqDst];
if (vls == null) {
if ((pcDst & pcSelfSide) == 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
moves ++;
}
} else if ((pcDst & pcOppSide) != 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
vls[moves] = MVV_LVA(pcDst, 3);
moves ++;
}
}
break;
case PIECE_PAWN:
int delta = FORWARD_DELTA(sdPlayer);
int sqDst = sqSrc + delta;
if (vls == null) {
if (IN_BOARD(sqDst) && squares[sqDst] == 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
moves ++;
if (PAWN_INIT(sqSrc, sdPlayer)) {
sqDst += delta;
if (squares[sqDst] == 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
moves ++;
}
}
}
} else {
// PROMOTION -> Promotions are regarded as Capture Moves
if (PAWN_PROMOTION(sqDst, sdPlayer) && squares[sqDst] == 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
vls[moves] = MVV_LVA(PIECE_QUEEN, 1);
moves ++;
}
}
int sqTmp = sqSrc + delta;
for (int i = -1; i <= 1; i += 2) {
sqDst = sqTmp + i;
if (!IN_BOARD(sqDst)) {
continue;
}
int pcDst = squares[sqDst];
// EN-PASSANT -> En-passant considered
if (sqDst == enPassantSquare()) {
pcDst = squares[sqDst - delta];
}
if ((pcDst & pcOppSide) != 0) {
mvs[moves] = MOVE(sqSrc, sqDst);
if (vls != null) {
vls[moves] = MVV_LVA(pcDst, 1);
}
moves ++;
}
}
break;
}
}
return moves;
}
public boolean legalMove(int mv) {
int sqSrc = SRC(mv);
int pcSrc = squares[sqSrc];
int pcSelfSide = SIDE_TAG(sdPlayer);
if ((pcSrc & pcSelfSide) == 0) {
return false;
}
int sqDst = DST(mv);
int pcDst = squares[sqDst];
if ((pcDst & pcSelfSide) != 0) {
return false;
}
int pieceType = pcSrc - pcSelfSide;
switch (pieceType) {
case PIECE_KING:
if (KING_SPAN(sqSrc, sqDst)) {
return true;
}
// CASTLING -> Castling considered
int castling = CASTLING_TYPE(sdPlayer, sqSrc, sqDst);
return (CASTLING_KING_DST[castling] == sqDst && canCastling(castling));
case PIECE_KNIGHT:
return KNIGHT_SPAN(sqSrc, sqDst);
case PIECE_QUEEN:
case PIECE_ROOK:
case PIECE_BISHOP:
int delta;
switch (SAME_LINE(sqSrc, sqDst)) {
case DIFF_LINE:
return false;
case SAME_RANK:
if (pieceType == PIECE_BISHOP) {
return false;
}
delta = (sqDst < sqSrc ? -1 : 1);
break;
case SAME_FILE:
if (pieceType == PIECE_BISHOP) {
return false;
}
delta = (sqDst < sqSrc ? -16 : 16);
break;
case SAME_DIAG_A1H8:
if (pieceType == PIECE_ROOK) {
return false;
}
delta = (sqDst < sqSrc ? -15 : 15);
break;
case SAME_DIAG_A8H1:
if (pieceType == PIECE_ROOK) {
return false;
}
delta = (sqDst < sqSrc ? -17 : 17);
break;
default: // Never Occurs
throw new RuntimeException();
}
int sqTmp = sqSrc + delta;
while (sqTmp != sqDst) {
if (squares[sqTmp] > 0) {
return false;
}
sqTmp += delta;
}
return true;
case PIECE_PAWN:
delta = FORWARD_DELTA(sdPlayer);
sqTmp = sqSrc + delta;
// EN-PASSANT -> En-passant is a capture move but "pcDst != 0"
if (pcDst != 0 || sqDst == enPassantSquare()) {
return (sqDst == sqTmp - 1 || sqDst == sqTmp + 1);
}
return (sqDst == sqTmp || (sqDst == sqTmp + delta &&
PAWN_INIT(sqSrc, sdPlayer) && squares[sqTmp] == 0));
default:
return false;
}
}
public boolean checked() {
int pcSelfSide = SIDE_TAG(sdPlayer);
for (int sqSrc = 0; sqSrc < 128; sqSrc ++) {
if (squares[sqSrc] == pcSelfSide + PIECE_KING) {
return checked(sqSrc);
}
}
return false;
}
public boolean checked(int sqSrc) {
int pcOppSide = OPP_SIDE_TAG(sdPlayer);
int sqTmp = sqSrc + FORWARD_DELTA(sdPlayer);
for (int i = -1; i <= 1; i += 2) {
int sqDst = sqTmp + i;
if (IN_BOARD(sqDst) && squares[sqDst] == pcOppSide + PIECE_PAWN) {
return true;
}
}
for (int i = 0; i < 8; i ++) {
int sqDst = sqSrc + KING_DELTA[i];
if (IN_BOARD(sqDst) && squares[sqDst] == pcOppSide + PIECE_KING) {
return true;
}
}
for (int i = 0; i < 8; i ++) {
int sqDst = sqSrc + KNIGHT_DELTA[i];
if (IN_BOARD(sqDst) && squares[sqDst] == pcOppSide + PIECE_KNIGHT) {
return true;
}
}
for (int i = 0; i < 4; i ++) {
int delta = BISHOP_DELTA[i];
int sqDst = sqSrc + delta;
while (IN_BOARD(sqDst)) {
int pcDst = squares[sqDst];
if (pcDst > 0) {
if (pcDst == pcOppSide + PIECE_BISHOP || pcDst == pcOppSide + PIECE_QUEEN) {
return true;
}
break;
}
sqDst += delta;
}
}
for (int i = 0; i < 4; i ++) {
int delta = ROOK_DELTA[i];
int sqDst = sqSrc + delta;
while (IN_BOARD(sqDst)) {
int pcDst = squares[sqDst];
if (pcDst > 0) {
if (pcDst == pcOppSide + PIECE_ROOK || pcDst == pcOppSide + PIECE_QUEEN) {
return true;
}
break;
}
sqDst += delta;
}
}
return false;
}
public boolean isMate() {
int[] mvs = new int[MAX_GEN_MOVES];
int moves = generateAllMoves(mvs);
for (int i = 0; i < moves; i ++) {
if (makeMove(mvs[i])) {
undoMakeMove();
return false;
}
}
return true;
}
public int drawValue() {
return (distance & 1) == 0 ? -DRAW_VALUE : DRAW_VALUE;
}
public int checkmateValue() {
return distance - MATE_VALUE;
}
public int mateValue() {
return inCheck() ? checkmateValue() : drawValue();
}
public int material() {
return (sdPlayer == 0 ? vlWhite - vlBlack : vlBlack - vlWhite) + ADVANCED_VALUE;
}
public boolean nullOkay() {
return (sdPlayer == 0 ? vlWhite : vlBlack) > NULL_OKAY_MARGIN;
}
public boolean nullSafe() {
return (sdPlayer == 0 ? vlWhite : vlBlack) > NULL_SAFE_MARGIN;
}
public boolean isRep() {
return isRep(1);
}
public boolean isRep(int recur_) {
int recur = recur_;
boolean selfSide = false;
int index = moveNum - 1;
while (mvList[index] > 0 && pcList[index] == 0) {
if (selfSide) {
if (keyList[index] == zobristKey) {
recur --;
if (recur == 0) {
return true;
}
}
}
selfSide = !selfSide;
index --;
}
return false;
}
public int bookMove() {
if (bookSize == 0) {
return 0;
}
int lock = zobristLock >>> 1; // Convert into Unsigned
int index = Util.binarySearch(lock, bookLock, 0, bookSize);
if (index < 0) {
return 0;
}
index --;
while (index >= 0 && bookLock[index] == lock) {
index --;
}
int[] mvs = new int[MAX_GEN_MOVES];
int[] vls = new int[MAX_GEN_MOVES];
int value = 0;
int moves = 0;
index ++;
while (index < bookSize && bookLock[index] == lock) {
int mv = 0xffff & bookMove[index];
if (legalMove(mv)) {
mvs[moves] = mv;
vls[moves] = bookValue[index];
value += vls[moves];
moves ++;
if (moves == MAX_GEN_MOVES) {
break;
}
}
index ++;
}
if (value == 0) {
return 0;
}
value = Math.abs(random.nextInt()) % value;
for (index = 0; index < moves; index ++) {
value -= vls[index];
if (value < 0) {
break;
}
}
return mvs[index];
}
public int historyIndex(int mv) {
return ((squares[SRC(mv)] - 8) << 7) + DST(mv);
}
public void printBoard() {
printBoard(System.out);
}
public void printBoard(PrintStream out) {
for (int y = Position.RANK_TOP; y <= Position.RANK_BOTTOM; y ++) {
out.print((char) ('8' - y));
out.print('|');
for (int x = Position.FILE_LEFT; x <= Position.FILE_RIGHT; x ++) {
int pc = squares[Position.COORD_XY(x, y)];
if (pc > 0) {
if (pc < 16) {
out.print(PIECE_STRING.charAt(pc - 8));
} else {
out.print((char) (PIECE_STRING.charAt(pc - 16) - 'A' + 'a'));
}
} else {
out.print('.');
}
out.print(' ');
}
out.println();
}
out.println(" +----------------");
out.println(" a b c d e f g h");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -