]> git.sesse.net Git - stockfish/commitdiff
Merge branch 'master' of /srv/git.sesse.net/www/stockfish
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Apr 2019 20:33:19 +0000 (22:33 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 12 Apr 2019 20:33:19 +0000 (22:33 +0200)
21 files changed:
.travis.yml
AUTHORS
appveyor.yml
src/Makefile
src/bitboard.h
src/endgame.cpp
src/evaluate.cpp
src/evaluate.h
src/material.h
src/misc.cpp
src/movegen.cpp
src/pawns.cpp
src/pawns.h
src/position.cpp
src/position.h
src/psqt.cpp
src/search.cpp
src/syzygy/tbprobe.cpp
src/thread.cpp
src/tt.cpp
src/types.h

index ded29e479cd7866019686dc72e92416676082b7c..ea5bda1d2bb15e915642ad191f00ef30f8d55385 100644 (file)
@@ -1,6 +1,6 @@
 language: cpp
 sudo: required
-dist: trusty
+dist: xenial
 
 matrix:
   include:
@@ -9,21 +9,21 @@ matrix:
       addons:
         apt:
           sources: ['ubuntu-toolchain-r-test']
-          packages: ['g++-7', 'g++-7-multilib', 'g++-multilib', 'valgrind', 'expect', 'curl']
+          packages: ['g++-8', 'g++-8-multilib', 'g++-multilib', 'valgrind', 'expect', 'curl']
       env:
-        - COMPILER=g++-7
+        - COMPILER=g++-8
         - COMP=gcc
 
     - os: linux
       compiler: clang
       addons:
         apt:
-          sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0']
-          packages: ['clang-5.0', 'llvm-5.0-dev', 'g++-multilib', 'valgrind', 'expect', 'curl']
+          sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-xenial-6.0']
+          packages: ['clang-6.0', 'llvm-6.0-dev', 'g++-multilib', 'valgrind', 'expect', 'curl']
       env:
-        - COMPILER=clang++-5.0
+        - COMPILER=clang++-6.0
         - COMP=clang
-        - LDFLAGS=-fuse-ld=gold
+        - LDFLAGS=-fuse-ld=lld
 
     - os: osx
       compiler: gcc
@@ -34,7 +34,7 @@ matrix:
     - os: osx
       compiler: clang
       env:
-        - COMPILER=clang++ V='Apple LLVM 6.0' # Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
+        - COMPILER=clang++ V='Apple LLVM 9.4.1' # Apple LLVM version 9.1.0 (clang-902.0.39.2)
         - COMP=clang
 
 branches:
@@ -69,6 +69,6 @@ script:
   #
   # Sanitizer
   #
-  # Use g++-7 as a proxy for having sanitizers, might need revision as they become available for more recent versions of clang/gcc
-  - if [[ "$COMPILER" == "g++-7" ]]; then make clean && make -j2 ARCH=x86-64 sanitize=undefined optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-undefined; fi
-  - if [[ "$COMPILER" == "g++-7" ]]; then make clean && make -j2 ARCH=x86-64 sanitize=thread    optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-thread; fi
+  # Use g++-8 as a proxy for having sanitizers, might need revision as they become available for more recent versions of clang/gcc
+  - if [[ "$COMPILER" == "g++-8" ]]; then make clean && make -j2 ARCH=x86-64 sanitize=undefined optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-undefined; fi
+  - if [[ "$COMPILER" == "g++-8" ]]; then make clean && make -j2 ARCH=x86-64 sanitize=thread    optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-thread; fi
diff --git a/AUTHORS b/AUTHORS
index 04fc7d0fb0b432411fac19d7dedbd2ffa317519a..603b0fb370aa760460067f7f5b95b5b2c44bb833 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,11 @@
-# List of authors for Stockfish, updated just after version 9
+# List of authors for Stockfish, updated for version 10
 
 Tord Romstad (romstad)
 Marco Costalba (mcostalba)
 Joona Kiiski (zamar)
 Gary Linscott (glinscott)
 
-absimaldata
+Aditya (absimaldata)
 Ajith Chandy Jose (ajithcj)
 Alain Savard (Rocky640)
 Alexander Kure
@@ -20,9 +20,9 @@ Balint Pfliegel
 Ben Koshy (BKSpurgeon)
 Bill Henry (VoyagerOne)
 braich
+Bojun Guo (noobpwnftw)
 Brian Sheppard (SapphireBrand)
 Bryan Cross (crossbr)
-Bujun Guo (noobpwnftw)
 Chris Cain (ceebo)
 Dan Schmidt
 Daniel Dugovic (ddugovic)
@@ -31,7 +31,6 @@ David Zar
 Daylen Yang (daylen)
 DiscanX
 Eelco de Groot
-ElbertoOne
 erbsenzaehler
 Ernesto Gatti
 Fabian Beuke (madnight)
@@ -55,10 +54,12 @@ Hongzhi Cheng
 Ivan Ivec (IIvec)
 Jacques B. (Timshel)
 Jan Ondruš (hxim)
+Jared Kish (Kurtbusch)
 Jarrod Torriero (DU-jdto)
 Jean-Francois Romang (jromang)
 Jerry Donald Watson (jerrydonaldwatson)
 Jonathan Calovski (Mysseno)
+Jonathan D. (SFisGOD)
 Joost VandeVondele (vondele)
 Jörg Oster (joergoster)
 Joseph Ellis (jhellis3)
@@ -70,10 +71,11 @@ Ken Takusagawa
 kinderchocolate
 Kiran Panditrao (Krgp)
 Kojirion
-Leonardo Ljubičić (GM)
+Leonardo Ljubičić (ICCF World Champion)
 Leonid Pechenik (lp--)
 Linus Arver
 loco-loco
+Lub van den Berg (ElbertoOne)
 Luca Brivio (lucabrivio)
 Lucas Braesch (lucasart)
 Lyudmil Antonov (lantonov)
@@ -86,7 +88,7 @@ Michael Chaly (Vizvezdenec)
 Michel Van den Bergh (vdbergh)
 Miguel Lahoz (miguel-l)
 Mikael Bäckman (mbootsector)
-Mike Whiteley (protonspring)
+Michael Whiteley (protonspring)
 Miroslav Fontán (Hexik)
 Moez Jellouli (MJZ1977)
 Mohammed Li (tthsqe12)
@@ -111,6 +113,7 @@ Ron Britvich (Britvich)
 Ronald de Man (syzygy1)
 Ryan Schmitt
 Ryan Takker
+Sebastian Buchwald (UniQP)
 Sergei Antonov (saproj)
 sf-x
 shane31
index c81869b58dbc6b7bcf626c42d3d7bab0c598ba70..21f3bbe326b20d8ba4a79ee1c3ac2b8f5f3d306a 100644 (file)
@@ -7,7 +7,7 @@ branches:
     - appveyor
 
 # Operating system (build VM template)
-os: Visual Studio 2015
+os: Visual Studio 2017
 
 # Build platform, i.e. x86, x64, AnyCPU. This setting is optional.
 platform:
@@ -51,7 +51,7 @@ before_build:
       $b = git log HEAD | sls "\b[Bb]ench[ :]+[0-9]{7}" | select -first 1
       $bench = $b -match '\D+(\d+)' | % { $matches[1] }
       Write-Host "Reference bench:" $bench
-      $g = "Visual Studio 14 2015"
+      $g = "Visual Studio 15 2017"
       If (${env:PLATFORM} -eq 'x64') { $g = $g + ' Win64' }
       cmake -G "${g}" .
       Write-Host "Generated files for: " $g
index c314e7d88b7cca0d6fb9e540809e6ed434b99ab7..1314092e79c43770d3e723c5140aea7bd12ba8ba 100644 (file)
@@ -551,7 +551,8 @@ GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
        $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
 
 #LDFLAGS += -Wl,-Bstatic -Wl,-\( -lprotobuf -lgrpc++_unsecure -lgrpc_unsecure -lgrpc -lz -Wl,-\) -Wl,-Bdynamic -ldl
-LDFLAGS += /usr/lib/x86_64-linux-gnu/libprotobuf.a /usr/lib/libgrpc++_unsecure.a /usr/lib/libgrpc_unsecure.a /usr/lib/libgrpc.a /usr/lib/x86_64-linux-gnu/libcares.a -ldl -lz
+LDFLAGS += /usr/lib/x86_64-linux-gnu/libprotobuf.a /usr/lib/x86_64-linux-gnu/libgrpc++_unsecure.a /usr/lib/x86_64-linux-gnu/libgrpc_unsecure.a /usr/lib/x86_64-linux-gnu/libgrpc.a /usr/lib/x86_64-linux-gnu/libcares.a -ldl -lz
+#LDFLAGS += /usr/lib/x86_64-linux-gnu/libprotobuf.a /usr/lib/libgrpc++_unsecure.a /usr/lib/libgrpc_unsecure.a /usr/lib/libgrpc.a /usr/lib/x86_64-linux-gnu/libcares.a -ldl -lz
 
 client: $(CLIOBJS)
        $(CXX) -o $@ $(CLIOBJS) $(LDFLAGS)
index 559c70f62acf9e5f056d26f205fa6dc2aa24f38f..f8440a23a1aaf3f71635c672200786573d26b2b7 100644 (file)
@@ -135,6 +135,10 @@ constexpr bool more_than_one(Bitboard b) {
   return b & (b - 1);
 }
 
+inline bool opposite_colors(Square s1, Square s2) {
+  return bool(DarkSquares & s1) != bool(DarkSquares & s2);
+}
+
 /// rank_bb() and file_bb() return a bitboard representing all the squares on
 /// the given file or rank.
 
@@ -177,6 +181,16 @@ constexpr Bitboard pawn_attacks_bb(Bitboard b) {
 }
 
 
+/// double_pawn_attacks_bb() returns the pawn attacks for the given color
+/// from the squares in the given bitboard.
+
+template<Color C>
+constexpr Bitboard double_pawn_attacks_bb(Bitboard b) {
+  return C == WHITE ? shift<NORTH_WEST>(b) & shift<NORTH_EAST>(b)
+                    : shift<SOUTH_WEST>(b) & shift<SOUTH_EAST>(b);
+}
+
+
 /// adjacent_files_bb() returns a bitboard representing all the squares on the
 /// adjacent files of the given one.
 
index 55a4caba593a43c77bf3d3d2343f239f8b9a0301..66ee54d846044c90d03ec4dcaf9699e07aae13ee 100644 (file)
@@ -45,14 +45,14 @@ namespace {
   // Table used to drive the king towards a corner square of the
   // right color in KBN vs K endgames.
   constexpr int PushToCorners[SQUARE_NB] = {
-    200, 190, 180, 170, 160, 150, 140, 130,
-    190, 180, 170, 160, 150, 140, 130, 140,
-    180, 170, 155, 140, 140, 125, 140, 150,
-    170, 160, 140, 120, 110, 140, 150, 160,
-    160, 150, 140, 110, 120, 140, 160, 170,
-    150, 140, 125, 140, 140, 155, 170, 180,
-    140, 130, 140, 150, 160, 170, 180, 190,
-    130, 140, 150, 160, 170, 180, 190, 200
+     6400, 6080, 5760, 5440, 5120, 4800, 4480, 4160,
+     6080, 5760, 5440, 5120, 4800, 4480, 4160, 4480,
+     5760, 5440, 4960, 4480, 4480, 4000, 4480, 4800,
+     5440, 5120, 4480, 3840, 3520, 4480, 4800, 5120,
+     5120, 4800, 4480, 3520, 3840, 4480, 5120, 5440,
+     4800, 4480, 4000, 4480, 4480, 4960, 5440, 5760,
+     4480, 4160, 4480, 4800, 5120, 5440, 5760, 6080,
+     4160, 4480, 4800, 5120, 5440, 5760, 6080, 6400
   };
 
   // Tables used to drive a piece towards or away from another piece
@@ -120,7 +120,7 @@ Value Endgame<KXK>::operator()(const Position& pos) const {
 
 
 /// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
-/// defending king towards a corner square of the right color.
+/// defending king towards a corner square that our bishop attacks.
 template<>
 Value Endgame<KBNK>::operator()(const Position& pos) const {
 
@@ -131,19 +131,14 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
   Square loserKSq = pos.square<KING>(weakSide);
   Square bishopSq = pos.square<BISHOP>(strongSide);
 
-  // kbnk_mate_table() tries to drive toward corners A1 or H8. If we have a
-  // bishop that cannot reach the above squares, we flip the kings in order
-  // to drive the enemy toward corners A8 or H1.
-  if (opposite_colors(bishopSq, SQ_A1))
-  {
-      winnerKSq = ~winnerKSq;
-      loserKSq  = ~loserKSq;
-  }
+  // If our Bishop does not attack A1/H8, we flip the enemy king square 
+  // to drive to opposite corners (A8/H1).
 
   Value result =  VALUE_KNOWN_WIN
                 + PushClose[distance(winnerKSq, loserKSq)]
-                + PushToCorners[loserKSq];
+                + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq];
 
+  assert(abs(result) < VALUE_MATE_IN_MAX_PLY);
   return strongSide == pos.side_to_move() ? result : -result;
 }
 
index aeaa4336383960142e77260b7442d17659871bcb..333d04aca277d0b456800017980887967d14e09d 100644 (file)
@@ -152,26 +152,25 @@ namespace {
   };
 
   // Assorted bonuses and penalties
-  constexpr Score BishopPawns        = S(  3,  8);
-  constexpr Score CloseEnemies       = S(  7,  0);
+  constexpr Score BishopPawns        = S(  3,  7);
+  constexpr Score CloseEnemies       = S(  8,  0);
   constexpr Score CorneredBishop     = S( 50, 50);
-  constexpr Score Hanging            = S( 62, 34);
-  constexpr Score KingProtector      = S(  6,  7);
-  constexpr Score KnightOnQueen      = S( 20, 12);
-  constexpr Score LongDiagonalBishop = S( 44,  0);
-  constexpr Score MinorBehindPawn    = S( 16,  0);
-  constexpr Score Overload           = S( 12,  6);
-  constexpr Score PawnlessFlank      = S( 18, 94);
-  constexpr Score RestrictedPiece    = S(  7,  6);
-  constexpr Score RookOnPawn         = S( 10, 28);
-  constexpr Score SliderOnQueen      = S( 49, 21);
-  constexpr Score ThreatByKing       = S( 21, 84);
-  constexpr Score ThreatByPawnPush   = S( 48, 42);
-  constexpr Score ThreatByRank       = S( 14,  3);
-  constexpr Score ThreatBySafePawn   = S(169, 99);
-  constexpr Score TrappedRook        = S( 98,  5);
-  constexpr Score WeakQueen          = S( 51, 10);
-  constexpr Score WeakUnopposedPawn  = S( 14, 20);
+  constexpr Score Hanging            = S( 69, 36);
+  constexpr Score KingProtector      = S(  7,  8);
+  constexpr Score KnightOnQueen      = S( 16, 12);
+  constexpr Score LongDiagonalBishop = S( 45,  0);
+  constexpr Score MinorBehindPawn    = S( 18,  3);
+  constexpr Score PawnlessFlank      = S( 17, 95);
+  constexpr Score RestrictedPiece    = S(  7,  7);
+  constexpr Score RookOnPawn         = S( 10, 32);
+  constexpr Score SliderOnQueen      = S( 59, 18);
+  constexpr Score ThreatByKing       = S( 24, 89);
+  constexpr Score ThreatByPawnPush   = S( 48, 39);
+  constexpr Score ThreatByRank       = S( 13,  0);
+  constexpr Score ThreatBySafePawn   = S(173, 94);
+  constexpr Score TrappedRook        = S( 96,  4);
+  constexpr Score WeakQueen          = S( 49, 15);
+  constexpr Score WeakUnopposedPawn  = S( 12, 23);
 
 #undef S
 
@@ -275,6 +274,7 @@ namespace {
             kingRing[Us] |= shift<EAST>(kingRing[Us]);
 
         kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
+        kingRing[Us] &= ~double_pawn_attacks_bb<Us>(pos.pieces(Us, PAWN));
         kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
     }
   }
@@ -382,7 +382,7 @@ namespace {
             {
                 File kf = file_of(pos.square<KING>(Us));
                 if ((kf < FILE_E) == (file_of(s) < kf))
-                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
+                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.castling_rights(Us));
             }
         }
 
@@ -513,7 +513,7 @@ namespace {
     Score score = SCORE_ZERO;
 
     // Non-pawn enemies
-    nonPawnEnemies = pos.pieces(Them) pos.pieces(Them, PAWN);
+    nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(Them, PAWN);
 
     // Squares strongly protected by the enemy, either because they defend the
     // square with a pawn, or because they defend the square twice and we don't.
@@ -553,16 +553,14 @@ namespace {
         if (weak & attackedBy[Us][KING])
             score += ThreatByKing;
 
-        score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
-
-        b = weak & nonPawnEnemies & attackedBy[Them][ALL_PIECES];
-        score += Overload * popcount(b);
+        b =  ~attackedBy[Them][ALL_PIECES]
+           | (nonPawnEnemies & attackedBy2[Us]);
+        score += Hanging * popcount(weak & b);
     }
 
     // Bonus for restricting their piece moves
     restricted =   attackedBy[Them][ALL_PIECES]
-                & ~attackedBy[Them][PAWN]
-                & ~attackedBy2[Them]
+                & ~stronglyProtected
                 &  attackedBy[Us][ALL_PIECES];
     score += RestrictedPiece * popcount(restricted);
 
index d54f4ab98c559dabe243d28a45a0f590b46c6fc7..cccdd25d2f36e311a9376c3a22a8244edac29441 100644 (file)
@@ -29,7 +29,7 @@ class Position;
 
 namespace Eval {
 
-constexpr Value Tempo = Value(20); // Must be visible to search
+constexpr Value Tempo = Value(28); // Must be visible to search
 
 std::string trace(const Position& pos);
 
index 56de9ad225022bb29db03ceed4c9f2d101da92a1..b472c3fd266c362cd0b032448908475b20291ec2 100644 (file)
@@ -58,7 +58,7 @@ struct Entry {
   Key key;
   const EndgameBase<Value>* evaluationFunction;
   const EndgameBase<ScaleFactor>* scalingFunction[COLOR_NB]; // Could be one for each
-                                                             // side (e.g. KPKP, KBPsKs)
+                                                             // side (e.g. KPKP, KBPsK)
   int16_t value;
   uint8_t factor[COLOR_NB];
   Phase gamePhase;
index 4d2abd5a17d65d231ca75c35e22c29145e551c7f..bca4887673ab78e7c67938602853d74769c2e98e 100644 (file)
@@ -258,7 +258,7 @@ int best_group(size_t idx) {
       return -1;
   }
 
-  while (ptr->Size > 0 && byteOffset + ptr->Size <= returnLength)
+  while (byteOffset < returnLength)
   {
       if (ptr->Relationship == RelationNumaNode)
           nodes++;
@@ -269,6 +269,7 @@ int best_group(size_t idx) {
           threads += (ptr->Processor.Flags == LTP_PC_SMT) ? 2 : 1;
       }
 
+      assert(ptr->Size);
       byteOffset += ptr->Size;
       ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((char*)ptr) + ptr->Size);
   }
index 833cd2fc88ec74d94ae19599408715621773baa6..76a27d9f4936320165c0378f2b59225038b0abbe 100644 (file)
@@ -29,7 +29,7 @@ namespace {
   ExtMove* generate_castling(const Position& pos, ExtMove* moveList) {
 
     constexpr CastlingRight Cr = Us | Cs;
-    constexpr bool KingSide = (Cr == WHITE_OO || Cr == BLACK_OO);
+    constexpr bool KingSide = (Cs == KING_SIDE);
 
     if (pos.castling_impeded(Cr) || !pos.can_castle(Cr))
         return moveList;
@@ -278,7 +278,7 @@ namespace {
             *moveList++ = make_move(ksq, pop_lsb(&b));
     }
 
-    if (Type != CAPTURES && Type != EVASIONS && pos.can_castle(Us))
+    if (Type != CAPTURES && Type != EVASIONS && pos.castling_rights(Us))
     {
         if (pos.is_chess960())
         {
index 7d39a4a08bde360f2299f3cc231817e0d749ac07..edd670b84cc4ec3021fdcd2b3962bbd419cfdc88 100644 (file)
@@ -67,7 +67,7 @@ namespace {
     constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
     constexpr Direction Up   = (Us == WHITE ? NORTH : SOUTH);
 
-    Bitboard b, neighbours, stoppers, doubled, supported, phalanx;
+    Bitboard b, neighbours, stoppers, doubled, support, phalanx;
     Bitboard lever, leverPush;
     Square s;
     bool opposed, backward;
@@ -102,7 +102,7 @@ namespace {
         doubled    = ourPawns   & (s - Up);
         neighbours = ourPawns   & adjacent_files_bb(f);
         phalanx    = neighbours & rank_bb(s);
-        supported  = neighbours & rank_bb(s - Up);
+        support    = neighbours & rank_bb(s - Up);
 
         // A pawn is backward when it is behind all pawns of the same color
         // on the adjacent files and cannot be safely advanced.
@@ -114,22 +114,22 @@ namespace {
         // which could become passed after one or two pawn pushes when are
         // not attacked more times than defended.
         if (   !(stoppers ^ lever ^ leverPush)
-            && popcount(supported) >= popcount(lever) - 1
+            && popcount(support) >= popcount(lever) - 1
             && popcount(phalanx)   >= popcount(leverPush))
             e->passedPawns[Us] |= s;
 
         else if (   stoppers == SquareBB[s + Up]
                  && relative_rank(Us, s) >= RANK_5)
         {
-            b = shift<Up>(supported) & ~theirPawns;
+            b = shift<Up>(support) & ~theirPawns;
             while (b)
                 if (!more_than_one(theirPawns & PawnAttacks[Us][pop_lsb(&b)]))
                     e->passedPawns[Us] |= s;
         }
 
         // Score this pawn
-        if (supported | phalanx)
-            score += Connected[opposed][bool(phalanx)][popcount(supported)][relative_rank(Us, s)];
+        if (support | phalanx)
+            score += Connected[opposed][bool(phalanx)][popcount(support)][relative_rank(Us, s)];
 
         else if (!neighbours)
             score -= Isolated, e->weakUnopposed[Us] += !opposed;
@@ -137,7 +137,7 @@ namespace {
         else if (backward)
             score -= Backward, e->weakUnopposed[Us] += !opposed;
 
-        if (doubled && !supported)
+        if (doubled && !support)
             score -= Doubled;
     }
 
@@ -214,10 +214,10 @@ Value Entry::evaluate_shelter(const Position& pos, Square ksq) {
   for (File f = File(center - 1); f <= File(center + 1); ++f)
   {
       b = ourPawns & file_bb(f);
-      int ourRank = b ? relative_rank(Us, backmost_sq(Us, b)) : 0;
+      Rank ourRank = b ? relative_rank(Us, backmost_sq(Us, b)) : RANK_1;
 
       b = theirPawns & file_bb(f);
-      int theirRank = b ? relative_rank(Us, frontmost_sq(Them, b)) : 0;
+      Rank theirRank = b ? relative_rank(Us, frontmost_sq(Them, b)) : RANK_1;
 
       int d = std::min(f, ~f);
       safety += ShelterStrength[d][ourRank];
@@ -237,7 +237,7 @@ Score Entry::do_king_safety(const Position& pos) {
 
   Square ksq = pos.square<KING>(Us);
   kingSquares[Us] = ksq;
-  castlingRights[Us] = pos.can_castle(Us);
+  castlingRights[Us] = pos.castling_rights(Us);
   int minKingPawnDistance = 0;
 
   Bitboard pawns = pos.pieces(Us, PAWN);
index 4d8b293664d6cabd176162a233189363a1f59d0a..df220eabbe9433fffad3dc47577446e49bbf84df 100644 (file)
@@ -51,7 +51,7 @@ struct Entry {
 
   template<Color Us>
   Score king_safety(const Position& pos) {
-    return  kingSquares[Us] == pos.square<KING>(Us) && castlingRights[Us] == pos.can_castle(Us)
+    return  kingSquares[Us] == pos.square<KING>(Us) && castlingRights[Us] == pos.castling_rights(Us)
           ? kingSafety[Us] : (kingSafety[Us] = do_king_safety<Us>(pos));
   }
 
index cf172126e99416a3b8923ee965b593b9c85bfc61..d3afddeb4fb1df982f15604d0f5c70eafa905e23 100644 (file)
@@ -474,7 +474,7 @@ const string Position::fen() const {
   if (can_castle(BLACK_OOO))
       ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK | QUEEN_SIDE))) : 'q');
 
-  if (!can_castle(WHITE) && !can_castle(BLACK))
+  if (!can_castle(ANY_CASTLING))
       ss << '-';
 
   ss << (ep_square() == SQ_NONE ? " - " : " " + UCI::square(ep_square()) + " ")
index e1eacf26d01530cfc9df3fb2e22e7233d394738e..d94ef185ac9c45a47de27148ce34f8dfe0ff3685 100644 (file)
@@ -97,8 +97,8 @@ public:
   template<PieceType Pt> Square square(Color c) const;
 
   // Castling
-  int can_castle(Color c) const;
-  int can_castle(CastlingRight cr) const;
+  int castling_rights(Color c) const;
+  bool can_castle(CastlingRight cr) const;
   bool castling_impeded(CastlingRight cr) const;
   Square castling_rook_square(CastlingRight cr) const;
 
@@ -260,11 +260,11 @@ inline Square Position::ep_square() const {
   return st->epSquare;
 }
 
-inline int Position::can_castle(CastlingRight cr) const {
+inline bool Position::can_castle(CastlingRight cr) const {
   return st->castlingRights & cr;
 }
 
-inline int Position::can_castle(Color c) const {
+inline int Position::castling_rights(Color c) const {
   return st->castlingRights & ((WHITE_OO | WHITE_OOO) << (2 * c));
 }
 
index 4703da35c8b754d237b47d562c44c7747127751f..a4a5e0a04dc60ef50840da1ec80ebb23e9908cb5 100644 (file)
@@ -37,15 +37,7 @@ namespace PSQT {
 // second half of the files.
 constexpr Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
   { },
-  { // Pawn
-   { S(  0, 0), S(  0,  0), S(  0, 0), S( 0, 0) },
-   { S(-11,-3), S(  7, -1), S(  7, 7), S(17, 2) },
-   { S(-16,-2), S( -3,  2), S( 23, 6), S(23,-1) },
-   { S(-14, 7), S( -7, -4), S( 20,-8), S(24, 2) },
-   { S( -5,13), S( -2, 10), S( -1,-1), S(12,-8) },
-   { S(-11,16), S(-12,  6), S( -2, 1), S( 4,16) },
-   { S( -2, 1), S( 20,-12), S(-10, 6), S(-2,25) }
-  },
+  { },
   { // Knight
    { S(-169,-105), S(-96,-74), S(-80,-46), S(-79,-18) },
    { S( -79, -70), S(-39,-56), S(-24,-15), S( -9,  6) },
@@ -57,24 +49,24 @@ constexpr Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
    { S(-200, -98), S(-80,-89), S(-53,-53), S(-32,-16) }
   },
   { // Bishop
-   { S(-49,-58), S(- 7,-31), S(-10,-37), S(-34,-19) },
-   { S(-24,-34), S(  9, -9), S( 15,-14), S(  1,  4) },
-   { S( -9,-23), S( 22,  0), S( -3, -3), S( 12, 16) },
-   { S(  4,-26), S(  9, -3), S( 18, -5), S( 40, 16) },
-   { S( -8,-26), S( 27, -4), S( 13, -7), S( 30, 14) },
-   { S(-17,-24), S( 14, -2), S( -6,  0), S(  6, 13) },
-   { S(-19,-34), S(-13,-10), S(  7,-12), S(-11,  6) },
-   { S(-47,-55), S( -7,-32), S(-17,-36), S(-29,-17) }
+   { S(-44,-63), S( -4,-30), S(-11,-35), S(-28, -8) },
+   { S(-18,-38), S(  7,-13), S( 14,-14), S(  3,  0) },
+   { S( -8,-18), S( 24,  0), S( -3, -7), S( 15, 13) },
+   { S(  1,-26), S(  8, -3), S( 26,  1), S( 37, 16) },
+   { S( -7,-24), S( 30, -6), S( 23,-10), S( 28, 17) },
+   { S(-17,-26), S(  4,  2), S( -1,  1), S(  8, 16) },
+   { S(-21,-34), S(-19,-18), S( 10, -7), S( -6,  9) },
+   { S(-48,-51), S( -3,-40), S(-12,-39), S(-25,-20) }
   },
   { // Rook
-   { S(-24, 0), S(-15, 3), S( -8, 0), S( 0, 3) },
-   { S(-18,-7), S( -5,-5), S( -1,-5), S( 1,-1) },
-   { S(-19, 6), S(-10,-7), S(  1, 3), S( 0, 3) },
-   { S(-21, 0), S( -7, 4), S( -4,-2), S(-4, 1) },
-   { S(-21,-7), S(-12, 5), S( -1,-5), S( 4,-7) },
-   { S(-23, 3), S(-10, 2), S(  1,-1), S( 6, 3) },
-   { S(-11,-1), S(  8, 7), S(  9,11), S(12,-1) },
-   { S(-25, 6), S(-18, 4), S(-11, 6), S( 2, 2) }
+   { S(-24, -2), S(-13,-6), S( -7, -3), S( 2,-2) },
+   { S(-18,-10), S(-10,-7), S( -5,  1), S( 9, 0) },
+   { S(-21, 10), S( -7,-4), S(  3,  2), S(-1,-2) },
+   { S(-13, -5), S( -5, 2), S( -4, -8), S(-6, 8) },
+   { S(-24, -8), S(-12, 5), S( -1,  4), S( 6,-9) },
+   { S(-24,  3), S( -4,-2), S(  4,-10), S(10, 7) },
+   { S( -8,  1), S(  6, 2), S( 10, 17), S(12,-8) },
+   { S(-22, 12), S(-24,-6), S( -6, 13), S( 4, 7) }
   },
   { // Queen
    { S(  3,-69), S(-5,-57), S(-5,-47), S( 4,-26) },
@@ -98,6 +90,17 @@ constexpr Score Bonus[][RANK_NB][int(FILE_NB) / 2] = {
   }
 };
 
+constexpr Score PBonus[RANK_NB][FILE_NB] =\r
+  { // Pawn\r
+   { S(  0,  0), S(  0,  0), S(  0,  0), S(  0,  0), S(  0,  0), S(  0,  0), S(  0,  0), S(  0,  0) },\r
+   { S(  0,-11), S( -3, -4), S( 13, -1), S( 19, -4), S( 16, 17), S( 13,  7), S(  4,  4), S( -4,-13) },\r
+   { S(-16, -8), S(-12, -6), S( 20, -3), S( 21,  0), S( 25,-11), S( 29,  3), S(  0,  0), S(-27, -1) },\r
+   { S(-11,  3), S(-17,  6), S( 11,-10), S( 21,  1), S( 32, -6), S( 19,-11), S( -5,  0), S(-14, -2) },\r
+   { S(  4, 13), S(  6,  7), S( -8,  3), S(  3, -5), S(  8,-15), S( -2, -1), S(-19,  9), S( -5, 13) },\r
+   { S( -5, 25), S(-19, 20), S(  7, 16), S(  8, 12), S( -7, 21), S( -2,  3), S(-10, -4), S(-16, 15) },\r
+   { S(-10,  6), S(  9, -5), S( -7, 16), S(-12, 27), S( -7, 15), S( -8, 11), S( 16, -7), S( -8,  4) }\r
+  };
+
 #undef S
 
 Score psq[PIECE_NB][SQUARE_NB];
@@ -117,7 +120,8 @@ void init() {
       for (Square s = SQ_A1; s <= SQ_H8; ++s)
       {
           File f = std::min(file_of(s), ~file_of(s));
-          psq[ pc][ s] = score + Bonus[pc][rank_of(s)][f];
+          psq[ pc][ s] = score + (type_of(pc) == PAWN ? PBonus[rank_of(s)][file_of(s)]
+                                                      : Bonus[pc][rank_of(s)][f]);
           psq[~pc][~s] = -psq[pc][s];
       }
   }
index f4e1da977990f18d2b77e988cbbc4c1c0798370e..4a541c5b90697137371c47cfb53662d066472e27 100644 (file)
@@ -254,7 +254,7 @@ void MainThread::search() {
       && !Skill(Options["Skill Level"]).enabled()
       &&  rootMoves[0].pv[0] != MOVE_NONE)
   {
-      std::map<Move, int> votes;
+      std::map<Move, int64_t> votes;
       Value minScore = this->rootMoves[0].score;
 
       // Find out minimum score and reset votes for moves which can be voted
@@ -265,12 +265,13 @@ void MainThread::search() {
       }
 
       // Vote according to score and depth
+      auto square = [](int64_t x) { return x * x; };
       for (Thread* th : Threads)
-          votes[th->rootMoves[0].pv[0]] +=  int(th->rootMoves[0].score - minScore)
-                                          + int(th->completedDepth);
+          votes[th->rootMoves[0].pv[0]] += 200 + (square(th->rootMoves[0].score - minScore + 1)
+                                                  * int64_t(th->completedDepth));
 
       // Select best thread
-      int bestVote = votes[this->rootMoves[0].pv[0]];
+      int64_t bestVote = votes[this->rootMoves[0].pv[0]];
       for (Thread* th : Threads)
       {
           if (votes[th->rootMoves[0].pv[0]] > bestVote)
@@ -302,7 +303,12 @@ void MainThread::search() {
 
 void Thread::search() {
 
-  Stack stack[MAX_PLY+7], *ss = stack+4; // To reference from (ss-4) to (ss+2)
+  // To allow access to (ss-5) up to (ss+2), the stack must be oversized.
+  // The former is needed to allow update_continuation_histories(ss-1, ...),
+  // which accesses its argument at ss-4, also near the root.
+  // The latter is needed for statScores and killer initialization.
+  Stack stack[MAX_PLY+8], *ss = stack+5;
+  Move  pv[MAX_PLY+1];
   Value bestValue, alpha, beta, delta;
   Move  lastBestMove = MOVE_NONE;
   Depth lastBestMoveDepth = DEPTH_ZERO;
@@ -311,9 +317,10 @@ void Thread::search() {
   Color us = rootPos.side_to_move();
   bool failedLow;
 
-  std::memset(ss-4, 0, 7 * sizeof(Stack));
-  for (int i = 4; i > 0; i--)
+  std::memset(ss-5, 0, 8 * sizeof(Stack));
+  for (int i = 5; i > 0; i--)
      (ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel
+  ss->pv = pv;
 
   bestValue = delta = alpha = -VALUE_INFINITE;
   beta = VALUE_INFINITE;
@@ -448,7 +455,7 @@ void Thread::search() {
               {
                   beta = std::min(bestValue + delta, VALUE_INFINITE);
                   if (mainThread)
-                         ++failedHighCnt;
+                      ++failedHighCnt;
               }
               else
                   break;
@@ -492,10 +499,8 @@ void Thread::search() {
           && !Threads.stop
           && !Threads.stopOnPonderhit)
           {
-              const int F[] = { failedLow,
-                                bestValue - mainThread->previousScore };
-
-              int improvingFactor = std::max(246, std::min(832, 306 + 119 * F[0] - 6 * F[1]));
+              double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
+              fallingEval        = std::max(0.5, std::min(1.5, fallingEval));
 
               // If the bestMove is stable over several iterations, reduce time accordingly
               timeReduction = 1.0;
@@ -509,7 +514,7 @@ void Thread::search() {
 
               // Stop the search if we have only one legal move, or if available time elapsed
               if (   rootMoves.size() == 1
-                  || Time.elapsed() > Time.optimum() * bestMoveInstability * improvingFactor / 581)
+                  || Time.elapsed() > Time.optimum() * bestMoveInstability * fallingEval)
               {
                   // If we are allowed to ponder do not stop the search now but
                   // keep pondering until the GUI sends "ponderhit" or "stop".
@@ -655,9 +660,10 @@ namespace {
                 if (!pos.capture_or_promotion(ttMove))
                     update_quiet_stats(pos, ss, ttMove, nullptr, 0, stat_bonus(depth));
 
-                // Extra penalty for a quiet TT move in previous ply when it gets refuted
-                if ((ss-1)->moveCount == 1 && !pos.captured_piece())
-                    update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
+                // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
+                if (    ((ss-1)->moveCount == 1 || (ss-1)->currentMove == (ss-1)->killers[0])
+                     && !pos.captured_piece())
+                        update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
             }
             // Penalty for a quiet ttMove that fails low
             else if (!pos.capture_or_promotion(ttMove))
@@ -758,15 +764,16 @@ namespace {
     }
 
     // Step 7. Razoring (~2 Elo)
-    if (   depth < 2 * ONE_PLY
-        && eval <= alpha - RazorMargin)
+    if (   !rootNode // The required rootNode PV handling is not available in qsearch
+        &&  depth < 2 * ONE_PLY
+        &&  eval <= alpha - RazorMargin)
         return qsearch<NT>(pos, ss, alpha, beta);
 
     improving =   ss->staticEval >= (ss-2)->staticEval
                || (ss-2)->staticEval == VALUE_NONE;
 
     // Step 8. Futility pruning: child node (~30 Elo)
-    if (   !rootNode
+    if (   !PvNode
         &&  depth < 7 * ONE_PLY
         &&  eval - futility_margin(depth, improving) >= beta
         &&  eval < VALUE_KNOWN_WIN) // Do not return unproven wins
@@ -828,8 +835,8 @@ namespace {
         &&  depth >= 5 * ONE_PLY
         &&  abs(beta) < VALUE_MATE_IN_MAX_PLY)
     {
-        Value rbeta = std::min(beta + 216 - 48 * improving, VALUE_INFINITE);
-        MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
+        Value raisedBeta = std::min(beta + 216 - 48 * improving, VALUE_INFINITE);
+        MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &thisThread->captureHistory);
         int probCutCount = 0;
 
         while (  (move = mp.next_move()) != MOVE_NONE
@@ -846,15 +853,15 @@ namespace {
                 pos.do_move(move, st);
 
                 // Perform a preliminary qsearch to verify that the move holds
-                value = -qsearch<NonPV>(pos, ss+1, -rbeta, -rbeta+1);
+                value = -qsearch<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1);
 
                 // If the qsearch held perform the regular search
-                if (value >= rbeta)
-                    value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, depth - 4 * ONE_PLY, !cutNode);
+                if (value >= raisedBeta)
+                    value = -search<NonPV>(pos, ss+1, -raisedBeta, -raisedBeta+1, depth - 4 * ONE_PLY, !cutNode);
 
                 pos.undo_move(move);
 
-                if (value >= rbeta)
+                if (value >= raisedBeta)
                     return value;
             }
     }
@@ -930,26 +937,26 @@ moves_loop: // When in check, search starts from here
       if (    depth >= 8 * ONE_PLY
           &&  move == ttMove
           && !rootNode
-          && !excludedMove // Recursive singular search is not allowed
+          && !excludedMove // Avoid recursive singular search
           &&  ttValue != VALUE_NONE
           && (tte->bound() & BOUND_LOWER)
           &&  tte->depth() >= depth - 3 * ONE_PLY
           &&  pos.legal(move))
       {
-          Value rBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
+          Value reducedBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
           ss->excludedMove = move;
-          value = search<NonPV>(pos, ss, rBeta - 1, rBeta, depth / 2, cutNode);
+          value = search<NonPV>(pos, ss, reducedBeta - 1, reducedBeta, depth / 2, cutNode);
           ss->excludedMove = MOVE_NONE;
 
-          if (value < rBeta)
+          if (value < reducedBeta)
               extension = ONE_PLY;
       }
       else if (    givesCheck // Check extension (~2 Elo)
                &&  pos.see_ge(move))
           extension = ONE_PLY;
 
-      else if (   pos.can_castle(us) // Extension for king moves that change castling rights
-               && type_of(movedPiece) == KING)
+      // Extension if castling
+      else if (type_of(move) == CASTLING)
           extension = ONE_PLY;
 
       // Calculate new depth for this move
@@ -962,7 +969,7 @@ moves_loop: // When in check, search starts from here
       {
           if (   !captureOrPromotion
               && !givesCheck
-              && (!pos.advanced_pawn_push(move) || pos.non_pawn_material() >= Value(5000)))
+              && !pos.advanced_pawn_push(move))
           {
               // Move count based pruning (~30 Elo)
               if (moveCountPruning)
@@ -975,7 +982,7 @@ moves_loop: // When in check, search starts from here
               int lmrDepth = std::max(newDepth - reduction<PvNode>(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY;
 
               // Countermoves based pruning (~20 Elo)
-              if (   lmrDepth < 3 + ((ss-1)->statScore > 0)
+              if (   lmrDepth < 3 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1)
                   && (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold
                   && (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
                   continue;
@@ -1187,14 +1194,15 @@ moves_loop: // When in check, search starts from here
 
         update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + ONE_PLY));
 
-        // Extra penalty for a quiet TT move in previous ply when it gets refuted
-        if ((ss-1)->moveCount == 1 && !pos.captured_piece())
-            update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
+        // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
+        if (   ((ss-1)->moveCount == 1 || ((ss-1)->currentMove == (ss-1)->killers[0]))
+            && !pos.captured_piece())
+                update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
+
     }
     // Bonus for prior countermove that caused the fail low
     else if (   (depth >= 3 * ONE_PLY || PvNode)
-             && !pos.captured_piece()
-             && is_ok((ss-1)->currentMove))
+             && !pos.captured_piece())
         update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));
 
     if (PvNode)
@@ -1395,21 +1403,15 @@ moves_loop: // When in check, search starts from here
 
           if (value > alpha)
           {
+              bestMove = move;
+
               if (PvNode) // Update pv even in fail-high case
                   update_pv(ss->pv, move, (ss+1)->pv);
 
               if (PvNode && value < beta) // Update alpha here!
-              {
                   alpha = value;
-                  bestMove = move;
-              }
-              else // Fail high
-              {
-                  tte->save(posKey, value_to_tt(value, ss->ply), BOUND_LOWER,
-                            ttDepth, move, ss->staticEval);
-
-                  return value;
-              }
+              else
+                  break; // Fail high
           }
        }
     }
@@ -1420,7 +1422,8 @@ moves_loop: // When in check, search starts from here
         return mated_in(ss->ply); // Plies to mate from the root
 
     tte->save(posKey, value_to_tt(bestValue, ss->ply),
-              PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
+              bestValue >= beta ? BOUND_LOWER :
+              PvNode && bestValue > oldAlpha  ? BOUND_EXACT : BOUND_UPPER,
               ttDepth, bestMove, ss->staticEval);
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
index 03cffca17bc4756839443559ea4247bb13c05d6d..94d7371499cb8e3d96621e8275592c241e3cd046 100644 (file)
@@ -224,8 +224,9 @@ public:
             exit(1);
         }
 #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;
@@ -1107,10 +1108,10 @@ void* mapped(TBTable<Type>& e, const Position& pos) {
 
     static 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);
 
@@ -1277,7 +1278,7 @@ void Tablebases::init(const std::string& paths) {
                         continue; // First on diagonal, second above
 
                     else if (!off_A1H8(s1) && !off_A1H8(s2))
-                        bothOnDiagonal.push_back(std::make_pair(idx, s2));
+                        bothOnDiagonal.emplace_back(idx, s2);
 
                     else
                         MapKK[idx][s2] = code++;
index 5e990fdc680c0549a58f6412256d61ddf4642ac2..f88e359b0373436db1f6c445f72f4b04448667e7 100644 (file)
@@ -118,7 +118,7 @@ void Thread::idle_loop() {
 }
 
 /// ThreadPool::set() creates/destroys threads to match the requested number.
-/// Created and launched threads will go immediately to sleep in idle_loop.
+/// Created and launched threads will immediately go to sleep in idle_loop.
 /// Upon resizing, threads are recreated to allow for binding if necessary.
 
 void ThreadPool::set(size_t requested) {
@@ -136,10 +136,10 @@ void ThreadPool::set(size_t requested) {
       while (size() < requested)
           push_back(new Thread(size()));
       clear();
-  }
 
-  // Reallocate the hash with the new threadpool size
-  TT.resize(Options["Hash"]);
+      // Reallocate the hash with the new threadpool size
+      TT.resize(Options["Hash"]);
+  }
 }
 
 /// ThreadPool::clear() sets threadPool data to initial values.
index 53e78595045548bed917e75132dfc084c60ed88a..653d081f8f0eb01859408043467a4e0486241f2f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "bitboard.h"
 #include "misc.h"
+#include "thread.h"
 #include "tt.h"
 #include "uci.h"
 
@@ -58,6 +59,8 @@ void TTEntry::save(Key k, Value v, Bound b, Depth d, Move m, Value ev) {
 
 void TranspositionTable::resize(size_t mbSize) {
 
+  Threads.main()->wait_for_search_finished();
+
   clusterCount = mbSize * 1024 * 1024 / sizeof(Cluster);
 
   free(mem);
@@ -82,9 +85,9 @@ void TranspositionTable::clear() {
 
   std::vector<std::thread> threads;
 
-  for (size_t idx = 0; idx < Options["Threads"]; idx++)
+  for (size_t idx = 0; idx < Options["Threads"]; ++idx)
   {
-      threads.push_back(std::thread([this, idx]() {
+      threads.emplace_back([this, idx]() {
 
           // Thread binding gives faster search on systems with a first-touch policy
           if (Options["Threads"] > 8)
@@ -97,7 +100,7 @@ void TranspositionTable::clear() {
                                 stride : clusterCount - start;
 
           std::memset(&table[start], 0, len * sizeof(Cluster));
-      }));
+      });
   }
 
   for (std::thread& th: threads)
@@ -145,12 +148,9 @@ TTEntry* TranspositionTable::probe(const Key key, bool& found) const {
 int TranspositionTable::hashfull() const {
 
   int cnt = 0;
-  for (int i = 0; i < 1000 / ClusterSize; i++)
-  {
-      const TTEntry* tte = &table[i].entry[0];
-      for (int j = 0; j < ClusterSize; j++)
-          if ((tte[j].genBound8 & 0xFC) == generation8)
-              cnt++;
-  }
-  return cnt;
+  for (int i = 0; i < 1000 / ClusterSize; ++i)
+      for (int j = 0; j < ClusterSize; ++j)
+          cnt += (table[i].entry[j].genBound8 & 0xFC) == generation8;
+
+  return cnt * 1000 / (ClusterSize * (1000 / ClusterSize));
 }
index 3b5afecf335f55d2aeb54c43bfc71532a3919fb6..c4c2752c8e553961a2fbc70140ee7dea4523e22f 100644 (file)
@@ -413,11 +413,6 @@ constexpr Rank relative_rank(Color c, Square s) {
   return relative_rank(c, rank_of(s));
 }
 
-inline bool opposite_colors(Square s1, Square s2) {
-  int s = int(s1) ^ int(s2);
-  return ((s >> 3) ^ s) & 1;
-}
-
 constexpr Direction pawn_push(Color c) {
   return c == WHITE ? NORTH : SOUTH;
 }