DroidFish: Updated stockfish to version 6.

This commit is contained in:
Peter Osterlund
2015-02-01 00:46:09 +00:00
parent fffd5107c3
commit 22e71744a1
48 changed files with 4233 additions and 4553 deletions

View File

@@ -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;