summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b97df4c)
Mostly comments fixing and other small things.
No functional change.
17 files changed:
#define BITCOUNT_H_INCLUDED
#include <cassert>
#define BITCOUNT_H_INCLUDED
#include <cassert>
#include "types.h"
enum BitCountType {
#include "types.h"
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.
/// 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;
const BitCountType Max15 = HasPopCnt ? CNT_HW_POPCNT : Is64Bit ? CNT_64_MAX15 : CNT_32_MAX15;
return (int)__popcnt64(b);
return (int)__popcnt64(b);
+#else // Assumed gcc or compatible compiler
return __builtin_popcountll(b);
return __builtin_popcountll(b);
KBPsK, // KB and pawns vs K
KQKRPs, // KQ vs KR and pawns
KBPsK, // KB and pawns vs K
KQKRPs, // KQ vs KR and pawns
-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) {}
struct Endgame : public EndgameBase<T> {
explicit Endgame(Color c) : strongSide(c), weakSide(~c) {}
/// The Endgames class stores the pointers to endgame evaluation and scaling
/// 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().
- 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
};
#endif // #ifndef ENDGAME_H_INCLUDED
#ifndef EVALUATE_H_INCLUDED
#define EVALUATE_H_INCLUDED
#ifndef EVALUATE_H_INCLUDED
#define EVALUATE_H_INCLUDED
#include "types.h"
class Position;
#include "types.h"
class Position;
// 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 {
// 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);
&& !(PseudoAttacks[Pt][from] & target & ci->checkSq[Pt]))
continue;
&& !(PseudoAttacks[Pt][from] & target & ci->checkSq[Pt]))
continue;
- if (unlikely(ci->dcCandidates) && (ci->dcCandidates & from))
+ if (ci->dcCandidates && (ci->dcCandidates & from))
enum GenType {
CAPTURES,
QUIETS,
enum GenType {
CAPTURES,
QUIETS,
+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);
template<GenType>
ExtMove* generate(const Position& pos, ExtMove* moveList);
Score pawns_score() const { return score; }
Bitboard pawn_attacks(Color c) const { return pawnAttacks[c]; }
Bitboard passed_pawns(Color c) const { return passedPawns[c]; }
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);
int semiopen_file(Color c, File f) const {
return semiopenFiles[c] & (1 << f);
return semiopenFiles[c] & (leftSide ? (1 << f) - 1 : ~((1 << (f + 1)) - 1));
}
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)];
}
int pawns_on_same_color_squares(Color c, Square s) const {
return pawnsOnSquares[c][!!(DarkSquares & s)];
}
return true;
// Is there a discovered check?
return true;
// Is there a discovered check?
- if ( unlikely(ci.dcCandidates)
&& (ci.dcCandidates & from)
&& !aligned(from, to, ci.ksq))
return true;
&& (ci.dcCandidates & from)
&& !aligned(from, to, ci.ksq))
return true;
st->checkersBB |= to;
// Discovered checks
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);
{
if (pt != ROOK)
st->checkersBB |= attacks_from<ROOK>(king_square(them)) & pieces(us, QUEEN, ROOK);
#include <cassert>
#include <cstddef> // For offsetof()
#include <cassert>
#include <cstddef> // For offsetof()
#include "bitboard.h"
#include "types.h"
#include "bitboard.h"
#include "types.h"
else if (ttHit)
{
// Never assume anything on values stored in TT
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?
eval = ss->staticEval = evaluate(pos);
// Can ttValue be used as a better position evaluation?
if (ttHit)
{
// Never assume anything on values stored in TT
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?
ss->staticEval = bestValue = evaluate(pos);
// Can ttValue be used as a better position evaluation?
#ifndef SEARCH_H_INCLUDED
#define SEARCH_H_INCLUDED
#ifndef SEARCH_H_INCLUDED
#define SEARCH_H_INCLUDED
+#include <memory> // For std::auto_ptr
#include <stack>
#include <vector>
#include <stack>
#include <vector>
-/// 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;
struct Stack {
SplitPoint* splitPoint;
bool skipEarlyPruning;
};
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; }
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;
void insert_pv_in_tt(Position& pos);
Value score;
typedef std::vector<RootMove> RootMoveVector;
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.
- 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;
}
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;
};
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.
/// The SignalsType struct stores volatile flags updated during the search
/// typically in an async fashion e.g. to stop the search by the GUI.
// Thread c'tor makes some init but does not launch any execution thread that
// will be started only when c'tor returns.
// 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;
searching = false;
maxPly = splitPointsSize = 0;
#include "position.h"
#include "search.h"
#include "position.h"
#include "search.h"
const int MAX_THREADS = 128;
const int MAX_SPLITPOINTS_PER_THREAD = 8;
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); }
struct Mutex {
Mutex() { lock_init(l); }
~Mutex() { lock_destroy(l); }
+
+/// SplitPoint struct stores information shared by the threads searching in
+/// parallel below the same split point. It is populated at splitting time.
MovePicker* movePicker;
SplitPoint* parentSplitPoint;
MovePicker* movePicker;
SplitPoint* parentSplitPoint;
+ // Shared variable data
Mutex mutex;
std::bitset<MAX_THREADS> slavesMask;
volatile bool allSlavesSearching;
Mutex mutex;
std::bitset<MAX_THREADS> slavesMask;
volatile bool allSlavesSearching;
Depth depth, int moveCount, MovePicker* movePicker, int nodeType, bool cutNode);
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
Depth depth, int moveCount, MovePicker* movePicker, int nodeType, bool cutNode);
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
+ Pawns::Table pawnsTable;
Material::Table materialTable;
Endgames endgames;
Material::Table materialTable;
Endgames endgames;
- Pawns::Table pawnsTable;
Position* activePosition;
size_t idx;
int maxPly;
Position* activePosition;
size_t idx;
int maxPly;
};
struct TimerThread : public ThreadBase {
};
struct TimerThread : public ThreadBase {
+
+ static const int Resolution = 5; // Millisec between two check_time() calls
+
TimerThread() : run(false) {}
virtual void idle_loop();
TimerThread() : run(false) {}
virtual void idle_loop();
- static const int Resolution = 5; // msec between two check_time() calls
struct ThreadPool : public std::vector<Thread*> {
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();
void read_uci_options();
Thread* available_slave(const Thread* master) const;
void wait_for_think_finished();
void TranspositionTable::resize(size_t mbSize) {
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)
size_t newClusterCount = size_t(1) << msb((mbSize * 1024 * 1024) / sizeof(TTCluster));
if (newClusterCount == clusterCount)
clusterCount = newClusterCount;
free(mem);
clusterCount = newClusterCount;
free(mem);
- mem = calloc(clusterCount * sizeof(TTCluster) + CACHE_LINE_SIZE - 1, 1);
+ mem = calloc(clusterCount * sizeof(TTCluster) + CacheLineSize - 1, 1);
- table = (TTCluster*)((uintptr_t(mem) + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1));
+ table = (TTCluster*)((uintptr_t(mem) + CacheLineSize - 1) & ~(CacheLineSize - 1));
TTEntry* const tte = first_entry(key);
const uint16_t key16 = key >> 48; // Use the high 16 bits as key inside the cluster
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)
if (!tte[i].key16 || tte[i].key16 == key16)
{
if (tte[i].key16)
// Find an entry to be replaced according to the replacement strategy
TTEntry* replace = tte;
// 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)
if ( (( tte[i].genBound8 & 0xFC) == generation8 || tte[i].bound() == BOUND_EXACT)
- ((replace->genBound8 & 0xFC) == generation8)
- (tte[i].depth8 < replace->depth8) < 0)
#include "misc.h"
#include "types.h"
#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
///
/// key 16 bit
/// move 16 bit
- 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;
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;
uint16_t key16;
uint16_t move16;
int16_t value16;
uint16_t key16;
uint16_t move16;
int16_t value16;
uint8_t genBound8;
int8_t depth8;
};
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
/// A TranspositionTable consists of a power of 2 number of clusters and each
/// cluster consists of TTClusterSize number of TTEntry. Each non-empty entry
class TranspositionTable {
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;
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();
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;
private:
size_t clusterCount;
TTCluster* table;
extern TranspositionTable TT;
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
#endif // #ifndef TT_H_INCLUDED
#ifndef TYPES_H_INCLUDED
#define TYPES_H_INCLUDED
#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
///
/// -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>
#include <cassert>
#include <cctype>
-#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
# 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
# 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(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__)
#ifdef _MSC_VER
# define FORCE_INLINE __forceinline
#elif defined(__GNUC__)
enum CastlingRight {
NO_CASTLING,
WHITE_OO,
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
};
ANY_CASTLING = WHITE_OO | WHITE_OOO | BLACK_OO | BLACK_OOO,
CASTLING_RIGHT_NB = 16
};
-/// 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 {
/// 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 {
SCORE_ENSURE_INTEGER_SIZE_N = INT_MIN
};
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) {
/// 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) {
}
inline Value eg_value(Score s) {
inline T& operator-=(T& d1, T d2) { return d1 = d1 - d2; } \
inline T& operator*=(T& d, int i) { return d = T(int(d) * i); }
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); } \
#define ENABLE_FULL_OPERATORS_ON(T) \
ENABLE_BASE_OPERATORS_ON(T) \
inline T& operator++(T& d) { return d = T(int(d) + 1); } \
ENABLE_FULL_OPERATORS_ON(File)
ENABLE_FULL_OPERATORS_ON(Rank)
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
#undef ENABLE_FULL_OPERATORS_ON
#undef ENABLE_BASE_OPERATORS_ON
extern Value PieceValue[PHASE_NB][PIECE_NB];
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);
}
inline Color operator~(Color c) {
return Color(c ^ BLACK);
}
}
inline bool is_ok(Move m) {
}
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
}
#endif // #ifndef TYPES_H_INCLUDED
Option(const char* v, OnChange = NULL);
Option(int v, int min, int max, OnChange = NULL);
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;
operator int() const;
operator std::string() const;
void init(OptionsMap&);
void loop(int argc, char* argv[]);
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);
std::string value(Value v);
std::string square(Square s);
std::string move(Move m, bool chess960);