mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-18 11:42:17 +01:00
Update to Stockfish 11
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||
Copyright (c) 2013 Ronald de Man
|
||||
Copyright (C) 2016-2018 Marco Costalba, Lucas Braesch
|
||||
Copyright (C) 2016-2020 Marco Costalba, Lucas Braesch
|
||||
|
||||
Stockfish is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,12 +27,12 @@
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
#include <mutex>
|
||||
|
||||
#include "../bitboard.h"
|
||||
#include "../movegen.h"
|
||||
#include "../position.h"
|
||||
#include "../search.h"
|
||||
#include "../thread_win32.h"
|
||||
#include "../types.h"
|
||||
#include "../uci.h"
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX // Disable macros min() and max()
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
@@ -214,39 +216,57 @@ public:
|
||||
return *baseAddress = nullptr, nullptr;
|
||||
|
||||
fstat(fd, &statbuf);
|
||||
|
||||
if (statbuf.st_size % 64 != 16)
|
||||
{
|
||||
std::cerr << "Corrupt tablebase file " << fname << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*mapping = statbuf.st_size;
|
||||
*baseAddress = mmap(nullptr, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
madvise(*baseAddress, statbuf.st_size, MADV_RANDOM);
|
||||
::close(fd);
|
||||
|
||||
if (*baseAddress == MAP_FAILED) {
|
||||
if (*baseAddress == MAP_FAILED)
|
||||
{
|
||||
std::cerr << "Could not mmap() " << fname << std::endl;
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
// Note FILE_FLAG_RANDOM_ACCESS is only a hint to Windows and as such may get ignored.
|
||||
HANDLE fd = CreateFile(fname.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr);
|
||||
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
return *baseAddress = nullptr, nullptr;
|
||||
|
||||
DWORD size_high;
|
||||
DWORD size_low = GetFileSize(fd, &size_high);
|
||||
|
||||
if (size_low % 64 != 16)
|
||||
{
|
||||
std::cerr << "Corrupt tablebase file " << fname << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
HANDLE mmap = CreateFileMapping(fd, nullptr, PAGE_READONLY, size_high, size_low, nullptr);
|
||||
CloseHandle(fd);
|
||||
|
||||
if (!mmap) {
|
||||
if (!mmap)
|
||||
{
|
||||
std::cerr << "CreateFileMapping() failed" << std::endl;
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*mapping = (uint64_t)mmap;
|
||||
*baseAddress = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0);
|
||||
|
||||
if (!*baseAddress) {
|
||||
if (!*baseAddress)
|
||||
{
|
||||
std::cerr << "MapViewOfFile() failed, name = " << fname
|
||||
<< ", error = " << GetLastError() << std::endl;
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
uint8_t* data = (uint8_t*)*baseAddress;
|
||||
@@ -254,7 +274,8 @@ public:
|
||||
constexpr uint8_t Magics[][4] = { { 0xD7, 0x66, 0x0C, 0xA5 },
|
||||
{ 0x71, 0xE8, 0x23, 0x5D } };
|
||||
|
||||
if (memcmp(data, Magics[type == WDL], 4)) {
|
||||
if (memcmp(data, Magics[type == WDL], 4))
|
||||
{
|
||||
std::cerr << "Corrupted table in file " << fname << std::endl;
|
||||
unmap(*baseAddress, *mapping);
|
||||
return *baseAddress = nullptr, nullptr;
|
||||
@@ -348,7 +369,7 @@ TBTable<WDL>::TBTable(const std::string& code) : TBTable() {
|
||||
hasPawns = pos.pieces(PAWN);
|
||||
|
||||
hasUniquePieces = false;
|
||||
for (Color c = WHITE; c <= BLACK; ++c)
|
||||
for (Color c : { WHITE, BLACK })
|
||||
for (PieceType pt = PAWN; pt < KING; ++pt)
|
||||
if (popcount(pos.pieces(c, pt)) == 1)
|
||||
hasUniquePieces = true;
|
||||
@@ -415,7 +436,7 @@ class TBTables {
|
||||
}
|
||||
}
|
||||
std::cerr << "TB hash table size too low!" << std::endl;
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -664,7 +685,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||
bool blackStronger = (pos.material_key() != entry->key);
|
||||
|
||||
int flipColor = (symmetricBlackToMove || blackStronger) * 8;
|
||||
int flipSquares = (symmetricBlackToMove || blackStronger) * 070;
|
||||
int flipSquares = (symmetricBlackToMove || blackStronger) * 56;
|
||||
int stm = (symmetricBlackToMove || blackStronger) ^ pos.side_to_move();
|
||||
|
||||
// For pawns, TB files store 4 separate tables according if leading pawn is on
|
||||
@@ -687,9 +708,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||
|
||||
std::swap(squares[0], *std::max_element(squares, squares + leadPawnsCnt, pawns_comp));
|
||||
|
||||
tbFile = file_of(squares[0]);
|
||||
if (tbFile > FILE_D)
|
||||
tbFile = file_of(squares[0] ^ 7); // Horizontal flip: SQ_H1 -> SQ_A1
|
||||
tbFile = map_to_queenside(file_of(squares[0]));
|
||||
}
|
||||
|
||||
// DTZ tables are one-sided, i.e. they store positions only for white to
|
||||
@@ -713,8 +732,8 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||
|
||||
// Then we reorder the pieces to have the same sequence as the one stored
|
||||
// in pieces[i]: the sequence that ensures the best compression.
|
||||
for (int i = leadPawnsCnt; i < size; ++i)
|
||||
for (int j = i; j < size; ++j)
|
||||
for (int i = leadPawnsCnt; i < size - 1; ++i)
|
||||
for (int j = i + 1; j < size; ++j)
|
||||
if (d->pieces[i] == pieces[j])
|
||||
{
|
||||
std::swap(pieces[i], pieces[j]);
|
||||
@@ -745,7 +764,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
||||
// piece is below RANK_5.
|
||||
if (rank_of(squares[0]) > RANK_4)
|
||||
for (int i = 0; i < size; ++i)
|
||||
squares[i] ^= 070; // Vertical flip: SQ_A8 -> SQ_A1
|
||||
squares[i] ^= SQ_A8; // Vertical flip: SQ_A8 -> SQ_A1
|
||||
|
||||
// Look for the first piece of the leading group not on the A1-D4 diagonal
|
||||
// and ensure it is mapped below the diagonal.
|
||||
@@ -1043,8 +1062,8 @@ void set(T& e, uint8_t* data) {
|
||||
|
||||
enum { Split = 1, HasPawns = 2 };
|
||||
|
||||
assert(e.hasPawns == !!(*data & HasPawns));
|
||||
assert((e.key != e.key2) == !!(*data & Split));
|
||||
assert(e.hasPawns == bool(*data & HasPawns));
|
||||
assert((e.key != e.key2) == bool(*data & Split));
|
||||
|
||||
data++; // First byte stores flags
|
||||
|
||||
@@ -1107,14 +1126,14 @@ void set(T& e, uint8_t* data) {
|
||||
template<TBType Type>
|
||||
void* mapped(TBTable<Type>& e, const Position& pos) {
|
||||
|
||||
static Mutex mutex;
|
||||
static std::mutex mutex;
|
||||
|
||||
// Use 'aquire' to avoid a thread reads 'ready' == true while another is
|
||||
// still working, this could happen due to compiler reordering.
|
||||
// Use 'acquire' to avoid a thread reading 'ready' == true while
|
||||
// another is still working. (compiler reordering may cause this).
|
||||
if (e.ready.load(std::memory_order_acquire))
|
||||
return e.baseAddress; // Could be nullptr if file does not exsist
|
||||
return e.baseAddress; // Could be nullptr if file does not exist
|
||||
|
||||
std::unique_lock<Mutex> lk(mutex);
|
||||
std::unique_lock<std::mutex> lk(mutex);
|
||||
|
||||
if (e.ready.load(std::memory_order_relaxed)) // Recheck under lock
|
||||
return e.baseAddress;
|
||||
|
||||
Reference in New Issue
Block a user