mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Assorted headers cleanup
Mostly comments fixing and other small things. No functional change.
This commit is contained in:
parent
b97df4c236
commit
4eb2d8ce09
17 changed files with 132 additions and 123 deletions
|
@ -22,6 +22,7 @@
|
|||
#define BITCOUNT_H_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
enum BitCountType {
|
||||
|
@ -35,7 +36,7 @@ enum BitCountType {
|
|||
/// Determine at compile time the best popcount<> specialization according to
|
||||
/// whether the platform is 32 or 64 bit, the maximum number of non-zero
|
||||
/// bits to count and if the hardware popcnt instruction is available.
|
||||
const BitCountType Full = HasPopCnt ? CNT_HW_POPCNT : Is64Bit ? CNT_64 : CNT_32;
|
||||
const BitCountType Full = HasPopCnt ? CNT_HW_POPCNT : Is64Bit ? CNT_64 : CNT_32;
|
||||
const BitCountType Max15 = HasPopCnt ? CNT_HW_POPCNT : Is64Bit ? CNT_64_MAX15 : CNT_32_MAX15;
|
||||
|
||||
|
||||
|
@ -94,7 +95,7 @@ inline int popcount<CNT_HW_POPCNT>(Bitboard b) {
|
|||
|
||||
return (int)__popcnt64(b);
|
||||
|
||||
#else
|
||||
#else // Assumed gcc or compatible compiler
|
||||
|
||||
return __builtin_popcountll(b);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum EndgameType {
|
|||
|
||||
|
||||
// Scaling functions
|
||||
SCALE_FUNS,
|
||||
SCALING_FUNCTIONS,
|
||||
|
||||
KBPsK, // KB and pawns vs K
|
||||
KQKRPs, // KQ vs KR and pawns
|
||||
|
@ -81,7 +81,7 @@ struct EndgameBase {
|
|||
};
|
||||
|
||||
|
||||
template<EndgameType E, typename T = typename eg_fun<(E > SCALE_FUNS)>::type>
|
||||
template<EndgameType E, typename T = typename eg_fun<(E > SCALING_FUNCTIONS)>::type>
|
||||
struct Endgame : public EndgameBase<T> {
|
||||
|
||||
explicit Endgame(Color c) : strongSide(c), weakSide(~c) {}
|
||||
|
@ -94,8 +94,8 @@ private:
|
|||
|
||||
|
||||
/// The Endgames class stores the pointers to endgame evaluation and scaling
|
||||
/// base objects in two std::map typedefs. We then use polymorphism to invoke
|
||||
/// the actual endgame function by calling its virtual operator().
|
||||
/// base objects in two std::map. We use polymorphism to invoke the actual
|
||||
/// endgame function by calling its virtual operator().
|
||||
|
||||
class Endgames {
|
||||
|
||||
|
@ -114,8 +114,9 @@ public:
|
|||
Endgames();
|
||||
~Endgames();
|
||||
|
||||
template<typename T> T probe(Key key, T& eg)
|
||||
{ return eg = map(eg).count(key) ? map(eg)[key] : NULL; }
|
||||
template<typename T> T probe(Key key, T& eg) {
|
||||
return eg = map(eg).count(key) ? map(eg)[key] : NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef ENDGAME_H_INCLUDED
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef EVALUATE_H_INCLUDED
|
||||
#define EVALUATE_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Position;
|
||||
|
|
|
@ -49,9 +49,9 @@ struct Entry {
|
|||
// the position. For instance, in KBP vs K endgames, the scaling function looks
|
||||
// for rook pawns and wrong-colored bishops.
|
||||
ScaleFactor scale_factor(const Position& pos, Color c) const {
|
||||
|
||||
return !scalingFunction[c] || (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE
|
||||
? ScaleFactor(factor[c]) : (*scalingFunction[c])(pos);
|
||||
return !scalingFunction[c]
|
||||
|| (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE ? ScaleFactor(factor[c])
|
||||
: (*scalingFunction[c])(pos);
|
||||
}
|
||||
|
||||
Key key;
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace {
|
|||
&& !(PseudoAttacks[Pt][from] & target & ci->checkSq[Pt]))
|
||||
continue;
|
||||
|
||||
if (unlikely(ci->dcCandidates) && (ci->dcCandidates & from))
|
||||
if (ci->dcCandidates && (ci->dcCandidates & from))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
class Position;
|
||||
|
||||
enum GenType {
|
||||
CAPTURES,
|
||||
QUIETS,
|
||||
|
@ -31,7 +33,14 @@ enum GenType {
|
|||
LEGAL
|
||||
};
|
||||
|
||||
class Position;
|
||||
struct ExtMove {
|
||||
Move move;
|
||||
Value value;
|
||||
};
|
||||
|
||||
inline bool operator<(const ExtMove& f, const ExtMove& s) {
|
||||
return f.value < s.value;
|
||||
}
|
||||
|
||||
template<GenType>
|
||||
ExtMove* generate(const Position& pos, ExtMove* moveList);
|
||||
|
|
|
@ -35,6 +35,7 @@ struct Entry {
|
|||
Score pawns_score() const { return score; }
|
||||
Bitboard pawn_attacks(Color c) const { return pawnAttacks[c]; }
|
||||
Bitboard passed_pawns(Color c) const { return passedPawns[c]; }
|
||||
int pawn_span(Color c) const { return pawnSpan[c]; }
|
||||
|
||||
int semiopen_file(Color c, File f) const {
|
||||
return semiopenFiles[c] & (1 << f);
|
||||
|
@ -44,10 +45,6 @@ struct Entry {
|
|||
return semiopenFiles[c] & (leftSide ? (1 << f) - 1 : ~((1 << (f + 1)) - 1));
|
||||
}
|
||||
|
||||
int pawn_span(Color c) const {
|
||||
return pawnSpan[c];
|
||||
}
|
||||
|
||||
int pawns_on_same_color_squares(Color c, Square s) const {
|
||||
return pawnsOnSquares[c][!!(DarkSquares & s)];
|
||||
}
|
||||
|
|
|
@ -641,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;
|
||||
|
@ -870,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);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <cstddef> // For offsetof()
|
||||
#include <string>
|
||||
|
||||
#include "bitboard.h"
|
||||
#include "types.h"
|
||||
|
|
|
@ -584,7 +584,7 @@ namespace {
|
|||
else if (ttHit)
|
||||
{
|
||||
// Never assume anything on values stored in TT
|
||||
if ((ss->staticEval = eval = tte->eval_value()) == VALUE_NONE)
|
||||
if ((ss->staticEval = eval = tte->eval()) == VALUE_NONE)
|
||||
eval = ss->staticEval = evaluate(pos);
|
||||
|
||||
// Can ttValue be used as a better position evaluation?
|
||||
|
@ -1165,7 +1165,7 @@ moves_loop: // When in check and at SpNode search starts from here
|
|||
if (ttHit)
|
||||
{
|
||||
// Never assume anything on values stored in TT
|
||||
if ((ss->staticEval = bestValue = tte->eval_value()) == VALUE_NONE)
|
||||
if ((ss->staticEval = bestValue = tte->eval()) == VALUE_NONE)
|
||||
ss->staticEval = bestValue = evaluate(pos);
|
||||
|
||||
// Can ttValue be used as a better position evaluation?
|
||||
|
|
30
src/search.h
30
src/search.h
|
@ -20,7 +20,7 @@
|
|||
#ifndef SEARCH_H_INCLUDED
|
||||
#define SEARCH_H_INCLUDED
|
||||
|
||||
#include <memory>
|
||||
#include <memory> // For std::auto_ptr
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
|
@ -32,9 +32,9 @@ struct SplitPoint;
|
|||
|
||||
namespace Search {
|
||||
|
||||
/// The Stack struct keeps track of the information we need to remember from
|
||||
/// nodes shallower and deeper in the tree during the search. Each search thread
|
||||
/// has its own array of Stack objects, indexed by the current ply.
|
||||
/// Stack struct keeps track of the information we need to remember from nodes
|
||||
/// shallower and deeper in the tree during the search. Each search thread has
|
||||
/// its own array of Stack objects, indexed by the current ply.
|
||||
|
||||
struct Stack {
|
||||
SplitPoint* splitPoint;
|
||||
|
@ -49,18 +49,16 @@ struct Stack {
|
|||
bool skipEarlyPruning;
|
||||
};
|
||||
|
||||
/// RootMove struct is used for moves at the root of the tree. For each root move
|
||||
/// we store a score and a PV (really a refutation in the case of moves which
|
||||
/// fail low). Score is normally set at -VALUE_INFINITE for all non-pv moves.
|
||||
|
||||
/// RootMove struct is used for moves at the root of the tree. For each root
|
||||
/// move we store a score, a node count, and a PV (really a refutation in the
|
||||
/// case of moves which fail low). Score is normally set at -VALUE_INFINITE for
|
||||
/// all non-pv moves.
|
||||
struct RootMove {
|
||||
|
||||
RootMove(Move m) : score(-VALUE_INFINITE), previousScore(-VALUE_INFINITE), pv(1, m) {}
|
||||
|
||||
bool operator<(const RootMove& m) const { return score > m.score; } // Ascending sort
|
||||
bool operator==(const Move& m) const { return pv[0] == m; }
|
||||
|
||||
void insert_pv_in_tt(Position& pos);
|
||||
|
||||
Value score;
|
||||
|
@ -70,24 +68,26 @@ struct RootMove {
|
|||
|
||||
typedef std::vector<RootMove> RootMoveVector;
|
||||
|
||||
/// The LimitsType struct stores information sent by GUI about available time
|
||||
/// to search the current move, maximum depth/time, if we are in analysis mode
|
||||
/// or if we have to ponder while it's our opponent's turn to move.
|
||||
/// LimitsType struct stores information sent by GUI about available time to
|
||||
/// search the current move, maximum depth/time, if we are in analysis mode or
|
||||
/// if we have to ponder while it's our opponent's turn to move.
|
||||
|
||||
struct LimitsType {
|
||||
|
||||
LimitsType() { // Using memset on a std::vector is undefined behavior
|
||||
LimitsType() { // Init explicitly due to broken value-initialization of non POD in MSVC
|
||||
nodes = time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] = movestogo =
|
||||
depth = movetime = mate = infinite = ponder = 0;
|
||||
}
|
||||
bool use_time_management() const { return !(mate | movetime | depth | nodes | infinite); }
|
||||
|
||||
bool use_time_management() const {
|
||||
return !(mate | movetime | depth | nodes | infinite);
|
||||
}
|
||||
|
||||
std::vector<Move> searchmoves;
|
||||
int time[COLOR_NB], inc[COLOR_NB], movestogo, depth, movetime, mate, infinite, ponder;
|
||||
int64_t nodes;
|
||||
};
|
||||
|
||||
|
||||
/// The SignalsType struct stores volatile flags updated during the search
|
||||
/// typically in an async fashion e.g. to stop the search by the GUI.
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ void ThreadBase::wait_for(volatile const bool& condition) {
|
|||
// Thread c'tor makes some init but does not launch any execution thread that
|
||||
// will be started only when c'tor returns.
|
||||
|
||||
Thread::Thread() /* : splitPoints() */ { // Value-initialization bug in MSVC
|
||||
Thread::Thread() /* : splitPoints() */ { // Initialization of non POD broken in MSVC
|
||||
|
||||
searching = false;
|
||||
maxPly = splitPointsSize = 0;
|
||||
|
|
24
src/thread.h
24
src/thread.h
|
@ -29,9 +29,14 @@
|
|||
#include "position.h"
|
||||
#include "search.h"
|
||||
|
||||
struct Thread;
|
||||
|
||||
const int MAX_THREADS = 128;
|
||||
const int MAX_SPLITPOINTS_PER_THREAD = 8;
|
||||
|
||||
/// Mutex and ConditionVariable struct are wrappers of the low level locking
|
||||
/// machinery and are modeled after the corresponding C++11 classes.
|
||||
|
||||
struct Mutex {
|
||||
Mutex() { lock_init(l); }
|
||||
~Mutex() { lock_destroy(l); }
|
||||
|
@ -57,7 +62,9 @@ private:
|
|||
WaitCondition c;
|
||||
};
|
||||
|
||||
struct Thread;
|
||||
|
||||
/// SplitPoint struct stores information shared by the threads searching in
|
||||
/// parallel below the same split point. It is populated at splitting time.
|
||||
|
||||
struct SplitPoint {
|
||||
|
||||
|
@ -74,7 +81,7 @@ struct SplitPoint {
|
|||
MovePicker* movePicker;
|
||||
SplitPoint* parentSplitPoint;
|
||||
|
||||
// Shared data
|
||||
// Shared variable data
|
||||
Mutex mutex;
|
||||
std::bitset<MAX_THREADS> slavesMask;
|
||||
volatile bool allSlavesSearching;
|
||||
|
@ -121,9 +128,9 @@ struct Thread : public ThreadBase {
|
|||
Depth depth, int moveCount, MovePicker* movePicker, int nodeType, bool cutNode);
|
||||
|
||||
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
|
||||
Pawns::Table pawnsTable;
|
||||
Material::Table materialTable;
|
||||
Endgames endgames;
|
||||
Pawns::Table pawnsTable;
|
||||
Position* activePosition;
|
||||
size_t idx;
|
||||
int maxPly;
|
||||
|
@ -143,10 +150,13 @@ struct MainThread : public Thread {
|
|||
};
|
||||
|
||||
struct TimerThread : public ThreadBase {
|
||||
|
||||
static const int Resolution = 5; // Millisec between two check_time() calls
|
||||
|
||||
TimerThread() : run(false) {}
|
||||
virtual void idle_loop();
|
||||
|
||||
bool run;
|
||||
static const int Resolution = 5; // msec between two check_time() calls
|
||||
};
|
||||
|
||||
|
||||
|
@ -156,10 +166,10 @@ struct TimerThread : public ThreadBase {
|
|||
|
||||
struct ThreadPool : public std::vector<Thread*> {
|
||||
|
||||
void init(); // No c'tor and d'tor, threads rely on globals that should
|
||||
void exit(); // be initialized and are valid during the whole thread lifetime.
|
||||
void init(); // No c'tor and d'tor, threads rely on globals that should be
|
||||
void exit(); // initialized and are valid during the whole thread lifetime.
|
||||
|
||||
MainThread* main() { return static_cast<MainThread*>((*this)[0]); }
|
||||
MainThread* main() { return static_cast<MainThread*>(at(0)); }
|
||||
void read_uci_options();
|
||||
Thread* available_slave(const Thread* master) const;
|
||||
void wait_for_think_finished();
|
||||
|
|
10
src/tt.cpp
10
src/tt.cpp
|
@ -32,6 +32,8 @@ TranspositionTable TT; // Our global transposition table
|
|||
|
||||
void TranspositionTable::resize(size_t mbSize) {
|
||||
|
||||
assert(sizeof(TTCluster) == CacheLineSize / 2);
|
||||
|
||||
size_t newClusterCount = size_t(1) << msb((mbSize * 1024 * 1024) / sizeof(TTCluster));
|
||||
|
||||
if (newClusterCount == clusterCount)
|
||||
|
@ -40,7 +42,7 @@ void TranspositionTable::resize(size_t mbSize) {
|
|||
clusterCount = newClusterCount;
|
||||
|
||||
free(mem);
|
||||
mem = calloc(clusterCount * sizeof(TTCluster) + CACHE_LINE_SIZE - 1, 1);
|
||||
mem = calloc(clusterCount * sizeof(TTCluster) + CacheLineSize - 1, 1);
|
||||
|
||||
if (!mem)
|
||||
{
|
||||
|
@ -49,7 +51,7 @@ void TranspositionTable::resize(size_t mbSize) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
table = (TTCluster*)((uintptr_t(mem) + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1));
|
||||
table = (TTCluster*)((uintptr_t(mem) + CacheLineSize - 1) & ~(CacheLineSize - 1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +77,7 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
|
|||
TTEntry* const tte = first_entry(key);
|
||||
const uint16_t key16 = key >> 48; // Use the high 16 bits as key inside the cluster
|
||||
|
||||
for (unsigned i = 0; i < TTClusterSize; ++i)
|
||||
for (int i = 0; i < TTClusterSize; ++i)
|
||||
if (!tte[i].key16 || tte[i].key16 == key16)
|
||||
{
|
||||
if (tte[i].key16)
|
||||
|
@ -86,7 +88,7 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
|
|||
|
||||
// Find an entry to be replaced according to the replacement strategy
|
||||
TTEntry* replace = tte;
|
||||
for (unsigned i = 1; i < TTClusterSize; ++i)
|
||||
for (int i = 1; i < TTClusterSize; ++i)
|
||||
if ( (( tte[i].genBound8 & 0xFC) == generation8 || tte[i].bound() == BOUND_EXACT)
|
||||
- ((replace->genBound8 & 0xFC) == generation8)
|
||||
- (tte[i].depth8 < replace->depth8) < 0)
|
||||
|
|
59
src/tt.h
59
src/tt.h
|
@ -23,7 +23,7 @@
|
|||
#include "misc.h"
|
||||
#include "types.h"
|
||||
|
||||
/// The TTEntry is the 10 bytes transposition table entry, defined as below:
|
||||
/// TTEntry struct is the 10 bytes transposition table entry, defined as below:
|
||||
///
|
||||
/// key 16 bit
|
||||
/// move 16 bit
|
||||
|
@ -35,22 +35,22 @@
|
|||
|
||||
struct TTEntry {
|
||||
|
||||
Move move() const { return (Move )move16; }
|
||||
Value value() const { return (Value)value16; }
|
||||
Value eval_value() const { return (Value)evalValue; }
|
||||
Depth depth() const { return (Depth)depth8; }
|
||||
Bound bound() const { return (Bound)(genBound8 & 0x3); }
|
||||
Move move() const { return (Move )move16; }
|
||||
Value value() const { return (Value)value16; }
|
||||
Value eval() const { return (Value)eval16; }
|
||||
Depth depth() const { return (Depth)depth8; }
|
||||
Bound bound() const { return (Bound)(genBound8 & 0x3); }
|
||||
|
||||
void save(Key k, Value v, Bound b, Depth d, Move m, Value ev, uint8_t g) {
|
||||
|
||||
if (m || (k >> 48) != key16) // Preserve any existing move for the same position
|
||||
move16 = (uint16_t)m;
|
||||
|
||||
key16 = (uint16_t)(k >> 48);
|
||||
value16 = (int16_t)v;
|
||||
evalValue = (int16_t)ev;
|
||||
genBound8 = (uint8_t)(g | b);
|
||||
depth8 = (int8_t)d;
|
||||
key16 = (uint16_t)(k >> 48);
|
||||
value16 = (int16_t)v;
|
||||
eval16 = (int16_t)ev;
|
||||
genBound8 = (uint8_t)(g | b);
|
||||
depth8 = (int8_t)d;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -59,22 +59,11 @@ private:
|
|||
uint16_t key16;
|
||||
uint16_t move16;
|
||||
int16_t value16;
|
||||
int16_t evalValue;
|
||||
int16_t eval16;
|
||||
uint8_t genBound8;
|
||||
int8_t depth8;
|
||||
};
|
||||
|
||||
/// TTCluster is a 32 bytes cluster of TT entries consisting of:
|
||||
///
|
||||
/// 3 x TTEntry (3 x 10 bytes)
|
||||
/// padding (2 bytes)
|
||||
|
||||
static const unsigned TTClusterSize = 3;
|
||||
|
||||
struct TTCluster {
|
||||
TTEntry entry[TTClusterSize];
|
||||
char padding[2];
|
||||
};
|
||||
|
||||
/// A TranspositionTable consists of a power of 2 number of clusters and each
|
||||
/// cluster consists of TTClusterSize number of TTEntry. Each non-empty entry
|
||||
|
@ -84,15 +73,27 @@ struct TTCluster {
|
|||
|
||||
class TranspositionTable {
|
||||
|
||||
static const int CacheLineSize = 64;
|
||||
static const int TTClusterSize = 3;
|
||||
|
||||
struct TTCluster {
|
||||
TTEntry entry[TTClusterSize];
|
||||
char padding[2]; // Align to the cache line size
|
||||
};
|
||||
|
||||
public:
|
||||
~TranspositionTable() { free(mem); }
|
||||
void new_search() { generation8 += 4; } // Lower 2 bits are used by Bound
|
||||
uint8_t generation() const { return generation8; }
|
||||
TTEntry* probe(const Key key, bool& found) const;
|
||||
TTEntry* first_entry(const Key key) const;
|
||||
void resize(size_t mbSize);
|
||||
void clear();
|
||||
|
||||
// The lowest order bits of the key are used to get the index of the cluster
|
||||
TTEntry* first_entry(const Key key) const {
|
||||
return &table[(size_t)key & (clusterCount - 1)].entry[0];
|
||||
}
|
||||
|
||||
private:
|
||||
size_t clusterCount;
|
||||
TTCluster* table;
|
||||
|
@ -102,14 +103,4 @@ private:
|
|||
|
||||
extern TranspositionTable TT;
|
||||
|
||||
|
||||
/// TranspositionTable::first_entry() returns a pointer to the first entry of
|
||||
/// a cluster given a position. The lowest order bits of the key are used to
|
||||
/// get the index of the cluster inside the table.
|
||||
|
||||
inline TTEntry* TranspositionTable::first_entry(const Key key) const {
|
||||
|
||||
return &table[(size_t)key & (clusterCount - 1)].entry[0];
|
||||
}
|
||||
|
||||
#endif // #ifndef TT_H_INCLUDED
|
||||
|
|
72
src/types.h
72
src/types.h
|
@ -20,20 +20,19 @@
|
|||
#ifndef TYPES_H_INCLUDED
|
||||
#define TYPES_H_INCLUDED
|
||||
|
||||
/// For Linux and OSX configuration is done automatically using Makefile. To get
|
||||
/// started type 'make help'.
|
||||
/// When compiling with provided Makefile (e.g. for Linux and OSX), configuration
|
||||
/// is done automatically. To get started type 'make help'.
|
||||
///
|
||||
/// For Windows, part of the configuration is detected automatically, but some
|
||||
/// switches need to be set manually:
|
||||
/// When Makefile is not used (e.g. with Microsoft Visual Studio) some switches
|
||||
/// need to be set manually:
|
||||
///
|
||||
/// -DNDEBUG | Disable debugging mode. Always use this.
|
||||
/// -DNDEBUG | Disable debugging mode. Always use this for release.
|
||||
///
|
||||
/// -DNO_PREFETCH | Disable use of prefetch asm-instruction. A must if you want
|
||||
/// | the executable to run on some very old machines.
|
||||
/// -DNO_PREFETCH | Disable use of prefetch asm-instruction. You may need this to
|
||||
/// | run on some very old machines.
|
||||
///
|
||||
/// -DUSE_POPCNT | Add runtime support for use of popcnt asm-instruction. Works
|
||||
/// | only in 64-bit mode. For compiling requires hardware with
|
||||
/// | popcnt support.
|
||||
/// | only in 64-bit mode and requires hardware with popcnt support.
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
|
@ -42,30 +41,34 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#define unlikely(x) (x) // For code annotation purposes
|
||||
/// Predefined macros hell:
|
||||
///
|
||||
/// __GNUC__ Compiler is gcc, Clang or Intel on Linux
|
||||
/// __INTEL_COMPILER Compiler is Intel
|
||||
/// _MSC_VER Compiler is MSVC or Intel on Windows
|
||||
/// _WIN32 Building on Windows (any)
|
||||
/// _WIN64 Building on Windows 64 bit
|
||||
|
||||
#if defined(_WIN64) && !defined(IS_64BIT)
|
||||
#if defined(_WIN64) && !defined(IS_64BIT) // Last condition means Makefile is not used
|
||||
# include <intrin.h> // MSVC popcnt and bsfq instrinsics
|
||||
# define IS_64BIT
|
||||
# define USE_BSFQ
|
||||
#endif
|
||||
|
||||
#if defined(USE_POPCNT) && defined(_MSC_VER) && defined(__INTEL_COMPILER)
|
||||
#if defined(USE_POPCNT) && defined(__INTEL_COMPILER) && defined(_MSC_VER)
|
||||
# include <nmmintrin.h> // Intel header for _mm_popcnt_u64() intrinsic
|
||||
#endif
|
||||
|
||||
#if !defined(NO_PREFETCH) && (defined(__INTEL_COMPILER) || defined(_MSC_VER))
|
||||
# include <xmmintrin.h> // Intel and Microsoft header for _mm_prefetch()
|
||||
#endif
|
||||
|
||||
#if defined(USE_PEXT)
|
||||
# include <immintrin.h> // Header for _pext_u64() intrinsic
|
||||
#else
|
||||
# define _pext_u64(b, m) (0)
|
||||
#endif
|
||||
|
||||
# if !defined(NO_PREFETCH) && (defined(__INTEL_COMPILER) || defined(_MSC_VER))
|
||||
# include <xmmintrin.h> // Intel and Microsoft header for _mm_prefetch()
|
||||
# endif
|
||||
|
||||
#define CACHE_LINE_SIZE 64
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define FORCE_INLINE __forceinline
|
||||
#elif defined(__GNUC__)
|
||||
|
@ -133,9 +136,9 @@ enum CastlingSide {
|
|||
enum CastlingRight {
|
||||
NO_CASTLING,
|
||||
WHITE_OO,
|
||||
WHITE_OOO = WHITE_OO << 1,
|
||||
BLACK_OO = WHITE_OO << 2,
|
||||
BLACK_OOO = WHITE_OO << 3,
|
||||
WHITE_OOO = WHITE_OO << 1,
|
||||
BLACK_OO = WHITE_OO << 2,
|
||||
BLACK_OOO = WHITE_OO << 3,
|
||||
ANY_CASTLING = WHITE_OO | WHITE_OOO | BLACK_OO | BLACK_OOO,
|
||||
CASTLING_RIGHT_NB = 16
|
||||
};
|
||||
|
@ -251,9 +254,9 @@ enum Rank {
|
|||
};
|
||||
|
||||
|
||||
/// The Score enum stores a middlegame and an endgame value in a single integer
|
||||
/// (enum). The least significant 16 bits are used to store the endgame value
|
||||
/// and the upper 16 bits are used to store the middlegame value. The compiler
|
||||
/// Score enum stores a middlegame and an endgame value in a single integer.
|
||||
/// The least significant 16 bits are used to store the endgame value and
|
||||
/// the upper 16 bits are used to store the middlegame value. The compiler
|
||||
/// is free to choose the enum type as long as it can store the data, so we
|
||||
/// ensure that Score is an integer type by assigning some big int values.
|
||||
enum Score {
|
||||
|
@ -262,13 +265,15 @@ enum Score {
|
|||
SCORE_ENSURE_INTEGER_SIZE_N = INT_MIN
|
||||
};
|
||||
|
||||
inline Score make_score(int mg, int eg) { return Score((mg << 16) + eg); }
|
||||
inline Score make_score(int mg, int eg) {
|
||||
return Score((mg << 16) + eg);
|
||||
}
|
||||
|
||||
/// Extracting the signed lower and upper 16 bits is not so trivial because
|
||||
/// according to the standard a simple cast to short is implementation defined
|
||||
/// and so is a right shift of a signed integer.
|
||||
inline Value mg_value(Score s) {
|
||||
return Value(((s + 0x8000) & ~0xffff) / 0x10000);
|
||||
return Value(((s + 0x8000) & ~0xFFFF) / 0x10000);
|
||||
}
|
||||
|
||||
inline Value eg_value(Score s) {
|
||||
|
@ -285,8 +290,6 @@ inline T& operator+=(T& d1, T d2) { return d1 = d1 + d2; } \
|
|||
inline T& operator-=(T& d1, T d2) { return d1 = d1 - d2; } \
|
||||
inline T& operator*=(T& d, int i) { return d = T(int(d) * i); }
|
||||
|
||||
ENABLE_BASE_OPERATORS_ON(Score)
|
||||
|
||||
#define ENABLE_FULL_OPERATORS_ON(T) \
|
||||
ENABLE_BASE_OPERATORS_ON(T) \
|
||||
inline T& operator++(T& d) { return d = T(int(d) + 1); } \
|
||||
|
@ -304,6 +307,8 @@ ENABLE_FULL_OPERATORS_ON(Square)
|
|||
ENABLE_FULL_OPERATORS_ON(File)
|
||||
ENABLE_FULL_OPERATORS_ON(Rank)
|
||||
|
||||
ENABLE_BASE_OPERATORS_ON(Score)
|
||||
|
||||
#undef ENABLE_FULL_OPERATORS_ON
|
||||
#undef ENABLE_BASE_OPERATORS_ON
|
||||
|
||||
|
@ -324,15 +329,6 @@ inline Score operator/(Score s, int i) {
|
|||
|
||||
extern Value PieceValue[PHASE_NB][PIECE_NB];
|
||||
|
||||
struct ExtMove {
|
||||
Move move;
|
||||
Value value;
|
||||
};
|
||||
|
||||
inline bool operator<(const ExtMove& f, const ExtMove& s) {
|
||||
return f.value < s.value;
|
||||
}
|
||||
|
||||
inline Color operator~(Color c) {
|
||||
return Color(c ^ BLACK);
|
||||
}
|
||||
|
@ -429,7 +425,7 @@ inline Move make(Square from, Square to, PieceType pt = KNIGHT) {
|
|||
}
|
||||
|
||||
inline bool is_ok(Move m) {
|
||||
return from_sq(m) != to_sq(m); // Catch also MOVE_NULL and MOVE_NONE
|
||||
return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
|
||||
}
|
||||
|
||||
#endif // #ifndef TYPES_H_INCLUDED
|
||||
|
|
|
@ -50,8 +50,8 @@ public:
|
|||
Option(const char* v, OnChange = NULL);
|
||||
Option(int v, int min, int max, OnChange = NULL);
|
||||
|
||||
Option& operator=(const std::string& v);
|
||||
void operator<<(const Option& o);
|
||||
Option& operator=(const std::string&);
|
||||
void operator<<(const Option&);
|
||||
operator int() const;
|
||||
operator std::string() const;
|
||||
|
||||
|
@ -66,7 +66,6 @@ private:
|
|||
|
||||
void init(OptionsMap&);
|
||||
void loop(int argc, char* argv[]);
|
||||
|
||||
std::string value(Value v);
|
||||
std::string square(Square s);
|
||||
std::string move(Move m, bool chess960);
|
||||
|
|
Loading…
Add table
Reference in a new issue