mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-01-30 17:13:50 +01:00
DroidFish: Updated stockfish to version 2.3.1.
This commit is contained in:
parent
87e38eca80
commit
0fd90e2550
|
@ -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 } };
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = "";
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user