DroidFish: Updated stockfish to version 2.3.1.

This commit is contained in:
Peter Osterlund 2012-09-23 08:13:11 +00:00
parent 87e38eca80
commit 0fd90e2550
8 changed files with 88 additions and 82 deletions

View File

@ -62,8 +62,8 @@ namespace {
CACHE_LINE_ALIGNMENT
int BSFTable[64];
int MS1BTable[256];
Square BSFTable[64];
Bitboard RTable[0x19000]; // Storage space for rook attacks
Bitboard BTable[0x1480]; // Storage space for bishop attacks
uint8_t BitCount8Bit[256];
@ -72,6 +72,16 @@ namespace {
void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
Bitboard masks[], unsigned shifts[], Square deltas[], Fn index);
FORCE_INLINE unsigned bsf_index(Bitboard b) {
if (Is64Bit)
return ((b & -b) * DeBruijn_64) >> 58;
// Use Matt Taylor's folding trick for 32 bit systems
b ^= (b - 1);
return ((unsigned(b) ^ unsigned(b >> 32)) * DeBruijn_32) >> 26;
}
}
/// lsb()/msb() finds the least/most significant bit in a nonzero bitboard.
@ -79,27 +89,13 @@ namespace {
#if !defined(USE_BSFQ)
Square lsb(Bitboard b) {
if (Is64Bit)
return Square(BSFTable[((b & -b) * DeBruijn_64) >> 58]);
b ^= (b - 1);
uint32_t fold = unsigned(b) ^ unsigned(b >> 32);
return Square(BSFTable[(fold * DeBruijn_32) >> 26]);
}
Square lsb(Bitboard b) { return BSFTable[bsf_index(b)]; }
Square pop_lsb(Bitboard* b) {
Bitboard bb = *b;
*b = bb & (bb - 1);
if (Is64Bit)
return Square(BSFTable[((bb & -bb) * DeBruijn_64) >> 58]);
bb ^= (bb - 1);
uint32_t fold = unsigned(bb) ^ unsigned(bb >> 32);
return Square(BSFTable[(fold * DeBruijn_32) >> 26]);
return BSFTable[bsf_index(bb)];
}
Square msb(Bitboard b) {
@ -127,7 +123,7 @@ Square msb(Bitboard b) {
result += 8;
}
return Square(result + MS1BTable[b32]);
return (Square)(result + MS1BTable[b32]);
}
#endif // !defined(USE_BSFQ)
@ -162,6 +158,9 @@ void Bitboards::init() {
while (k < (2 << i))
MS1BTable[k++] = i;
for (int i = 0; i < 64; i++)
BSFTable[bsf_index(1ULL << i)] = Square(i);
for (Bitboard b = 0; b < 256; b++)
BitCount8Bit[b] = (uint8_t)popcount<Max15>(b);
@ -204,17 +203,6 @@ void Bitboards::init() {
if (SquareDistance[s1][s2] == d)
DistanceRingsBB[s1][d - 1] |= s2;
for (int i = 0; i < 64; i++)
if (!Is64Bit) // Matt Taylor's folding trick for 32 bit systems
{
Bitboard b = 1ULL << i;
b ^= b - 1;
b ^= b >> 32;
BSFTable[(uint32_t)(b * DeBruijn_32) >> 26] = i;
}
else
BSFTable[((1ULL << i) * DeBruijn_64) >> 58] = i;
int steps[][9] = { {}, { 7, 9 }, { 17, 15, 10, 6, -6, -10, -15, -17 },
{}, {}, {}, { 9, 7, -7, -9, 8, 1, -1, -8 } };

View File

@ -35,6 +35,16 @@ using namespace std;
namespace {
// A Polyglot book is a series of "entries" of 16 bytes. All integers are
// stored in big-endian format, with highest byte first (regardless of size).
// The entries are ordered according to the key in ascending order.
struct BookEntry {
uint64_t key;
uint16_t move;
uint16_t count;
uint32_t learn;
};
// Random numbers from PolyGlot, used to compute book hash keys
const Key PolyGlotRandoms[781] = {
0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL,
@ -338,20 +348,20 @@ namespace {
} // namespace
Book::Book() {
PolyglotBook::PolyglotBook() {
for (int i = Time::now() % 10000; i > 0; i--)
RKiss.rand<unsigned>(); // Make random number generation less deterministic
}
Book::~Book() { if (is_open()) close(); }
PolyglotBook::~PolyglotBook() { if (is_open()) close(); }
/// Book::operator>>() reads sizeof(T) chars from the file's binary byte stream
/// and converts them in a number of type T. A Polyglot book stores numbers in
/// operator>>() reads sizeof(T) chars from the file's binary byte stream and
/// converts them in a number of type T. A Polyglot book stores numbers in
/// big-endian format.
template<typename T> Book& Book::operator>>(T& n) {
template<typename T> PolyglotBook& PolyglotBook::operator>>(T& n) {
n = 0;
for (size_t i = 0; i < sizeof(T); i++)
@ -360,15 +370,15 @@ template<typename T> Book& Book::operator>>(T& n) {
return *this;
}
template<> Book& Book::operator>>(BookEntry& e) {
template<> PolyglotBook& PolyglotBook::operator>>(BookEntry& e) {
return *this >> e.key >> e.move >> e.count >> e.learn;
}
/// Book::open() tries to open a book file with the given name after closing
/// any exsisting one.
/// open() tries to open a book file with the given name after closing any
/// exsisting one.
bool Book::open(const char* fName) {
bool PolyglotBook::open(const char* fName) {
if (is_open()) // Cannot close an already closed file
close();
@ -381,11 +391,11 @@ bool Book::open(const char* fName) {
}
/// Book::probe() tries to find a book move for the given position. If no move
/// is found returns MOVE_NONE. If pickBest is true returns always the highest
/// probe() tries to find a book move for the given position. If no move is
/// found returns MOVE_NONE. If pickBest is true returns always the highest
/// rated move, otherwise randomly chooses one, based on the move score.
Move Book::probe(const Position& pos, const string& fName, bool pickBest) {
Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest) {
if (fileName != fName && !open(fName.c_str()))
return MOVE_NONE;
@ -437,11 +447,11 @@ Move Book::probe(const Position& pos, const string& fName, bool pickBest) {
}
/// Book::find_first() takes a book key as input, and does a binary search
/// through the book file for the given key. Returns the index of the leftmost
/// book entry with the same key as the input.
/// find_first() takes a book key as input, and does a binary search through
/// the book file for the given key. Returns the index of the leftmost book
/// entry with the same key as the input.
size_t Book::find_first(uint64_t key) {
size_t PolyglotBook::find_first(uint64_t key) {
seekg(0, ios::end); // Move pointer to end, so tellg() gets file's size

View File

@ -26,26 +26,14 @@
#include "position.h"
#include "rkiss.h"
/// A Polyglot book is a series of "entries" of 16 bytes. All integers are
/// stored highest byte first (regardless of size). The entries are ordered
/// according to key. Lowest key first.
struct BookEntry {
uint64_t key;
uint16_t move;
uint16_t count;
uint32_t learn;
};
class Book : private std::ifstream {
class PolyglotBook : private std::ifstream {
public:
Book();
~Book();
PolyglotBook();
~PolyglotBook();
Move probe(const Position& pos, const std::string& fName, bool pickBest);
private:
template<typename T> Book& operator>>(T& n);
template<typename T> PolyglotBook& operator>>(T& n);
bool open(const char* fName);
size_t find_first(uint64_t key);

View File

@ -648,7 +648,7 @@ ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1
|| ( file_of(ksq) == FILE_A
&& !in_front_bb(strongerSide, ksq) & pawns))
&& !(in_front_bb(strongerSide, ksq) & pawns)))
return SCALE_FACTOR_DRAW;
}
// Are all pawns on the 'h' file?
@ -657,7 +657,7 @@ ScaleFactor Endgame<KPsK>::operator()(const Position& pos) const {
// Does the defending king block the pawns?
if ( square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1
|| ( file_of(ksq) == FILE_H
&& !in_front_bb(strongerSide, ksq) & pawns))
&& !(in_front_bb(strongerSide, ksq) & pawns)))
return SCALE_FACTOR_DRAW;
}
return SCALE_FACTOR_NONE;

View File

@ -138,7 +138,7 @@ namespace {
{}, {},
{ S(0, 0), S( 7, 39), S( 0, 0), S(24, 49), S(41,100), S(41,100) }, // KNIGHT
{ S(0, 0), S( 7, 39), S(24, 49), S( 0, 0), S(41,100), S(41,100) }, // BISHOP
{ S(0, 0), S(-1, 29), S(15, 49), S(15, 49), S( 0, 0), S(24, 49) }, // ROOK
{ S(0, 0), S( 0, 22), S(15, 49), S(15, 49), S( 0, 0), S(24, 49) }, // ROOK
{ S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
};
@ -153,12 +153,16 @@ namespace {
// Bonus for having the side to move (modified by Joona Kiiski)
const Score Tempo = make_score(24, 11);
// Rooks and queens on the 7th rank (modified by Joona Kiiski)
const Score RookOn7thBonus = make_score(47, 98);
const Score QueenOn7thBonus = make_score(27, 54);
// Rooks and queens on the 7th rank
const Score RookOn7thBonus = make_score(3, 20);
const Score QueenOn7thBonus = make_score(1, 8);
// Rooks and queens attacking pawns on the same rank
const Score RookOnPawnBonus = make_score(3, 48);
const Score QueenOnPawnBonus = make_score(1, 40);
// Rooks on open files (modified by Joona Kiiski)
const Score RookOpenFileBonus = make_score(43, 21);
const Score RookOpenFileBonus = make_score(43, 21);
const Score RookHalfOpenFileBonus = make_score(19, 10);
// Penalty for rooks trapped inside a friendly king which has lost the
@ -595,12 +599,18 @@ Value do_evaluate(const Position& pos, Value& margin) {
&& !(pos.pieces(Them, PAWN) & attack_span_mask(Us, s)))
score += evaluate_outposts<Piece, Us>(pos, ei, s);
// Queen or rook on 7th rank
if ( (Piece == ROOK || Piece == QUEEN)
&& relative_rank(Us, s) == RANK_7
&& relative_rank(Us, pos.king_square(Them)) == RANK_8)
if ((Piece == ROOK || Piece == QUEEN) && relative_rank(Us, s) >= RANK_5)
{
score += (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
// Major piece on 7th rank
if ( relative_rank(Us, s) == RANK_7
&& relative_rank(Us, pos.king_square(Them)) == RANK_8)
score += (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
// Major piece attacking pawns on the same rank
Bitboard pawns = pos.pieces(Them, PAWN) & rank_bb(s);
if (pawns)
score += (Piece == ROOK ? RookOnPawnBonus
: QueenOnPawnBonus) * popcount<Max15>(pawns);
}
// Special extra evaluation for bishops

View File

@ -33,7 +33,7 @@ using namespace std;
/// Version number. If Version is left empty, then Tag plus current
/// date (in the format YYMMDD) is used as a version number.
static const string Version = "2.3";
static const string Version = "2.3.1";
static const string Tag = "";

View File

@ -31,7 +31,7 @@
(*mlist++).move = make_move(to - (d), to); }
namespace {
template<CastlingSide Side, bool Checks>
template<CastlingSide Side, bool Checks, bool Chess960>
MoveStack* generate_castle(const Position& pos, MoveStack* mlist, Color us) {
if (pos.castle_impeded(us, Side) || !pos.can_castle(make_castle_right(us, Side)))
@ -46,16 +46,18 @@ namespace {
assert(!pos.in_check());
for (Square s = kto; s != kfrom; s += (Square)(Side == KING_SIDE ? -1 : 1))
const int K = Chess960 ? kto > kfrom ? -1 : 1
: Side == KING_SIDE ? -1 : 1;
for (Square s = kto; s != kfrom; s += (Square)K)
if (pos.attackers_to(s) & enemies)
return mlist;
// Because we generate only legal castling moves we need to verify that
// when moving the castling rook we do not discover some hidden checker.
// For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1.
if ( pos.is_chess960()
&& (pos.attackers_to(kto, pos.pieces() ^ rfrom) & enemies))
return mlist;
if (Chess960 && (pos.attackers_to(kto, pos.pieces() ^ rfrom) & enemies))
return mlist;
(*mlist++).move = make<CASTLE>(kfrom, rfrom);
@ -273,8 +275,16 @@ namespace {
if (Type != CAPTURES && Type != EVASIONS && pos.can_castle(us))
{
mlist = generate_castle<KING_SIDE, Type == QUIET_CHECKS>(pos, mlist, us);
mlist = generate_castle<QUEEN_SIDE, Type == QUIET_CHECKS>(pos, mlist, us);
if (pos.is_chess960())
{
mlist = generate_castle<KING_SIDE, Type == QUIET_CHECKS, true>(pos, mlist, us);
mlist = generate_castle<QUEEN_SIDE, Type == QUIET_CHECKS, true>(pos, mlist, us);
}
else
{
mlist = generate_castle<KING_SIDE, Type == QUIET_CHECKS, false>(pos, mlist, us);
mlist = generate_castle<QUEEN_SIDE, Type == QUIET_CHECKS, false>(pos, mlist, us);
}
}
return mlist;

View File

@ -224,7 +224,7 @@ size_t Search::perft(Position& pos, Depth depth) {
void Search::think() {
static Book book; // Defined static to initialize the PRNG only once
static PolyglotBook book; // Defined static to initialize the PRNG only once
Position& pos = RootPosition;
Chess960 = pos.is_chess960();