position.java
来自「J2ME编写的完整国际象棋程序」· Java 代码 · 共 1,200 行 · 第 1/3 页
JAVA
1,200 行
}
public void addPiece(int sq, int pc) {
addPiece(sq, pc, false);
}
public void delPiece(int sq, int pc) {
addPiece(sq, pc, true);
}
/* A - Take out Captured Piece (Different in En-Passant, see A-EP)
* B - Remove Source
* C - Add into Destination (Different in Promotion, see C-P)
* D - for Castling only
*/
public void movePiece() {
int sqSrc = SRC(mvList[moveNum]);
int sqDst = DST(mvList[moveNum]);
int pcCaptured = squares[sqDst];
if (pcCaptured > 0) {
delPiece(sqDst, pcCaptured); // A
}
int pc = squares[sqSrc];
// __ASSERT((pcCaptured & SIDE_TAG(sdPlayer)) == 0);
// __ASSERT((pc & SIDE_TAG(sdPlayer)) != 0);
delPiece(sqSrc, pc); // B
addPiece(sqDst, pc); // C
pcList[moveNum] = pcCaptured;
specialMoveList[moveNum] = false;
castlingBitsList[moveNum] = castlingBits();
sqEnPassantList[moveNum] = 0;
// CASTLING -> Set Castling Bits for Rook's Capture
if (PIECE_TYPE(pcCaptured) == PIECE_ROOK) {
int castling = (1 - sdPlayer) << 1;
if (sqDst == CASTLING_ROOK_SRC[castling]) {
castlingBitsList[moveNum] &= ~(1 << castling);
} else if (sqDst == CASTLING_ROOK_SRC[castling + 1]) {
castlingBitsList[moveNum] &= ~(1 << (castling + 1));
}
}
if (PIECE_TYPE(pc) == PIECE_KING) {
// CASTLING -> Move both King and Rook
if (!KING_SPAN(sqSrc, sqDst)) {
int castling = CASTLING_TYPE(sdPlayer, sqSrc, sqDst);
delPiece(CASTLING_ROOK_SRC[castling], pc - PIECE_KING + PIECE_ROOK); // D
addPiece(CASTLING_ROOK_DST[castling], pc - PIECE_KING + PIECE_ROOK); // D
specialMoveList[moveNum] = true;
}
// CASTLING -> Set Castling Bits for King's Move
castlingBitsList[moveNum] &= ~(3 << (sdPlayer << 1));
} else if (PIECE_TYPE(pc) == PIECE_PAWN) {
if (PAWN_PROMOTION(sqDst, sdPlayer)) {
// PROMOTION -> Add a Queen instead of a Pawn
delPiece(sqDst, pc); // C-P
addPiece(sqDst, pc - PIECE_PAWN + PIECE_QUEEN); // C-P
specialMoveList[moveNum] = true;
} else if (sqDst == enPassantSquare()) {
// EN-PASSANT -> Reset the Captured Piece for En-Passant Move
int sqCaptured = sqDst - FORWARD_DELTA(sdPlayer);
pcCaptured = squares[sqCaptured];
// __ASSERT(sqSrc == sqCaptured + 1 || sqSrc == sqCaptured - 1);
// __ASSERT(pcCaptured == OPP_SIDE_TAG(sdPlayer) + PIECE_PAWN);
delPiece(sqCaptured, pcCaptured); // A-EP
pcList[moveNum] = pcCaptured;
specialMoveList[moveNum] = true;
} else {
// EN-PASSANT -> Set En-Passant Square for Pawn's Double-Move
int delta = FORWARD_DELTA(sdPlayer);
if (sqDst == sqSrc + (delta << 1)) {
sqEnPassantList[moveNum] = sqSrc + delta;
}
}
} else if (PIECE_TYPE(pc) == PIECE_ROOK) {
// CASTLING -> Set Castling Bits for Rook's Move
int castling = sdPlayer << 1;
if (sqSrc == CASTLING_ROOK_SRC[castling]) {
castlingBitsList[moveNum] &= ~(1 << castling);
} else if (sqSrc == CASTLING_ROOK_SRC[castling + 1]) {
castlingBitsList[moveNum] &= ~(1 << (castling + 1));
}
}
}
/* A - Return Captured Piece (Different in En-Passant, see A-EP)
* B - Add into Source (Different in Promotion, see B-P)
* C - Remove Destination
* D - for Castling only
*/
public void undoMovePiece() {
int sqSrc = SRC(mvList[moveNum]);
int sqDst = DST(mvList[moveNum]);
int pc = squares[sqDst];
// __ASSERT((pcList[moveNum] & SIDE_TAG(sdPlayer)) == 0);
// __ASSERT((pc & SIDE_TAG(sdPlayer)) != 0);
delPiece(sqDst, pc); // C
addPiece(sqSrc, pc); // B
if (pcList[moveNum] > 0) {
addPiece(sqDst, pcList[moveNum]); // A
}
if (specialMoveList[moveNum]) {
if (PIECE_TYPE(pc) == PIECE_KING) {
// CASTLING -> Move both King and Rook
int castling = CASTLING_TYPE(sdPlayer, sqSrc, sqDst);
// __ASSERT((castlingBits() & (1 << castling)) != 0);
// __ASSERT(squares[CASTLING_ROOK_DST[castling]] == SIDE_TAG(sdPlayer) + PIECE_ROOK);
// __ASSERT(squares[CASTLING_ROOK_SRC[castling]] == 0);
delPiece(CASTLING_ROOK_DST[castling], pc - PIECE_KING + PIECE_ROOK); // D
addPiece(CASTLING_ROOK_SRC[castling], pc - PIECE_KING + PIECE_ROOK); // D
} else if (PAWN_PROMOTION(sqDst, sdPlayer)) {
// PROMOTION -> Add a Pawn instead of a Queen
// __ASSERT(pc == SIDE_TAG(sdPlayer) + PIECE_QUEEN);
delPiece(sqSrc, pc); // B-P
addPiece(sqSrc, pc - PIECE_QUEEN + PIECE_PAWN); // B-P
} else {
// __ASSERT(sqDst == enPassantSquare());
// EN-PASSANT -> Adjust the Captured Pawn
// __ASSERT(pcList[moveNum] == OPP_SIDE_TAG(sdPlayer) + PIECE_PAWN);
delPiece(sqDst, pcList[moveNum]); // A-EP
addPiece(sqDst - FORWARD_DELTA(sdPlayer), pcList[moveNum]); // A-EP
}
}
}
public void changeSide() {
sdPlayer = 1 - sdPlayer;
zobristKey ^= PreGen_zobristKeyPlayer;
zobristLock ^= PreGen_zobristLockPlayer;
}
public boolean makeMove(int mv) {
keyList[moveNum] = zobristKey;
mvList[moveNum] = mv;
movePiece();
if (checked()) {
undoMovePiece();
return false;
}
changeSide();
chkList[moveNum] = checked();
moveNum ++;
distance ++;
return true;
}
public void undoMakeMove() {
moveNum --;
distance --;
changeSide();
undoMovePiece();
}
public void nullMove() {
keyList[moveNum] = zobristKey;
changeSide();
mvList[moveNum] = pcList[moveNum] = sqEnPassantList[moveNum] = 0;
chkList[moveNum] = specialMoveList[moveNum] = false;
castlingBitsList[moveNum] = castlingBits();
moveNum ++;
distance ++;
}
public void undoNullMove() {
moveNum --;
distance --;
changeSide();
}
public int fenPiece(char c) {
switch (c) {
case 'K':
return PIECE_KING;
case 'Q':
return PIECE_QUEEN;
case 'R':
return PIECE_ROOK;
case 'B':
return PIECE_BISHOP;
case 'N':
return PIECE_KNIGHT;
case 'P':
return PIECE_PAWN;
default:
return -1;
}
}
public void fromFen(String fen) {
clearBoard();
int y = RANK_TOP;
int x = FILE_LEFT;
int index = 0;
if (index == fen.length()) {
setIrrev(0, 0);
return;
}
char c = fen.charAt(index);
while (c != ' ') {
if (c == '/') {
x = FILE_LEFT;
y ++;
if (y > RANK_BOTTOM) {
break;
}
} else if (c >= '1' && c <= '9') {
for (int k = 0; k < (c - '0'); k ++) {
if (x >= FILE_RIGHT) {
break;
}
x ++;
}
} else if (c >= 'A' && c <= 'Z') {
if (x <= FILE_RIGHT) {
if (c != 'P' || (y != RANK_TOP && y != RANK_BOTTOM)) {
int pt = fenPiece(c);
if (pt >= 0) {
addPiece(COORD_XY(x, y), pt + 8);
}
}
x ++;
}
} else if (c >= 'a' && c <= 'z') {
if (x <= FILE_RIGHT) {
if (c != 'p' || (y != RANK_TOP && y != RANK_BOTTOM)) {
int pt = fenPiece((char) (c + 'A' - 'a'));
if (pt >= 0) {
addPiece(COORD_XY(x, y), pt + 16);
}
}
x ++;
}
}
index ++;
if (index == fen.length()) {
setIrrev(0, 0);
return;
}
c = fen.charAt(index);
}
index ++;
if (index == fen.length()) {
setIrrev(0, 0);
return;
}
if (sdPlayer == (fen.charAt(index) == 'b' ? 0 : 1)) {
changeSide();
}
index ++; // Skip a ' '
if (index == fen.length()) {
setIrrev(0, 0);
return;
}
int castlingBits = 0;
index ++;
if (index == fen.length()) {
setIrrev(0, 0);
return;
}
c = fen.charAt(index);
while (c != ' ') {
switch (c) {
case 'K':
if (squares[0x78] == 8 && squares[0x7b] == 10) {
castlingBits += 1;
}
break;
case 'Q':
if (squares[0x78] == 8 && squares[0x74] == 10) {
castlingBits += 2;
}
break;
case 'k':
if (squares[0x08] == 16 && squares[0x0b] == 18) {
castlingBits += 4;
}
break;
case 'q':
if (squares[0x08] == 16 && squares[0x04] == 18) {
castlingBits += 8;
}
break;
}
index ++;
if (index == fen.length()) {
setIrrev(castlingBits, 0);
return;
}
c = fen.charAt(index);
}
int sqEnPassant = PARSE_COORD(fen, index + 1);
if (sqEnPassant > 0 && PAWN_EN_PASSANT(sqEnPassant, sdPlayer) &&
squares[sqEnPassant - FORWARD_DELTA(sdPlayer)] > 0) {
setIrrev(castlingBits, sqEnPassant);
} else {
setIrrev(castlingBits, 0);
}
}
public static final String FEN_PIECE = " KQRBNP kqrbnp ";
public static final String CASTLING_CHAR = "KQkq";
public String toFen() {
StringBuffer fen = new StringBuffer();
for (int y = RANK_TOP; y <= RANK_BOTTOM; y ++) {
int k = 0;
for (int x = FILE_LEFT; x <= FILE_RIGHT; x ++) {
int pc = squares[COORD_XY(x, y)];
if (pc > 0) {
if (k > 0) {
fen.append((char) ('0' + k));
k = 0;
}
fen.append(FEN_PIECE.charAt(pc));
} else {
k ++;
}
}
if (k > 0) {
fen.append((char) ('0' + k));
}
fen.append('/');
}
fen.setCharAt(fen.length() - 1, ' ');
fen.append(sdPlayer == 0 ? 'w' : 'b');
fen.append(' ');
int castlingBits = castlingBits();
if (castlingBits == 0) {
fen.append('-');
} else {
for (int castling = 0; castling < 4; castling ++) {
if ((castlingBits & (1 << castling)) != 0) {
fen.append(CASTLING_CHAR.charAt(castling));
}
}
}
fen.append(' ');
fen.append(enPassantSquare() > 0 ? SQUARE_STR(enPassantSquare()) : "-");
return fen.toString();
}
public int generateAllMoves(int[] mvs) {
return generateMoves(mvs, null);
}
public int generateMoves(int[] mvs, int[] vls) {
int moves = 0;
int pcSelfSide = SIDE_TAG(sdPlayer);
int pcOppSide = OPP_SIDE_TAG(sdPlayer);
// CASTLING -> Begin Generating Castling Moves
if (vls == null) {
for (int i = 0; i < 2; i ++) {
int castling = (sdPlayer << 1) + i;
if (canCastling(castling)) {
mvs[moves] = MOVE(CASTLING_KING_SRC[castling], CASTLING_KING_DST[castling]);
moves ++;
}
}
}
// CASTLING -> End Generating Castling Moves
for (int sqSrc = 0; sqSrc < 128; sqSrc ++) {
int pcSrc = squares[sqSrc];
if ((pcSrc & pcSelfSide) == 0) {
continue;
}
switch (pcSrc - pcSelfSide) {
case PIECE_KING:
for (int i = 0; i < 8; i ++) {
int sqDst = sqSrc + KING_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, 99);
moves ++;
}
}
break;
case PIECE_QUEEN:
for (int i = 0; i < 8; i ++) {
int delta = KING_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, 9);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?