mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-11 00:22:41 +01:00
DroidFish: Implemented DTZ/WDL tablebase hints in the GUI when only syzygy tablebases are available.
This commit is contained in:
211
DroidFish/jni/rtb/position.cpp
Normal file
211
DroidFish/jni/rtb/position.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
Texel - A UCI chess engine.
|
||||
Copyright (C) 2012-2014 Peter Österlund, peterosterlund2@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* position.cpp
|
||||
*
|
||||
* Created on: Feb 25, 2012
|
||||
* Author: petero
|
||||
*/
|
||||
|
||||
#include "position.hpp"
|
||||
|
||||
|
||||
Position::Position() {
|
||||
for (int i = 0; i < 64; i++)
|
||||
squares[i] = Piece::EMPTY;
|
||||
for (int i = 0; i < Piece::nPieceTypes; i++)
|
||||
pieceTypeBB_[i] = 0;
|
||||
whiteBB_ = blackBB_ = 0;
|
||||
whiteMove = true;
|
||||
castleMask = 0;
|
||||
epSquare = -1;
|
||||
halfMoveClock = 0;
|
||||
fullMoveCounter = 1;
|
||||
matId = {};
|
||||
for (int sq = 0; sq < 64; sq++) {
|
||||
int p = squares[sq];
|
||||
matId.addPiece(p);
|
||||
}
|
||||
wKingSq_ = bKingSq_ = -1;
|
||||
}
|
||||
|
||||
void
|
||||
Position::setPiece(int square, int piece) {
|
||||
int removedPiece = squares[square];
|
||||
squares[square] = piece;
|
||||
|
||||
// Update material identifier
|
||||
matId.removePiece(removedPiece);
|
||||
matId.addPiece(piece);
|
||||
|
||||
// Update bitboards
|
||||
const U64 sqMask = 1ULL << square;
|
||||
pieceTypeBB_[removedPiece] &= ~sqMask;
|
||||
pieceTypeBB_[piece] |= sqMask;
|
||||
|
||||
if (removedPiece != Piece::EMPTY) {
|
||||
if (Piece::isWhite(removedPiece)) {
|
||||
whiteBB_ &= ~sqMask;
|
||||
} else {
|
||||
blackBB_ &= ~sqMask;
|
||||
}
|
||||
}
|
||||
|
||||
if (piece != Piece::EMPTY) {
|
||||
if (Piece::isWhite(piece)) {
|
||||
whiteBB_ |= sqMask;
|
||||
if (piece == Piece::WKING)
|
||||
wKingSq_ = square;
|
||||
} else {
|
||||
blackBB_ |= sqMask;
|
||||
if (piece == Piece::BKING)
|
||||
bKingSq_ = square;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Position::makeMove(const Move& move, UndoInfo& ui) {
|
||||
ui.capturedPiece = squares[move.to()];
|
||||
ui.castleMask = castleMask;
|
||||
ui.epSquare = epSquare;
|
||||
ui.halfMoveClock = halfMoveClock;
|
||||
bool wtm = whiteMove;
|
||||
|
||||
const int p = squares[move.from()];
|
||||
int capP = squares[move.to()];
|
||||
U64 fromMask = 1ULL << move.from();
|
||||
|
||||
int prevEpSquare = epSquare;
|
||||
setEpSquare(-1);
|
||||
|
||||
if ((capP != Piece::EMPTY) || ((pieceTypeBB(Piece::WPAWN, Piece::BPAWN) & fromMask) != 0)) {
|
||||
halfMoveClock = 0;
|
||||
|
||||
// Handle en passant and epSquare
|
||||
if (p == Piece::WPAWN) {
|
||||
if (move.to() - move.from() == 2 * 8) {
|
||||
int x = getX(move.to());
|
||||
if (BitBoard::epMaskW[x] & pieceTypeBB(Piece::BPAWN))
|
||||
setEpSquare(move.from() + 8);
|
||||
} else if (move.to() == prevEpSquare) {
|
||||
setPiece(move.to() - 8, Piece::EMPTY);
|
||||
}
|
||||
} else if (p == Piece::BPAWN) {
|
||||
if (move.to() - move.from() == -2 * 8) {
|
||||
int x = getX(move.to());
|
||||
if (BitBoard::epMaskB[x] & pieceTypeBB(Piece::WPAWN))
|
||||
setEpSquare(move.from() - 8);
|
||||
} else if (move.to() == prevEpSquare) {
|
||||
setPiece(move.to() + 8, Piece::EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pieceTypeBB(Piece::WKING, Piece::BKING) & fromMask) != 0) {
|
||||
if (wtm) {
|
||||
setCastleMask(castleMask & ~(1 << A1_CASTLE));
|
||||
setCastleMask(castleMask & ~(1 << H1_CASTLE));
|
||||
} else {
|
||||
setCastleMask(castleMask & ~(1 << A8_CASTLE));
|
||||
setCastleMask(castleMask & ~(1 << H8_CASTLE));
|
||||
}
|
||||
}
|
||||
|
||||
// Perform move
|
||||
setPiece(move.from(), Piece::EMPTY);
|
||||
// Handle promotion
|
||||
if (move.promoteTo() != Piece::EMPTY) {
|
||||
setPiece(move.to(), move.promoteTo());
|
||||
} else {
|
||||
setPiece(move.to(), p);
|
||||
}
|
||||
} else {
|
||||
halfMoveClock++;
|
||||
|
||||
// Handle castling
|
||||
if ((pieceTypeBB(Piece::WKING, Piece::BKING) & fromMask) != 0) {
|
||||
int k0 = move.from();
|
||||
if (move.to() == k0 + 2) { // O-O
|
||||
movePieceNotPawn(k0 + 3, k0 + 1);
|
||||
} else if (move.to() == k0 - 2) { // O-O-O
|
||||
movePieceNotPawn(k0 - 4, k0 - 1);
|
||||
}
|
||||
if (wtm) {
|
||||
setCastleMask(castleMask & ~(1 << A1_CASTLE));
|
||||
setCastleMask(castleMask & ~(1 << H1_CASTLE));
|
||||
} else {
|
||||
setCastleMask(castleMask & ~(1 << A8_CASTLE));
|
||||
setCastleMask(castleMask & ~(1 << H8_CASTLE));
|
||||
}
|
||||
}
|
||||
|
||||
// Perform move
|
||||
movePieceNotPawn(move.from(), move.to());
|
||||
}
|
||||
if (wtm) {
|
||||
// Update castling rights when rook moves
|
||||
if ((BitBoard::maskCorners & fromMask) != 0) {
|
||||
if (p == Piece::WROOK)
|
||||
removeCastleRights(move.from());
|
||||
}
|
||||
if ((BitBoard::maskCorners & (1ULL << move.to())) != 0) {
|
||||
if (capP == Piece::BROOK)
|
||||
removeCastleRights(move.to());
|
||||
}
|
||||
} else {
|
||||
fullMoveCounter++;
|
||||
// Update castling rights when rook moves
|
||||
if ((BitBoard::maskCorners & fromMask) != 0) {
|
||||
if (p == Piece::BROOK)
|
||||
removeCastleRights(move.from());
|
||||
}
|
||||
if ((BitBoard::maskCorners & (1ULL << move.to())) != 0) {
|
||||
if (capP == Piece::WROOK)
|
||||
removeCastleRights(move.to());
|
||||
}
|
||||
}
|
||||
|
||||
whiteMove = !wtm;
|
||||
}
|
||||
|
||||
void
|
||||
Position::movePieceNotPawn(int from, int to) {
|
||||
const int piece = squares[from];
|
||||
|
||||
squares[from] = Piece::EMPTY;
|
||||
squares[to] = piece;
|
||||
|
||||
const U64 sqMaskF = 1ULL << from;
|
||||
const U64 sqMaskT = 1ULL << to;
|
||||
pieceTypeBB_[piece] &= ~sqMaskF;
|
||||
pieceTypeBB_[piece] |= sqMaskT;
|
||||
if (Piece::isWhite(piece)) {
|
||||
whiteBB_ &= ~sqMaskF;
|
||||
whiteBB_ |= sqMaskT;
|
||||
if (piece == Piece::WKING)
|
||||
wKingSq_ = to;
|
||||
} else {
|
||||
blackBB_ &= ~sqMaskF;
|
||||
blackBB_ |= sqMaskT;
|
||||
if (piece == Piece::BKING)
|
||||
bKingSq_ = to;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user