mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-24 02:57:11 +08:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
096351d1f5 | ||
|
|
6b96e6f33d | ||
|
|
f200f3ccd2 | ||
|
|
2bb555025f | ||
|
|
d5f2e32b5c | ||
|
|
83d8d54216 | ||
|
|
078354060e | ||
|
|
5973e09854 | ||
|
|
22ede4442c | ||
|
|
deee18c758 | ||
|
|
0693ff178e | ||
|
|
57c51dd1ef | ||
|
|
f902ddaa89 | ||
|
|
24485df3df |
15
Readme.txt
15
Readme.txt
@@ -8,8 +8,8 @@ Chess Partner, or Fritz) in order to be used comfortably. Read the
|
||||
documentation for your GUI of choice for information about how to use
|
||||
Stockfish with your GUI.
|
||||
|
||||
This version of Stockfish supports up to 8 CPUs, but has not been
|
||||
tested thoroughly with more than 2. The program tries to detect the
|
||||
This version of Stockfish supports up to 16 CPUs, but has not been
|
||||
tested thoroughly with more than 4. The program tries to detect the
|
||||
number of CPUs on your computer and set the number of search threads
|
||||
accordingly, but please be aware that the detection is not always
|
||||
correct. It is therefore recommended to inspect the value of the
|
||||
@@ -41,10 +41,10 @@ This distribution of Stockfish consists of the following files:
|
||||
3. Opening books
|
||||
----------------
|
||||
|
||||
This version of Stockfish has experimental support for PolyGlot opening
|
||||
books. For information about how to create such books, consult the
|
||||
PolyGlot documentation. The book file can be selected by setting the
|
||||
UCI parameter "Book File".
|
||||
This version of Stockfish has support for PolyGlot opening books.
|
||||
For information about how to create such books, consult the PolyGlot
|
||||
documentation. The book file can be selected by setting the UCI
|
||||
parameter "Book File".
|
||||
|
||||
|
||||
4. Compiling it yourself
|
||||
@@ -64,6 +64,9 @@ On 64 bit Unix-like systems the 'bsfq' assembly instruction will be used
|
||||
for bit counting. Detection is automatic at compile time, but in case you
|
||||
experience compile problems you can comment out #define USE_BSFQ line in types.h
|
||||
|
||||
In general is recommended to run 'make help' to see a list of make targets
|
||||
with corresponding descriptions.
|
||||
|
||||
|
||||
5. Terms of use
|
||||
---------------
|
||||
|
||||
@@ -43,6 +43,10 @@ Passed Pawn Extension (PV nodes) = 1
|
||||
Passed Pawn Extension (non-PV nodes) = 0
|
||||
Pawn Endgame Extension (PV nodes) = 2
|
||||
Pawn Endgame Extension (non-PV nodes) = 2
|
||||
Randomness = 0
|
||||
Minimum Split Depth = 4
|
||||
Maximum Number of Threads per Split Point = 5
|
||||
Use Sleeping Threads = false
|
||||
Emergency Move Horizon = 40
|
||||
Emergency Base Time = 200
|
||||
Emergency Move Time = 70
|
||||
Minimum Thinking Time = 20
|
||||
|
||||
@@ -125,7 +125,7 @@ void benchmark(int argc, char* argv[]) {
|
||||
{
|
||||
Move moves[1] = { MOVE_NONE };
|
||||
int dummy[2] = { 0, 0 };
|
||||
Position pos(*it, 0);
|
||||
Position pos(*it, false, 0);
|
||||
cerr << "\nBench position: " << cnt << '/' << positions.size() << endl << endl;
|
||||
if (valType == "perft")
|
||||
{
|
||||
|
||||
@@ -248,7 +248,6 @@ namespace {
|
||||
void init_attacks();
|
||||
void init_between_bitboards();
|
||||
void init_pseudo_attacks();
|
||||
SquareDelta squares_delta(Square orig, Square dest);
|
||||
Bitboard index_to_bitboard(int index, Bitboard mask);
|
||||
Bitboard sliding_attacks(int sq, Bitboard block, int dirs, int deltas[][2],
|
||||
int fmin, int fmax, int rmin, int rmax);
|
||||
@@ -288,10 +287,10 @@ void init_bitboards() {
|
||||
|
||||
init_masks();
|
||||
init_attacks();
|
||||
init_between_bitboards();
|
||||
init_sliding_attacks(RAttacks, RAttackIndex, RMask, RShift, RMult, rookDeltas);
|
||||
init_sliding_attacks(BAttacks, BAttackIndex, BMask, BShift, BMult, bishopDeltas);
|
||||
init_pseudo_attacks();
|
||||
init_between_bitboards();
|
||||
}
|
||||
|
||||
|
||||
@@ -454,40 +453,27 @@ namespace {
|
||||
return result;
|
||||
}
|
||||
|
||||
SquareDelta squares_delta(Square orig, Square dest) {
|
||||
|
||||
const SquareDelta deltas[] = { DELTA_N, DELTA_NE, DELTA_E, DELTA_SE,
|
||||
DELTA_S, DELTA_SW, DELTA_W, DELTA_NW };
|
||||
|
||||
for (int idx = 0; idx < 8; idx++)
|
||||
{
|
||||
Square s = orig + deltas[idx];
|
||||
|
||||
while (square_is_ok(s) && square_distance(s, s - deltas[idx]) == 1)
|
||||
{
|
||||
if (s == dest)
|
||||
return deltas[idx];
|
||||
|
||||
s += deltas[idx];
|
||||
}
|
||||
}
|
||||
return DELTA_NONE;
|
||||
}
|
||||
|
||||
void init_between_bitboards() {
|
||||
|
||||
Square s1, s2, s3;
|
||||
SquareDelta d;
|
||||
int f, r;
|
||||
|
||||
for (s1 = SQ_A1; s1 <= SQ_H8; s1++)
|
||||
for (s2 = SQ_A1; s2 <= SQ_H8; s2++)
|
||||
{
|
||||
BetweenBB[s1][s2] = EmptyBoardBB;
|
||||
d = squares_delta(s1, s2);
|
||||
|
||||
if (d != DELTA_NONE)
|
||||
if (bit_is_set(QueenPseudoAttacks[s1], s2))
|
||||
{
|
||||
f = file_distance(s1, s2);
|
||||
r = rank_distance(s1, s2);
|
||||
|
||||
d = SquareDelta(s2 - s1) / Max(f, r);
|
||||
|
||||
for (s3 = s1 + d; s3 != s2; s3 += d)
|
||||
set_bit(&(BetweenBB[s1][s2]), s3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ enum SquareColor {
|
||||
LIGHT
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(Color);
|
||||
ENABLE_OPERATORS_ON(Color)
|
||||
|
||||
|
||||
////
|
||||
|
||||
@@ -38,6 +38,6 @@ enum Depth {
|
||||
DEPTH_NONE = -127 * ONE_PLY
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(Depth);
|
||||
ENABLE_OPERATORS_ON(Depth)
|
||||
|
||||
#endif // !defined(DEPTH_H_INCLUDED)
|
||||
|
||||
@@ -168,6 +168,11 @@ namespace {
|
||||
// right to castle.
|
||||
const Value TrappedRookPenalty = Value(180);
|
||||
|
||||
// Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
|
||||
// a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
|
||||
// happen in Chess960 games.
|
||||
const Score TrappedBishopA1H1Penalty = make_score(100, 100);
|
||||
|
||||
// The SpaceMask[Color] contains the area of the board which is considered
|
||||
// by the space evaluation. In the middle game, each side is given a bonus
|
||||
// based on how many squares inside this area are safe and available for
|
||||
@@ -556,6 +561,28 @@ namespace {
|
||||
bonus += (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
|
||||
}
|
||||
|
||||
// Special extra evaluation for bishops
|
||||
if (Piece == BISHOP && pos.is_chess960())
|
||||
{
|
||||
// An important Chess960 pattern: A cornered bishop blocked by
|
||||
// a friendly pawn diagonally in front of it is a very serious
|
||||
// problem, especially when that pawn is also blocked.
|
||||
if (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1))
|
||||
{
|
||||
SquareDelta d = pawn_push(Us)
|
||||
+ (square_file(s) == FILE_A ? DELTA_E : DELTA_W);
|
||||
if (pos.piece_on(s + d) == piece_of_color_and_type(Us, PAWN))
|
||||
{
|
||||
if (!pos.square_is_empty(s + d + pawn_push(Us)))
|
||||
bonus -= 2*TrappedBishopA1H1Penalty;
|
||||
else if (pos.piece_on(s + 2*d) == piece_of_color_and_type(Us, PAWN))
|
||||
bonus -= TrappedBishopA1H1Penalty;
|
||||
else
|
||||
bonus -= TrappedBishopA1H1Penalty / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special extra evaluation for rooks
|
||||
if (Piece == ROOK)
|
||||
{
|
||||
|
||||
21
src/lock.h
21
src/lock.h
@@ -44,6 +44,25 @@ typedef pthread_cond_t WaitCondition;
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
|
||||
// Default fast and race free locks and condition variables
|
||||
#if !defined(OLD_LOCKS)
|
||||
|
||||
typedef SRWLOCK Lock;
|
||||
typedef CONDITION_VARIABLE WaitCondition;
|
||||
|
||||
# define lock_init(x) InitializeSRWLock(x)
|
||||
# define lock_grab(x) AcquireSRWLockExclusive(x)
|
||||
# define lock_release(x) ReleaseSRWLockExclusive(x)
|
||||
# define lock_destroy(x) (x)
|
||||
# define cond_destroy(x) (x)
|
||||
# define cond_init(x) InitializeConditionVariable(x)
|
||||
# define cond_signal(x) WakeConditionVariable(x)
|
||||
# define cond_wait(x,y) SleepConditionVariableSRW(x, y, INFINITE,0)
|
||||
|
||||
// Fallback solution to build for Windows XP and older versions, note that
|
||||
// cond_wait() is racy between lock_release() and WaitForSingleObject().
|
||||
#else
|
||||
|
||||
typedef CRITICAL_SECTION Lock;
|
||||
typedef HANDLE WaitCondition;
|
||||
|
||||
@@ -57,4 +76,6 @@ typedef HANDLE WaitCondition;
|
||||
# define cond_wait(x,y) { lock_release(y); WaitForSingleObject(*x, INFINITE); lock_grab(y); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(LOCK_H_INCLUDED)
|
||||
|
||||
@@ -192,7 +192,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
|
||||
|
||||
// Clear the MaterialInfo object, and set its key
|
||||
memset(mi, 0, sizeof(MaterialInfo));
|
||||
mi->factor[WHITE] = mi->factor[BLACK] = uint8_t(SCALE_FACTOR_NORMAL);
|
||||
mi->factor[WHITE] = mi->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
|
||||
mi->key = key;
|
||||
|
||||
// Store game phase
|
||||
@@ -353,7 +353,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
|
||||
}
|
||||
matValue += sign * v;
|
||||
}
|
||||
mi->value = int16_t(matValue / 16);
|
||||
mi->value = (int16_t)(matValue / 16);
|
||||
return mi;
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ Key EndgameFunctions::buildKey(const string& keyCode) {
|
||||
}
|
||||
fen += char(8 - keyCode.length() + '0');
|
||||
fen += "/8/8/8/8/8/8/8 w - -";
|
||||
return Position(fen, 0).get_material_key();
|
||||
return Position(fen, false, 0).get_material_key();
|
||||
}
|
||||
|
||||
const string EndgameFunctions::swapColors(const string& keyCode) {
|
||||
|
||||
@@ -58,7 +58,7 @@ using namespace std;
|
||||
/// Version number. If this is left empty, the current date (in the format
|
||||
/// YYMMDD) is used as a version number.
|
||||
|
||||
static const string EngineVersion = "2.0";
|
||||
static const string EngineVersion = "2.0.1";
|
||||
static const string AppName = "Stockfish";
|
||||
static const string AppTag = "";
|
||||
|
||||
|
||||
@@ -562,7 +562,7 @@ namespace {
|
||||
|
||||
if (Type == CHECK)
|
||||
{
|
||||
// Condider only pawn moves which give direct checks
|
||||
// Consider only pawn moves which give direct checks
|
||||
b1 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||
b2 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ enum Piece {
|
||||
BP = 9, BN = 10, BB = 11, BR = 12, BQ = 13, BK = 14, PIECE_NONE = 16
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(PieceType);
|
||||
ENABLE_OPERATORS_ON(Piece);
|
||||
ENABLE_OPERATORS_ON(PieceType)
|
||||
ENABLE_OPERATORS_ON(Piece)
|
||||
|
||||
|
||||
////
|
||||
|
||||
@@ -152,9 +152,9 @@ Position::Position(const Position& pos, int th) {
|
||||
nodes = 0;
|
||||
}
|
||||
|
||||
Position::Position(const string& fen, int th) {
|
||||
Position::Position(const string& fen, bool isChess960, int th) {
|
||||
|
||||
from_fen(fen);
|
||||
from_fen(fen, isChess960);
|
||||
threadID = th;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ void Position::detach() {
|
||||
/// string. This function is not very robust - make sure that input FENs are
|
||||
/// correct (this is assumed to be the responsibility of the GUI).
|
||||
|
||||
void Position::from_fen(const string& fen) {
|
||||
void Position::from_fen(const string& fen, bool c960) {
|
||||
/*
|
||||
A FEN string defines a particular position using only the ASCII character set.
|
||||
|
||||
@@ -274,10 +274,7 @@ void Position::from_fen(const string& fen) {
|
||||
castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO;
|
||||
castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO;
|
||||
|
||||
isChess960 = initialKFile != FILE_E
|
||||
|| initialQRFile != FILE_A
|
||||
|| initialKRFile != FILE_H;
|
||||
|
||||
isChess960 = c960;
|
||||
find_checkers();
|
||||
|
||||
st->key = compute_key();
|
||||
|
||||
@@ -134,10 +134,10 @@ public:
|
||||
|
||||
// Constructors
|
||||
Position(const Position& pos, int threadID);
|
||||
Position(const std::string& fen, int threadID);
|
||||
Position(const std::string& fen, bool isChess960, int threadID);
|
||||
|
||||
// Text input/output
|
||||
void from_fen(const std::string& fen);
|
||||
void from_fen(const std::string& fen, bool isChess960);
|
||||
const std::string to_fen() const;
|
||||
void print(Move m = MOVE_NONE) const;
|
||||
|
||||
|
||||
@@ -513,6 +513,9 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[
|
||||
<< move_to_san(pos, ponderMove) // Works also with MOVE_NONE
|
||||
<< endl;
|
||||
|
||||
// Return from think() with unchanged position
|
||||
pos.undo_move(bestMove);
|
||||
|
||||
LogFile.close();
|
||||
}
|
||||
|
||||
@@ -903,7 +906,7 @@ namespace {
|
||||
|
||||
// Write PV lines to transposition table, in case the relevant entries
|
||||
// have been overwritten during the search.
|
||||
for (int i = 0; i < MultiPV; i++)
|
||||
for (int i = 0; i < Min(MultiPV, (int)rml.size()); i++)
|
||||
rml[i].insert_pv_in_tt(pos);
|
||||
|
||||
return alpha;
|
||||
|
||||
@@ -68,10 +68,10 @@ enum SquareDelta {
|
||||
DELTA_NW = DELTA_N + DELTA_W
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(Square);
|
||||
ENABLE_OPERATORS_ON(File);
|
||||
ENABLE_OPERATORS_ON(Rank);
|
||||
ENABLE_OPERATORS_ON(SquareDelta);
|
||||
ENABLE_OPERATORS_ON(Square)
|
||||
ENABLE_OPERATORS_ON(File)
|
||||
ENABLE_OPERATORS_ON(Rank)
|
||||
ENABLE_OPERATORS_ON(SquareDelta)
|
||||
|
||||
|
||||
////
|
||||
|
||||
10
src/tt.h
10
src/tt.h
@@ -59,10 +59,10 @@ public:
|
||||
|
||||
key32 = k;
|
||||
data = (m & 0x1FFFF) | (t << 21) | (g << 23);
|
||||
value16 = int16_t(v);
|
||||
depth16 = int16_t(d);
|
||||
staticValue = int16_t(statV);
|
||||
staticValueMargin = int16_t(kd);
|
||||
value16 = (int16_t)v;
|
||||
depth16 = (int16_t)d;
|
||||
staticValue = (int16_t)statV;
|
||||
staticValueMargin = (int16_t)kd;
|
||||
}
|
||||
void set_generation(int g) { data = move() | (type() << 21) | (g << 23); }
|
||||
|
||||
@@ -132,7 +132,7 @@ extern TranspositionTable TT;
|
||||
|
||||
inline TTEntry* TranspositionTable::first_entry(const Key posKey) const {
|
||||
|
||||
return entries[uint32_t(posKey) & (size - 1)].data;
|
||||
return entries[((uint32_t)posKey) & (size - 1)].data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
76
src/types.h
76
src/types.h
@@ -70,6 +70,10 @@ typedef uint64_t Bitboard;
|
||||
//// -DUSE_POPCNT | Add runtime support for use of popcnt asm-instruction.
|
||||
//// | Works only in 64-bit mode. For compiling requires hardware
|
||||
//// | with popcnt support. Around 4% speed-up.
|
||||
////
|
||||
//// -DOLD_LOCKS | By default under Windows are used the fast Slim Reader/Writer (SRW)
|
||||
//// | Locks and Condition Variables: these are not supported by Windows XP
|
||||
//// | and older, to compile for those platforms you should enable OLD_LOCKS.
|
||||
|
||||
// Automatic detection for 64-bit under Windows
|
||||
#if defined(_WIN64)
|
||||
@@ -113,64 +117,20 @@ inline void __cpuid(int CPUInfo[4], int)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Operators used by enum types like Depth, Piece, Square and so on.
|
||||
|
||||
// Templetized operators used by enum types like Depth, Piece, Square and so on.
|
||||
// We don't want to write the same inline for each different enum. Note that we
|
||||
// pass by value to silence scaring warnings when using volatiles.
|
||||
// Because these templates override common operators and are included in all the
|
||||
// files, there is a possibility that the compiler silently performs some unwanted
|
||||
// overrides. To avoid possible very nasty bugs the templates are disabled by default
|
||||
// and must be enabled for each type on a case by case base. The enabling trick
|
||||
// uses template specialization, namely we just declare following struct.
|
||||
template<typename T> struct TempletizedOperator;
|
||||
|
||||
// Then to enable the enum type we use following macro that defines a specialization
|
||||
// of TempletizedOperator for the given enum T. Here is defined typedef Not_Enabled.
|
||||
// Name of typedef is chosen to produce somewhat informative compile error messages.
|
||||
#define ENABLE_OPERATORS_ON(T) \
|
||||
template<> struct TempletizedOperator<T> { typedef T Not_Enabled; }
|
||||
|
||||
// Finally we use macro OK(T) to check if type T is enabled. The macro simply
|
||||
// tries to use Not_Enabled, if was not previously defined a compile error occurs.
|
||||
// The check is done fully at compile time and there is zero overhead at runtime.
|
||||
#define OK(T) typedef typename TempletizedOperator<T>::Not_Enabled Type
|
||||
|
||||
template<typename T>
|
||||
inline T operator+ (const T d1, const T d2) { OK(T); return T(int(d1) + int(d2)); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator- (const T d1, const T d2) { OK(T); return T(int(d1) - int(d2)); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator* (int i, const T d) { OK(T); return T(i * int(d)); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator* (const T d, int i) { OK(T); return T(int(d) * i); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator/ (const T d, int i) { OK(T); return T(int(d) / i); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator- (const T d) { OK(T); return T(-int(d)); }
|
||||
|
||||
template<typename T>
|
||||
inline T operator++ (T& d, int) { OK(T); d = T(int(d) + 1); return d; }
|
||||
|
||||
template<typename T>
|
||||
inline T operator-- (T& d, int) { OK(T); d = T(int(d) - 1); return d; }
|
||||
|
||||
template<typename T>
|
||||
inline void operator+= (T& d1, const T d2) { OK(T); d1 = d1 + d2; }
|
||||
|
||||
template<typename T>
|
||||
inline void operator-= (T& d1, const T d2) { OK(T); d1 = d1 - d2; }
|
||||
|
||||
template<typename T>
|
||||
inline void operator*= (T& d, int i) { OK(T); d = T(int(d) * i); }
|
||||
|
||||
template<typename T>
|
||||
inline void operator/= (T& d, int i) { OK(T); d = T(int(d) / i); }
|
||||
|
||||
#undef OK
|
||||
#define ENABLE_OPERATORS_ON(T) \
|
||||
inline T operator+ (const T d1, const T d2) { return T(int(d1) + int(d2)); } \
|
||||
inline T operator- (const T d1, const T d2) { return T(int(d1) - int(d2)); } \
|
||||
inline T operator* (int i, const T d) { return T(i * int(d)); } \
|
||||
inline T operator* (const T d, int i) { return T(int(d) * i); } \
|
||||
inline T operator/ (const T d, int i) { return T(int(d) / i); } \
|
||||
inline T operator- (const T d) { return T(-int(d)); } \
|
||||
inline T operator++ (T& d, int) {d = T(int(d) + 1); return d; } \
|
||||
inline T operator-- (T& d, int) { d = T(int(d) - 1); return d; } \
|
||||
inline void operator+= (T& d1, const T d2) { d1 = d1 + d2; } \
|
||||
inline void operator-= (T& d1, const T d2) { d1 = d1 - d2; } \
|
||||
inline void operator*= (T& d, int i) { d = T(int(d) * i); } \
|
||||
inline void operator/= (T& d, int i) { d = T(int(d) / i); }
|
||||
|
||||
#endif // !defined(TYPES_H_INCLUDED)
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace {
|
||||
|
||||
bool execute_uci_command(const string& cmd) {
|
||||
|
||||
static Position pos(StartPositionFEN, 0); // The root position
|
||||
static Position pos(StartPositionFEN, false, 0); // The root position
|
||||
UCIParser up(cmd);
|
||||
string token;
|
||||
|
||||
@@ -84,7 +84,7 @@ bool execute_uci_command(const string& cmd) {
|
||||
cout << "uciok" << endl;
|
||||
}
|
||||
else if (token == "ucinewgame")
|
||||
pos.from_fen(StartPositionFEN);
|
||||
pos.from_fen(StartPositionFEN, false);
|
||||
|
||||
else if (token == "isready")
|
||||
cout << "readyok" << endl;
|
||||
@@ -147,7 +147,7 @@ namespace {
|
||||
|
||||
if (token == "startpos")
|
||||
{
|
||||
pos.from_fen(StartPositionFEN);
|
||||
pos.from_fen(StartPositionFEN, false);
|
||||
if (!(up >> token))
|
||||
return;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ namespace {
|
||||
fen += token;
|
||||
fen += ' ';
|
||||
}
|
||||
pos.from_fen(fen);
|
||||
pos.from_fen(fen, Options["UCI_Chess960"].value<bool>());
|
||||
}
|
||||
|
||||
if (token != "moves")
|
||||
|
||||
16
src/value.h
16
src/value.h
@@ -43,7 +43,7 @@ enum Value {
|
||||
VALUE_ENSURE_SIGNED = -1
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(Value);
|
||||
ENABLE_OPERATORS_ON(Value)
|
||||
|
||||
|
||||
enum ScaleFactor {
|
||||
@@ -66,9 +66,6 @@ enum Score {
|
||||
SCORE_ENSURE_32_BITS_SIZE_N = -(1 << 16)
|
||||
};
|
||||
|
||||
ENABLE_OPERATORS_ON(Score);
|
||||
|
||||
|
||||
// Extracting the _signed_ lower and upper 16 bits it 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.
|
||||
@@ -91,6 +88,17 @@ inline Score operator/(Score s, int i) { return make_score(mg_value(s) / i, eg_v
|
||||
// a very high risk of overflow. So user should explicitly convert to integer.
|
||||
inline Score operator*(Score s1, Score s2);
|
||||
|
||||
// Rest of operators are standard:
|
||||
inline Score operator+ (const Score d1, const Score d2) { return Score(int(d1) + int(d2)); }
|
||||
inline Score operator- (const Score d1, const Score d2) { return Score(int(d1) - int(d2)); }
|
||||
inline Score operator* (int i, const Score d) { return Score(i * int(d)); }
|
||||
inline Score operator* (const Score d, int i) { return Score(int(d) * i); }
|
||||
inline Score operator- (const Score d) { return Score(-int(d)); }
|
||||
inline void operator+= (Score& d1, const Score d2) { d1 = d1 + d2; }
|
||||
inline void operator-= (Score& d1, const Score d2) { d1 = d1 - d2; }
|
||||
inline void operator*= (Score& d, int i) { d = Score(int(d) * i); }
|
||||
inline void operator/= (Score& d, int i) { d = Score(int(d) / i); }
|
||||
|
||||
|
||||
////
|
||||
//// Inline functions
|
||||
|
||||
Reference in New Issue
Block a user