Skip to content
Permalink
Browse files

Assorted trivial cleanups 5/2019

No functional change.

bench: 4178282
  • Loading branch information...
mcostalba committed May 2, 2019
1 parent 2ead74d commit d39bc2efa197ba2fd55b68eced1c60bcfe2facc1
Showing with 74 additions and 83 deletions.
  1. +14 −14 Readme.md
  2. +19 −18 src/endgame.cpp
  3. +4 −4 src/endgame.h
  4. +3 −5 src/evaluate.cpp
  5. +1 −1 src/main.cpp
  6. +0 −1 src/pawns.h
  7. +6 −6 src/position.cpp
  8. +18 −27 src/search.cpp
  9. +1 −1 src/search.h
  10. +4 −3 src/tt.cpp
  11. +1 −1 src/tt.h
  12. +3 −2 src/types.h
@@ -1,7 +1,7 @@
## Overview

[![Build Status](https://travis-ci.org/official-stockfish/Stockfish.svg?branch=master)](https://travis-ci.org/official-stockfish/Stockfish)
[![Build Status](https://ci.appveyor.com/api/projects/status/github/official-stockfish/Stockfish?svg=true)](https://ci.appveyor.com/project/mcostalba/stockfish)
[![Build Status](https://ci.appveyor.com/api/projects/status/github/official-stockfish/Stockfish?branch=master&svg=true)](https://ci.appveyor.com/project/mcostalba/stockfish/branch/master)

[Stockfish](https://stockfishchess.org) is a free, powerful UCI chess engine
derived from Glaurung 2.1. It is not a complete chess program and requires a
@@ -34,11 +34,11 @@ Currently, Stockfish has the following UCI options:
A positive value for contempt favors middle game positions and avoids draws.

* #### Analysis Contempt
By default, contempt is set to prefer the side to move. Set this option to "White"
By default, contempt is set to prefer the side to move. Set this option to "White"
or "Black" to analyse with contempt for that side, or "Off" to disable contempt.

* #### Threads
The number of CPU threads used for searching a position. For best performance, set
The number of CPU threads used for searching a position. For best performance, set
this equal to the number of CPU cores available.

* #### Hash
@@ -58,18 +58,18 @@ Currently, Stockfish has the following UCI options:
Lower the Skill Level in order to make Stockfish play weaker.

* #### Move Overhead
Assume a time delay of x ms due to network and GUI overheads. This is useful to
Assume a time delay of x ms due to network and GUI overheads. This is useful to
avoid losses on time in those cases.

* #### Minimum Thinking Time
Search for at least x ms per move.
Search for at least x ms per move.

* #### Slow Mover
Lower values will make Stockfish take less time in games, higher values will
Lower values will make Stockfish take less time in games, higher values will
make it think longer.

* #### nodestime
Tells the engine to use nodes searched instead of wall time to account for
Tells the engine to use nodes searched instead of wall time to account for
elapsed time. Useful for engine testing.

* #### UCI_Chess960
@@ -79,13 +79,13 @@ Currently, Stockfish has the following UCI options:
An option handled by your GUI.

* #### SyzygyPath
Path to the folders/directories storing the Syzygy tablebase files. Multiple
directories are to be separated by ";" on Windows and by ":" on Unix-based
Path to the folders/directories storing the Syzygy tablebase files. Multiple
directories are to be separated by ";" on Windows and by ":" on Unix-based
operating systems. Do not use spaces around the ";" or ":".

Example: `C:\tablebases\wdl345;C:\tablebases\wdl6;D:\tablebases\dtz345;D:\tablebases\dtz6`
It is recommended to store .rtbw files on an SSD. There is no loss in storing

It is recommended to store .rtbw files on an SSD. There is no loss in storing
the .rtbz files on a regular HD. It is recommended to verify all md5 checksums
of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will
lead to engine crashes.
@@ -153,7 +153,7 @@ community effort. There are a few ways to help contribute to its growth.
### Donating hardware

Improving Stockfish requires a massive amount of testing. You can donate
your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker)
your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker)
and view the current tests on [Fishtest](http://tests.stockfishchess.org/tests).

### Improving the code
@@ -169,7 +169,7 @@ generic rather than being focused on Stockfish's precise implementation.
Nevertheless, a helpful resource.

* The latest source can always be found on [GitHub](https://github.com/official-stockfish/Stockfish).
Discussions about Stockfish take place in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking)
Discussions about Stockfish take place in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking)
group and engine testing is done on [Fishtest](http://tests.stockfishchess.org/tests).
If you want to help improve Stockfish, please read this [guideline](https://github.com/glinscott/fishtest/wiki/Creating-my-first-test)
first, where the basics of Stockfish development are explained.
@@ -88,27 +88,28 @@ namespace Endgames {

void init() {

add<KPK>("KPK");
add<KNNK>("KNNK");
add<KBNK>("KBNK");
add<KRKP>("KRKP");
add<KRKB>("KRKB");
add<KRKN>("KRKN");
add<KQKP>("KQKP");
add<KQKR>("KQKR");
add<KNNKP>("KNNKP");

add<KNPK>("KNPK");
add<KNPKB>("KNPKB");
add<KRPKR>("KRPKR");
add<KRPKB>("KRPKB");
add<KBPKB>("KBPKB");
add<KBPKN>("KBPKN");
add<KBPPKB>("KBPPKB");
add<KRPPKRP>("KRPPKRP");
add<KPK>("KPK");
add<KNNK>("KNNK");
add<KBNK>("KBNK");
add<KRKP>("KRKP");
add<KRKB>("KRKB");
add<KRKN>("KRKN");
add<KQKP>("KQKP");
add<KQKR>("KQKR");
add<KNNKP>("KNNKP");

add<KNPK>("KNPK");
add<KNPKB>("KNPKB");
add<KRPKR>("KRPKR");
add<KRPKB>("KRPKB");
add<KBPKB>("KBPKB");
add<KBPKN>("KBPKN");
add<KBPPKB>("KBPPKB");
add<KRPPKRP>("KRPPKRP");
}
}


/// Mate with KX vs K. This function is used to evaluate positions with
/// king and plenty of material vs a lone king. It simply gives the
/// attacking side a bonus for driving the defending king towards the edge
@@ -91,17 +91,19 @@ struct Endgame : public EndgameBase<T> {
};


/// The Endgames class stores the pointers to endgame evaluation and scaling
/// The Endgames namespace handles the pointers to endgame evaluation and scaling
/// base objects in two std::map. We use polymorphism to invoke the actual
/// endgame function by calling its virtual operator().

namespace Endgames {

template<typename T> using Ptr = std::unique_ptr<EndgameBase<T>>;
template<typename T> using Map = std::map<Key, Ptr<T>>;

extern std::pair<Map<Value>, Map<ScaleFactor>> maps;

void init();

template<typename T>
Map<T>& map() {
return std::get<std::is_same<T, ScaleFactor>::value>(maps);
@@ -119,8 +121,6 @@ namespace Endgames {
const EndgameBase<T>* probe(Key key) {
return map<T>().count(key) ? map<T>()[key].get() : nullptr;
}

void init();
}

#endif // #ifndef ENDGAME_H_INCLUDED
@@ -190,10 +190,8 @@ namespace {
// color, including x-rays. But diagonal x-rays through pawns are not computed.
Bitboard attackedBy2[COLOR_NB];

// kingRing[color] are the squares adjacent to the king, plus (only for a
// king on its first rank) the squares two ranks in front. For instance,
// if black's king is on g8, kingRing[BLACK] is f8, h8, f7, g7, h7, f6, g6
// and h6.
// kingRing[color] are the squares adjacent to the king plus some other
// very near squares, depending on king position.
Bitboard kingRing[COLOR_NB];

// kingAttackersCount[color] is the number of pieces of the given color
@@ -802,7 +800,7 @@ namespace {

// Early exit if score is high
Value v = (mg_value(score) + eg_value(score)) / 2;
if (abs(v) > (LazyThreshold + pos.non_pawn_material() / 64))
if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
return pos.side_to_move() == WHITE ? v : -v;

// Main evaluation begins here
@@ -42,8 +42,8 @@ int main(int argc, char* argv[]) {
Bitboards::init();
Position::init();
Bitbases::init();
Search::init();
Endgames::init();
Search::init();
Threads.set(Options["Threads"]);
Search::clear(); // After threads are up

@@ -59,7 +59,6 @@ struct Entry {
Square kingSquares[COLOR_NB];
Score kingSafety[COLOR_NB];
int castlingRights[COLOR_NB];
int pawnsOnSquares[COLOR_NB][COLOR_NB]; // [color][light/dark squares]
};

typedef HashTable<Entry, 16384> Table;
@@ -387,7 +387,7 @@ void Position::set_state(StateInfo* si) const {
if (type_of(pc) == PAWN)
si->pawnKey ^= Zobrist::psq[pc][s];

else if (type_of(pc) != PAWN && type_of(pc) != KING)
else if (type_of(pc) != KING)
si->nonPawnMaterial[color_of(pc)] += PieceValue[MG][pc];
}

@@ -491,7 +491,7 @@ Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners
// Snipers are sliders that attack 's' when a piece and other snipers are removed
Bitboard snipers = ( (PseudoAttacks[ ROOK][s] & pieces(QUEEN, ROOK))
| (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders;
Bitboard occupancy = pieces() & ~snipers;
Bitboard occupancy = pieces() ^ snipers;

while (snipers)
{
@@ -1192,10 +1192,10 @@ bool Position::has_game_cycle(int ply) const {
if (ply > i)
return true;

// For nodes before or at the root, check that the move is a repetition one
// rather than a move to the current position.
// In the cuckoo table, both moves Rc1c5 and Rc5c1 are stored in the same
// location, so we have to select which square to check.
// For nodes before or at the root, check that the move is a
// repetition rather than a move to the current position.
// In the cuckoo table, both moves Rc1c5 and Rc5c1 are stored in
// the same location, so we have to select which square to check.
if (color_of(piece_on(empty(s1) ? s2 : s1)) != side_to_move())
continue;

@@ -149,7 +149,7 @@ namespace {
void Search::init() {

for (int i = 1; i < MAX_MOVES; ++i)
Reductions[i] = int(22.9 * std::log(i));
Reductions[i] = int(22.9 * std::log(i));
}


@@ -240,17 +240,13 @@ void MainThread::search() {
minScore = std::min(minScore, th->rootMoves[0].score);

// Vote according to score and depth, and select the best thread
int64_t bestVote = 0;
for (Thread* th : Threads)
{
votes[th->rootMoves[0].pv[0]] +=
(th->rootMoves[0].score - minScore + 14) * int(th->completedDepth);
(th->rootMoves[0].score - minScore + 14) * int(th->completedDepth);

if (votes[th->rootMoves[0].pv[0]] > bestVote)
{
bestVote = votes[th->rootMoves[0].pv[0]];
if (votes[th->rootMoves[0].pv[0]] > votes[bestThread->rootMoves[0].pv[0]])
bestThread = th;
}
}
}

@@ -538,13 +534,13 @@ namespace {
bool ttHit, ttPv, inCheck, givesCheck, improving;
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, ttCapture;
Piece movedPiece;
int moveCount, captureCount, quietCount;
int moveCount, captureCount, quietCount, singularLMR;

// Step 1. Initialize node
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
Color us = pos.side_to_move();
moveCount = captureCount = quietCount = ss->moveCount = 0;
moveCount = captureCount = quietCount = singularLMR = ss->moveCount = 0;
bestValue = -VALUE_INFINITE;
maxValue = VALUE_INFINITE;

@@ -589,10 +585,10 @@ namespace {
// starts with statScore = 0. Later grandchildren start with the last calculated
// statScore of the previous grandchild. This influences the reduction rules in
// LMR which are based on the statScore of parent position.
if (rootNode)
(ss + 4)->statScore = 0;
else
(ss + 2)->statScore = 0;
if (rootNode)
(ss + 4)->statScore = 0;
else
(ss + 2)->statScore = 0;

// Step 4. Transposition table lookup. We don't want the score of a partial
// search to overwrite a previous full search TT value, so we use a different
@@ -850,7 +846,6 @@ namespace {
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
moveCountPruning = false;
ttCapture = ttMove && pos.capture_or_promotion(ttMove);
int singularExtensionLMRmultiplier = 0;

// Step 12. Loop through all pseudo-legal moves until no moves remain
// or a beta cutoff occurs.
@@ -907,12 +902,13 @@ namespace {
ss->excludedMove = MOVE_NONE;

if (value < singularBeta)
{
{
extension = ONE_PLY;
singularExtensionLMRmultiplier++;
singularLMR++;

if (value < singularBeta - std::min(3 * depth / ONE_PLY, 39))
singularExtensionLMRmultiplier++;
}
singularLMR++;
}

// Multi-cut pruning
// Our ttMove is assumed to fail high, and now we failed high also on a reduced
@@ -1023,8 +1019,9 @@ namespace {
// Decrease reduction if opponent's move count is high (~10 Elo)
if ((ss-1)->moveCount > 15)
r -= ONE_PLY;

// Decrease reduction if move has been singularly extended
r -= singularExtensionLMRmultiplier * ONE_PLY;
r -= singularLMR * ONE_PLY;

if (!captureOrPromotion)
{
@@ -1060,7 +1057,7 @@ namespace {
r -= ss->statScore / 20000 * ONE_PLY;
}

Depth d = std::max(newDepth - std::max(r, DEPTH_ZERO), ONE_PLY);
Depth d = clamp(newDepth - r, ONE_PLY, newDepth);

value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);

@@ -1476,7 +1473,7 @@ namespace {
void update_capture_stats(const Position& pos, Move move,
Move* captures, int captureCount, int bonus) {

CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
Piece moved_piece = pos.moved_piece(move);
PieceType captured = type_of(pos.piece_on(to_sq(move)));

@@ -1715,10 +1712,4 @@ void Tablebases::rank_root_moves(Position& pos, Search::RootMoves& rootMoves) {
if (dtz_available || rootMoves[0].tbScore <= VALUE_DRAW)
Cardinality = 0;
}
else
{
// Assign the same rank to all moves
for (auto& m : rootMoves)
m.tbRank = 0;
}
}
@@ -69,7 +69,7 @@ struct RootMove {
Value score = -VALUE_INFINITE;
Value previousScore = -VALUE_INFINITE;
int selDepth = 0;
int tbRank;
int tbRank = 0;
Value tbScore;
std::vector<Move> pv;
};
@@ -43,15 +43,16 @@ void TTEntry::save(Key k, Value v, bool pv, Bound b, Depth d, Move m, Value ev)

// Overwrite less valuable entries
if ( (k >> 48) != key16
|| d / ONE_PLY + 10 > depth8
||(d - DEPTH_OFFSET) / ONE_PLY > depth8 - 4
|| b == BOUND_EXACT)
{
assert((d - DEPTH_OFFSET) / ONE_PLY >= 0);

key16 = (uint16_t)(k >> 48);
value16 = (int16_t)v;
eval16 = (int16_t)ev;
genBound8 = (uint8_t)(TT.generation8 | uint8_t(pv) << 2 | b);
assert((d - DEPTH_NONE) / ONE_PLY >= 0);
depth8 = (uint8_t)((d - DEPTH_NONE) / ONE_PLY);
depth8 = (uint8_t)((d - DEPTH_OFFSET) / ONE_PLY);
}
}

@@ -40,7 +40,7 @@ struct TTEntry {
Move move() const { return (Move )move16; }
Value value() const { return (Value)value16; }
Value eval() const { return (Value)eval16; }
Depth depth() const { return (Depth)(depth8 * int(ONE_PLY)) + DEPTH_NONE; }
Depth depth() const { return (Depth)(depth8 * int(ONE_PLY)) + DEPTH_OFFSET; }
bool is_pv() const { return (bool)(genBound8 & 0x4); }
Bound bound() const { return (Bound)(genBound8 & 0x3); }
void save(Key k, Value v, bool pv, Bound b, Depth d, Move m, Value ev);

0 comments on commit d39bc2e

Please sign in to comment.
You can’t perform that action at this time.