DroidFish: Updated stockfish engine to git version from 2016-09-17.

This commit is contained in:
Peter Osterlund
2016-09-18 00:05:29 +02:00
parent ad63e43412
commit c144bb9800
17 changed files with 457 additions and 452 deletions

View File

@@ -20,7 +20,8 @@
#include <algorithm>
#include <cassert>
#include <cstring> // For std::memset, std::memcmp
#include <cstddef> // For offsetof()
#include <cstring> // For std::memset, std::memcmp
#include <iomanip>
#include <sstream>
@@ -34,17 +35,18 @@
using std::string;
namespace PSQT {
extern Score psq[PIECE_NB][SQUARE_NB];
}
namespace Zobrist {
Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
Key psq[PIECE_NB][SQUARE_NB];
Key enpassant[FILE_NB];
Key castling[CASTLING_RIGHT_NB];
Key side;
Key exclusion;
}
Key Position::exclusion_key() const { return st->key ^ Zobrist::exclusion; }
namespace {
const string PieceToChar(" PNBRQK pnbrqk");
@@ -112,10 +114,9 @@ void Position::init() {
PRNG rng(1070372);
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
for (Square s = SQ_A1; s <= SQ_H8; ++s)
Zobrist::psq[c][pt][s] = rng.rand<Key>();
for (Piece pc : Pieces)
for (Square s = SQ_A1; s <= SQ_H8; ++s)
Zobrist::psq[pc][s] = rng.rand<Key>();
for (File f = FILE_A; f <= FILE_H; ++f)
Zobrist::enpassant[f] = rng.rand<Key>();
@@ -132,7 +133,6 @@ void Position::init() {
}
Zobrist::side = rng.rand<Key>();
Zobrist::exclusion = rng.rand<Key>();
}
@@ -182,7 +182,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
std::memset(this, 0, sizeof(Position));
std::memset(si, 0, sizeof(StateInfo));
std::fill_n(&pieceList[0][0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
st = si;
ss >> std::noskipws;
@@ -198,7 +198,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
else if ((idx = PieceToChar.find(token)) != string::npos)
{
put_piece(color_of(Piece(idx)), type_of(Piece(idx)), sq);
put_piece(Piece(idx), sq);
++sq;
}
}
@@ -296,8 +296,8 @@ void Position::set_castling_right(Color c, Square rfrom) {
void Position::set_check_info(StateInfo* si) const {
si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE));
si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK));
si->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), si->pinnersForKing[WHITE]);
si->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), si->pinnersForKing[BLACK]);
Square ksq = square<KING>(~sideToMove);
@@ -328,8 +328,8 @@ void Position::set_state(StateInfo* si) const {
{
Square s = pop_lsb(&b);
Piece pc = piece_on(s);
si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s];
si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s];
si->key ^= Zobrist::psq[pc][s];
si->psq += PSQT::psq[pc][s];
}
if (si->epSquare != SQ_NONE)
@@ -343,17 +343,17 @@ void Position::set_state(StateInfo* si) const {
for (Bitboard b = pieces(PAWN); b; )
{
Square s = pop_lsb(&b);
si->pawnKey ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s];
si->pawnKey ^= Zobrist::psq[piece_on(s)][s];
}
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
for (int cnt = 0; cnt < pieceCount[c][pt]; ++cnt)
si->materialKey ^= Zobrist::psq[c][pt][cnt];
for (Piece pc : Pieces)
{
if (type_of(pc) != PAWN && type_of(pc) != KING)
si->nonPawnMaterial[color_of(pc)] += pieceCount[pc] * PieceValue[MG][pc];
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
for (int cnt = 0; cnt < pieceCount[pc]; ++cnt)
si->materialKey ^= Zobrist::psq[pc][cnt];
}
}
@@ -420,24 +420,25 @@ Phase Position::game_phase() const {
}
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors) that
/// are blocking attacks on the square 's' from 'sliders'. A piece blocks a slider
/// if removing that piece from the board would result in a position where square 's'
/// is attacked. For example, a king-attack blocking piece can be either a pinned or
/// a discovered check piece, according if its color is the opposite or the same of
/// the color of the slider.
/// Position::slider_blockers() returns a bitboard of all the pieces (both colors)
/// that are blocking attacks on the square 's' from 'sliders'. A piece blocks a
/// slider if removing that piece from the board would result in a position where
/// square 's' is attacked. For example, a king-attack blocking piece can be either
/// a pinned or a discovered check piece, according if its color is the opposite
/// or the same of the color of the slider. The pinners bitboard get filled with
/// real and potential pinners.
Bitboard Position::slider_blockers(Bitboard sliders, Square s) const {
Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const {
Bitboard b, pinners, result = 0;
Bitboard b, p, result = 0;
// Pinners are sliders that attack 's' when a pinned piece is removed
pinners = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
pinners = p = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK))
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
while (pinners)
while (p)
{
b = between_bb(s, pop_lsb(&pinners)) & pieces();
b = between_bb(s, pop_lsb(&p)) & pieces();
if (!more_than_one(b))
result |= b;
@@ -661,23 +662,24 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
Color them = ~us;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
PieceType captured = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
Piece pc = piece_on(from);
Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
assert(color_of(piece_on(from)) == us);
assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == (type_of(m) != CASTLING ? them : us));
assert(captured != KING);
assert(color_of(pc) == us);
assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
assert(type_of(captured) != KING);
if (type_of(m) == CASTLING)
{
assert(pt == KING);
assert(pc == make_piece(us, KING));
assert(captured == make_piece(us, ROOK));
Square rfrom, rto;
do_castling<true>(us, from, to, rfrom, rto);
captured = NO_PIECE_TYPE;
st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom];
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
st->psq += PSQT::psq[captured][rto] - PSQT::psq[captured][rfrom];
k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
captured = NO_PIECE;
}
if (captured)
@@ -686,13 +688,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// If the captured piece is a pawn, update pawn hash key, otherwise
// update non-pawn material.
if (captured == PAWN)
if (type_of(captured) == PAWN)
{
if (type_of(m) == ENPASSANT)
{
capsq -= pawn_push(us);
assert(pt == PAWN);
assert(pc == make_piece(us, PAWN));
assert(to == st->epSquare);
assert(relative_rank(us, to) == RANK_6);
assert(piece_on(to) == NO_PIECE);
@@ -701,28 +703,28 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
board[capsq] = NO_PIECE; // Not done by remove_piece()
}
st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
st->pawnKey ^= Zobrist::psq[captured][capsq];
}
else
st->nonPawnMaterial[them] -= PieceValue[MG][captured];
// Update board and piece lists
remove_piece(them, captured, capsq);
remove_piece(captured, capsq);
// Update material hash key and prefetch access to materialTable
k ^= Zobrist::psq[them][captured][capsq];
st->materialKey ^= Zobrist::psq[them][captured][pieceCount[them][captured]];
k ^= Zobrist::psq[captured][capsq];
st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
prefetch(thisThread->materialTable[st->materialKey]);
// Update incremental scores
st->psq -= PSQT::psq[them][captured][capsq];
st->psq -= PSQT::psq[captured][capsq];
// Reset rule 50 counter
st->rule50 = 0;
}
// Update hash key
k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to];
k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
// Reset en passant square
if (st->epSquare != SQ_NONE)
@@ -741,10 +743,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// Move the piece. The tricky Chess960 castling is handled earlier
if (type_of(m) != CASTLING)
move_piece(us, pt, from, to);
move_piece(pc, from, to);
// If the moving piece is a pawn do some special extra work
if (pt == PAWN)
if (type_of(pc) == PAWN)
{
// Set en-passant square if the moved pawn can be captured
if ( (int(to) ^ int(from)) == 16
@@ -756,29 +758,29 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
else if (type_of(m) == PROMOTION)
{
PieceType promotion = promotion_type(m);
Piece promotion = make_piece(us, promotion_type(m));
assert(relative_rank(us, to) == RANK_8);
assert(promotion >= KNIGHT && promotion <= QUEEN);
assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
remove_piece(us, PAWN, to);
put_piece(us, promotion, to);
remove_piece(pc, to);
put_piece(promotion, to);
// Update hash keys
k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
st->pawnKey ^= Zobrist::psq[us][PAWN][to];
st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]-1]
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
st->pawnKey ^= Zobrist::psq[pc][to];
st->materialKey ^= Zobrist::psq[promotion][pieceCount[promotion]-1]
^ Zobrist::psq[pc][pieceCount[pc]];
// Update incremental score
st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to];
st->psq += PSQT::psq[promotion][to] - PSQT::psq[pc][to];
// Update material
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
}
// Update pawn hash key and prefetch access to pawnsTable
st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to];
st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
prefetch(thisThread->pawnsTable[st->pawnKey]);
// Reset rule 50 draw counter
@@ -786,10 +788,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
}
// Update incremental scores
st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from];
st->psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
// Set capture piece
st->capturedType = captured;
st->capturedPiece = captured;
// Update the key with the final value
st->key = k;
@@ -818,20 +820,20 @@ void Position::undo_move(Move m) {
Color us = sideToMove;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(to));
Piece pc = piece_on(to);
assert(empty(from) || type_of(m) == CASTLING);
assert(st->capturedType != KING);
assert(type_of(st->capturedPiece) != KING);
if (type_of(m) == PROMOTION)
{
assert(relative_rank(us, to) == RANK_8);
assert(pt == promotion_type(m));
assert(pt >= KNIGHT && pt <= QUEEN);
assert(type_of(pc) == promotion_type(m));
assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);
remove_piece(us, pt, to);
put_piece(us, PAWN, to);
pt = PAWN;
remove_piece(pc, to);
pc = make_piece(us, PAWN);
put_piece(pc, to);
}
if (type_of(m) == CASTLING)
@@ -841,9 +843,9 @@ void Position::undo_move(Move m) {
}
else
{
move_piece(us, pt, to, from); // Put the piece back at the source square
move_piece(pc, to, from); // Put the piece back at the source square
if (st->capturedType)
if (st->capturedPiece)
{
Square capsq = to;
@@ -851,14 +853,14 @@ void Position::undo_move(Move m) {
{
capsq -= pawn_push(us);
assert(pt == PAWN);
assert(type_of(pc) == PAWN);
assert(to == st->previous->epSquare);
assert(relative_rank(us, to) == RANK_6);
assert(piece_on(capsq) == NO_PIECE);
assert(st->capturedType == PAWN);
assert(st->capturedPiece == make_piece(~us, PAWN));
}
put_piece(~us, st->capturedType, capsq); // Restore the captured piece
put_piece(st->capturedPiece, capsq); // Restore the captured piece
}
}
@@ -871,7 +873,7 @@ void Position::undo_move(Move m) {
/// Position::do_castling() is a helper used to do/undo a castling move. This
/// is a bit tricky, especially in Chess960.
/// is a bit tricky in Chess960 where from/to squares can overlap.
template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
@@ -881,11 +883,11 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
// Remove both pieces first since squares could overlap in Chess960
remove_piece(us, KING, Do ? from : to);
remove_piece(us, ROOK, Do ? rfrom : rto);
remove_piece(make_piece(us, KING), Do ? from : to);
remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
put_piece(us, KING, Do ? to : from);
put_piece(us, ROOK, Do ? rto : rfrom);
put_piece(make_piece(us, KING), Do ? to : from);
put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
}
@@ -935,17 +937,16 @@ void Position::undo_null_move() {
Key Position::key_after(Move m) const {
Color us = sideToMove;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
PieceType captured = type_of(piece_on(to));
Piece pc = piece_on(from);
Piece captured = piece_on(to);
Key k = st->key ^ Zobrist::side;
if (captured)
k ^= Zobrist::psq[~us][captured][to];
k ^= Zobrist::psq[captured][to];
return k ^ Zobrist::psq[us][pt][to] ^ Zobrist::psq[us][pt][from];
return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
}
@@ -1001,8 +1002,17 @@ Value Position::see(Move m) const {
// If the opponent has no attackers we are finished
stm = ~stm;
stmAttackers = attackers & pieces(stm);
occupied ^= to; // For the case when captured piece is a pinner
// Don't allow pinned pieces to attack as long all pinners (this includes also
// potential ones) are on their original square. When a pinner moves to the
// exchange-square or get captured on it, we fall back to standard SEE behaviour.
if ( (stmAttackers & pinned_pieces(stm))
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
stmAttackers &= ~pinned_pieces(stm);
if (!stmAttackers)
return swapList[0];
return swapList[0];
// The destination square is defended, which makes things rather more
// difficult to compute. We proceed by building up a "swap list" containing
@@ -1022,6 +1032,10 @@ Value Position::see(Move m) const {
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm;
stmAttackers = attackers & pieces(stm);
if ( (stmAttackers & pinned_pieces(stm))
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
stmAttackers &= ~pinned_pieces(stm);
++slIndex;
} while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture
@@ -1140,17 +1154,15 @@ bool Position::pos_is_ok(int* failedStep) const {
}
if (step == Lists)
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
{
if (pieceCount[c][pt] != popcount(pieces(c, pt)))
return false;
for (Piece pc : Pieces)
{
if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc))))
return false;
for (int i = 0; i < pieceCount[c][pt]; ++i)
if ( board[pieceList[c][pt][i]] != make_piece(c, pt)
|| index[pieceList[c][pt][i]] != i)
return false;
}
for (int i = 0; i < pieceCount[pc]; ++i)
if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
return false;
}
if (step == Castling)
for (Color c = WHITE; c <= BLACK; ++c)