mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-17 19:22:18 +01:00
DroidFish: Updated stockfish to version 6.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||
Copyright (C) 2008-2014 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||
|
||||
Stockfish is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -19,31 +19,25 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstring> // For std::memset
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "bitcount.h"
|
||||
#include "misc.h"
|
||||
#include "movegen.h"
|
||||
#include "notation.h"
|
||||
#include "position.h"
|
||||
#include "psqtab.h"
|
||||
#include "rkiss.h"
|
||||
#include "thread.h"
|
||||
#include "tt.h"
|
||||
#include "uci.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
static const string PieceToChar(" PNBRQK pnbrqk");
|
||||
|
||||
CACHE_LINE_ALIGNMENT
|
||||
|
||||
Value PieceValue[PHASE_NB][PIECE_NB] = {
|
||||
{ VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg },
|
||||
{ VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } };
|
||||
|
||||
static Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
||||
|
||||
namespace Zobrist {
|
||||
|
||||
Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
||||
@@ -57,6 +51,9 @@ Key Position::exclusion_key() const { return st->key ^ Zobrist::exclusion;}
|
||||
|
||||
namespace {
|
||||
|
||||
const string PieceToChar(" PNBRQK pnbrqk");
|
||||
Score psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
||||
|
||||
// min_attacker() is a helper function used by see() to locate the least
|
||||
// valuable attacker for the side to move, remove the attacker we just found
|
||||
// from the bitboards and scan for new X-ray attacks behind it.
|
||||
@@ -108,6 +105,30 @@ CheckInfo::CheckInfo(const Position& pos) {
|
||||
}
|
||||
|
||||
|
||||
/// operator<<(Position) returns an ASCII representation of the position
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Position& pos) {
|
||||
|
||||
os << "\n +---+---+---+---+---+---+---+---+\n";
|
||||
|
||||
for (Rank r = RANK_8; r >= RANK_1; --r)
|
||||
{
|
||||
for (File f = FILE_A; f <= FILE_H; ++f)
|
||||
os << " | " << PieceToChar[pos.piece_on(make_square(f, r))];
|
||||
|
||||
os << " |\n +---+---+---+---+---+---+---+---+\n";
|
||||
}
|
||||
|
||||
os << "\nFen: " << pos.fen() << "\nKey: " << std::hex << std::uppercase
|
||||
<< std::setfill('0') << std::setw(16) << pos.st->key << std::dec << "\nCheckers: ";
|
||||
|
||||
for (Bitboard b = pos.checkers(); b; )
|
||||
os << UCI::square(pop_lsb(&b)) << " ";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
/// Position::init() initializes at startup the various arrays used to compute
|
||||
/// hash keys and the piece square tables. The latter is a two-step operation:
|
||||
/// Firstly, the white halves of the tables are copied from PSQT[] tables.
|
||||
@@ -116,28 +137,28 @@ CheckInfo::CheckInfo(const Position& pos) {
|
||||
|
||||
void Position::init() {
|
||||
|
||||
RKISS rk;
|
||||
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] = rk.rand<Key>();
|
||||
Zobrist::psq[c][pt][s] = rng.rand<Key>();
|
||||
|
||||
for (File f = FILE_A; f <= FILE_H; ++f)
|
||||
Zobrist::enpassant[f] = rk.rand<Key>();
|
||||
Zobrist::enpassant[f] = rng.rand<Key>();
|
||||
|
||||
for (int cf = NO_CASTLING; cf <= ANY_CASTLING; ++cf)
|
||||
for (int cr = NO_CASTLING; cr <= ANY_CASTLING; ++cr)
|
||||
{
|
||||
Bitboard b = cf;
|
||||
Bitboard b = cr;
|
||||
while (b)
|
||||
{
|
||||
Key k = Zobrist::castling[1ULL << pop_lsb(&b)];
|
||||
Zobrist::castling[cf] ^= k ? k : rk.rand<Key>();
|
||||
Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
|
||||
}
|
||||
}
|
||||
|
||||
Zobrist::side = rk.rand<Key>();
|
||||
Zobrist::exclusion = rk.rand<Key>();
|
||||
Zobrist::side = rng.rand<Key>();
|
||||
Zobrist::exclusion = rng.rand<Key>();
|
||||
|
||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
||||
{
|
||||
@@ -155,9 +176,8 @@ void Position::init() {
|
||||
}
|
||||
|
||||
|
||||
/// Position::operator=() creates a copy of 'pos'. We want the new born Position
|
||||
/// object to not depend on any external data so we detach state pointer from
|
||||
/// the source one.
|
||||
/// Position::operator=() creates a copy of 'pos' but detaching the state pointer
|
||||
/// from the source to be self-consistent and not depending on any external data.
|
||||
|
||||
Position& Position::operator=(const Position& pos) {
|
||||
|
||||
@@ -342,7 +362,7 @@ void Position::set_castling_right(Color c, Square rfrom) {
|
||||
void Position::set_state(StateInfo* si) const {
|
||||
|
||||
si->key = si->pawnKey = si->materialKey = 0;
|
||||
si->npMaterial[WHITE] = si->npMaterial[BLACK] = VALUE_ZERO;
|
||||
si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
|
||||
si->psq = SCORE_ZERO;
|
||||
|
||||
si->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
|
||||
@@ -376,7 +396,7 @@ void Position::set_state(StateInfo* si) const {
|
||||
|
||||
for (Color c = WHITE; c <= BLACK; ++c)
|
||||
for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
|
||||
si->npMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
|
||||
si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
|
||||
}
|
||||
|
||||
|
||||
@@ -409,63 +429,37 @@ const string Position::fen() const {
|
||||
ss << (sideToMove == WHITE ? " w " : " b ");
|
||||
|
||||
if (can_castle(WHITE_OO))
|
||||
ss << (chess960 ? to_char(file_of(castling_rook_square(WHITE | KING_SIDE)), false) : 'K');
|
||||
ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE | KING_SIDE))) : 'K');
|
||||
|
||||
if (can_castle(WHITE_OOO))
|
||||
ss << (chess960 ? to_char(file_of(castling_rook_square(WHITE | QUEEN_SIDE)), false) : 'Q');
|
||||
ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE | QUEEN_SIDE))) : 'Q');
|
||||
|
||||
if (can_castle(BLACK_OO))
|
||||
ss << (chess960 ? to_char(file_of(castling_rook_square(BLACK | KING_SIDE)), true) : 'k');
|
||||
ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK | KING_SIDE))) : 'k');
|
||||
|
||||
if (can_castle(BLACK_OOO))
|
||||
ss << (chess960 ? to_char(file_of(castling_rook_square(BLACK | QUEEN_SIDE)), true) : 'q');
|
||||
ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK | QUEEN_SIDE))) : 'q');
|
||||
|
||||
if (!can_castle(WHITE) && !can_castle(BLACK))
|
||||
ss << '-';
|
||||
|
||||
ss << (ep_square() == SQ_NONE ? " - " : " " + to_string(ep_square()) + " ")
|
||||
ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
|
||||
<< st->rule50 << " " << 1 + (gamePly - (sideToMove == BLACK)) / 2;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
/// Position::pretty() returns an ASCII representation of the position
|
||||
|
||||
const string Position::pretty() const {
|
||||
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "\n +---+---+---+---+---+---+---+---+\n";
|
||||
|
||||
for (Rank r = RANK_8; r >= RANK_1; --r)
|
||||
{
|
||||
for (File f = FILE_A; f <= FILE_H; ++f)
|
||||
ss << " | " << PieceToChar[piece_on(make_square(f, r))];
|
||||
|
||||
ss << " |\n +---+---+---+---+---+---+---+---+\n";
|
||||
}
|
||||
|
||||
ss << "\nFen: " << fen() << "\nKey: " << std::hex << std::uppercase
|
||||
<< std::setfill('0') << std::setw(16) << st->key << "\nCheckers: ";
|
||||
|
||||
for (Bitboard b = checkers(); b; )
|
||||
ss << to_string(pop_lsb(&b)) << " ";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
/// Position::game_phase() calculates the game phase interpolating total non-pawn
|
||||
/// material between endgame and midgame limits.
|
||||
|
||||
Phase Position::game_phase() const {
|
||||
|
||||
Value npm = st->npMaterial[WHITE] + st->npMaterial[BLACK];
|
||||
Value npm = st->nonPawnMaterial[WHITE] + st->nonPawnMaterial[BLACK];
|
||||
|
||||
npm = std::max(EndgameLimit, std::min(npm, MidgameLimit));
|
||||
|
||||
return Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));
|
||||
return Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
|
||||
}
|
||||
|
||||
|
||||
@@ -497,16 +491,16 @@ Bitboard Position::check_blockers(Color c, Color kingColor) const {
|
||||
|
||||
|
||||
/// Position::attackers_to() computes a bitboard of all pieces which attack a
|
||||
/// given square. Slider attacks use the occ bitboard to indicate occupancy.
|
||||
/// given square. Slider attacks use the occupied bitboard to indicate occupancy.
|
||||
|
||||
Bitboard Position::attackers_to(Square s, Bitboard occ) const {
|
||||
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
|
||||
|
||||
return (attacks_from<PAWN>(s, BLACK) & pieces(WHITE, PAWN))
|
||||
| (attacks_from<PAWN>(s, WHITE) & pieces(BLACK, PAWN))
|
||||
| (attacks_from<KNIGHT>(s) & pieces(KNIGHT))
|
||||
| (attacks_bb<ROOK>(s, occ) & pieces(ROOK, QUEEN))
|
||||
| (attacks_bb<BISHOP>(s, occ) & pieces(BISHOP, QUEEN))
|
||||
| (attacks_from<KING>(s) & pieces(KING));
|
||||
return (attacks_from<PAWN>(s, BLACK) & pieces(WHITE, PAWN))
|
||||
| (attacks_from<PAWN>(s, WHITE) & pieces(BLACK, PAWN))
|
||||
| (attacks_from<KNIGHT>(s) & pieces(KNIGHT))
|
||||
| (attacks_bb<ROOK>(s, occupied) & pieces(ROOK, QUEEN))
|
||||
| (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
|
||||
| (attacks_from<KING>(s) & pieces(KING));
|
||||
}
|
||||
|
||||
|
||||
@@ -531,15 +525,15 @@ bool Position::legal(Move m, Bitboard pinned) const {
|
||||
Square ksq = king_square(us);
|
||||
Square to = to_sq(m);
|
||||
Square capsq = to - pawn_push(us);
|
||||
Bitboard occ = (pieces() ^ from ^ capsq) | to;
|
||||
Bitboard occupied = (pieces() ^ from ^ capsq) | to;
|
||||
|
||||
assert(to == ep_square());
|
||||
assert(moved_piece(m) == make_piece(us, PAWN));
|
||||
assert(piece_on(capsq) == make_piece(~us, PAWN));
|
||||
assert(piece_on(to) == NO_PIECE);
|
||||
|
||||
return !(attacks_bb< ROOK>(ksq, occ) & pieces(~us, QUEEN, ROOK))
|
||||
&& !(attacks_bb<BISHOP>(ksq, occ) & pieces(~us, QUEEN, BISHOP));
|
||||
return !(attacks_bb< ROOK>(ksq, occupied) & pieces(~us, QUEEN, ROOK))
|
||||
&& !(attacks_bb<BISHOP>(ksq, occupied) & pieces(~us, QUEEN, BISHOP));
|
||||
}
|
||||
|
||||
// If the moving piece is a king, check whether the destination
|
||||
@@ -647,7 +641,7 @@ bool Position::gives_check(Move m, const CheckInfo& ci) const {
|
||||
return true;
|
||||
|
||||
// Is there a discovered check?
|
||||
if ( unlikely(ci.dcCandidates)
|
||||
if ( ci.dcCandidates
|
||||
&& (ci.dcCandidates & from)
|
||||
&& !aligned(from, to, ci.ksq))
|
||||
return true;
|
||||
@@ -772,7 +766,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
||||
st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
|
||||
}
|
||||
else
|
||||
st->npMaterial[them] -= PieceValue[MG][captured];
|
||||
st->nonPawnMaterial[them] -= PieceValue[MG][captured];
|
||||
|
||||
// Update board and piece lists
|
||||
remove_piece(capsq, them, captured);
|
||||
@@ -842,7 +836,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
||||
st->psq += psq[us][promotion][to] - psq[us][PAWN][to];
|
||||
|
||||
// Update material
|
||||
st->npMaterial[us] += PieceValue[MG][promotion];
|
||||
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
|
||||
}
|
||||
|
||||
// Update pawn hash key and prefetch access to pawnsTable
|
||||
@@ -876,7 +870,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
||||
st->checkersBB |= to;
|
||||
|
||||
// Discovered checks
|
||||
if (unlikely(ci.dcCandidates) && (ci.dcCandidates & from))
|
||||
if (ci.dcCandidates && (ci.dcCandidates & from))
|
||||
{
|
||||
if (pt != ROOK)
|
||||
st->checkersBB |= attacks_from<ROOK>(king_square(them)) & pieces(us, QUEEN, ROOK);
|
||||
@@ -1013,7 +1007,7 @@ void Position::undo_null_move() {
|
||||
}
|
||||
|
||||
|
||||
/// Position::key_after() computes the new hash key after the given moven. Needed
|
||||
/// Position::key_after() computes the new hash key after the given move. Needed
|
||||
/// for speculative prefetch. It doesn't recognize special moves like castling,
|
||||
/// en-passant and promotions.
|
||||
|
||||
@@ -1239,8 +1233,8 @@ bool Position::pos_is_ok(int* step) const {
|
||||
if ( st->key != si.key
|
||||
|| st->pawnKey != si.pawnKey
|
||||
|| st->materialKey != si.materialKey
|
||||
|| st->npMaterial[WHITE] != si.npMaterial[WHITE]
|
||||
|| st->npMaterial[BLACK] != si.npMaterial[BLACK]
|
||||
|| st->nonPawnMaterial[WHITE] != si.nonPawnMaterial[WHITE]
|
||||
|| st->nonPawnMaterial[BLACK] != si.nonPawnMaterial[BLACK]
|
||||
|| st->psq != si.psq
|
||||
|| st->checkersBB != si.checkersBB)
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user