LCOV - code coverage report
Current view: top level - Source - searcherDraw.cpp (source / functions) Coverage Total Hit
Test: coverage Lines: 56.5 % 46 26
Test Date: 2026-03-02 16:42:41 Functions: 100.0 % 3 3

            Line data    Source code
       1              : #include "com.hpp"
       2              : #include "position.hpp"
       3              : #include "searcher.hpp"
       4              : 
       5      4946510 : bool Searcher::isRep(const Position& p, bool isPV) const {
       6              :    // handles chess variants
       7      4946510 :    const int limit = isPV ? 2 : 1;
       8      4946510 :    if (p.fifty < (2 * limit - 1)) return false;
       9              :    int count = 0;
      10      3084791 :    const Hash h = computeHash(p);
      11      3084791 :    int k = p.halfmoves - 4;
      12              :    bool irreversible = false;
      13              :    //std::cout << "***************** " << k << " " << h << " " << GetFEN(p) << std::endl;
      14              :    // look in stack first
      15      7850888 :    for ( ; k >= 0; k-=2) {
      16              :       //std::cout << "stack " << k << " " << stack[k].h << " " << count << " " << ToString(stack[k].p.lastMove) << " " << GetFEN(stack[k].p) << std::endl;
      17      7671769 :       if (stack[k].h == nullHash) break; // no more "history" in stack (will look at game state later)
      18      7468822 :       if (stack[k].h == h){
      19              : #ifdef DEBUG_FIFTY_COLLISION
      20              :          if (stack[k].p != p){
      21              :             Logging::LogIt(Logging::logFatal) << "Collision in fifty hash comparation" << ToString(p) << ToString(stack[k].p);
      22              :          }
      23              : #endif
      24         6943 :          ++count;
      25         6943 :          if (count >= limit){
      26              :             //std::cout << "draw" << std::endl;
      27              :             return true;
      28              :          }
      29              :       }
      30              :       // irreversible moves - check both k-1 and k positions
      31      7462271 :       if (k > 0) {
      32      7462271 :          const Move prevMove = stack[k-1].p.lastMove;
      33      4581789 :          if (isValidMove(prevMove) && 
      34     11860795 :              (isCapture(prevMove) || PieceTools::getPieceType(stack[k-1].p, Move2To(prevMove)) == P_wp)){
      35              :                irreversible=true;
      36              :                break;
      37              :          }
      38              :       }
      39      5593100 :       const Move curMove = stack[k].p.lastMove;
      40      2897997 :       if (isValidMove(curMove) && 
      41      8178969 :           (isCapture(curMove) || PieceTools::getPieceType(stack[k].p, Move2To(curMove)) == P_wp)){
      42              :             irreversible=true;
      43              :             break;
      44              :       }
      45              :    }
      46              :    // then double check in game history
      47      3078240 :    while(!irreversible && k>=0){
      48       202947 :       const std::optional<Hash> curh = COM::GetGameInfo().getHash(k);
      49       202947 :       if (!curh.has_value()) break;
      50              :       //std::cout << "history " << k << " " << curh.value() << " " << count << " " << ToString(COM::GetGameInfo().getMove(k).value()) << " " << GetFEN(COM::GetGameInfo().getPosition(k).value()) << std::endl;
      51            0 :       if (curh.value() == h){
      52            0 :          ++count;
      53            0 :          if (count >= limit){
      54              :             //std::cout << "draw" << std::endl;
      55            0 :             return true;
      56              :          }
      57              :       }
      58              :       // irreversible moves - check both k-1 and k
      59            0 :       if (k>0){
      60            0 :          const auto m = COM::GetGameInfo().getMove(k-1);
      61            0 :          if (m.has_value()){
      62            0 :             const Move move = m.value();
      63            0 :             if (isCapture(move)){
      64              :                irreversible=true;
      65            0 :                break;
      66              :             }
      67            0 :             const auto pp = COM::GetGameInfo().getPosition(k-1);
      68            0 :             if (pp.has_value() && PieceTools::getPieceType(pp.value(), Move2To(move)) == P_wp){
      69              :                irreversible=true;
      70              :                break;
      71              :             }
      72              :          }
      73              :       }
      74            0 :       const auto m = COM::GetGameInfo().getMove(k);
      75            0 :       if (m.has_value()){
      76            0 :          const Move move = m.value();
      77            0 :          if (isCapture(move)){
      78              :             irreversible=true;
      79            0 :             break;
      80              :          }
      81            0 :          const auto pp = COM::GetGameInfo().getPosition(k);
      82            0 :          if (pp.has_value() && PieceTools::getPieceType(pp.value(), Move2To(move)) == P_wp){
      83              :             irreversible=true;
      84              :             break;
      85              :          }
      86              :       }
      87            0 :       k-=2;
      88              :    }
      89              :    return false;
      90              : }
      91              : 
      92      4939959 : bool Searcher::isMaterialDraw(const Position& p) const{
      93              :    // handles chess variants
      94      4939959 :    if ( (p.occupancy() & ~p.allKing()) == emptyBitBoard) return true;
      95      4939959 :    const auto ter = ( (p.mat[Co_White][M_p] + p.mat[Co_Black][M_p]) < 2) ? MaterialHash::probeMaterialHashTable(p.mat) : MaterialHash::Terminaison::Ter_Unknown;
      96      4939959 :    return ter == MaterialHash::Terminaison::Ter_Draw || ter == MaterialHash::Terminaison::Ter_MaterialDraw;
      97              : }
      98              : 
      99      7239395 : bool Searcher::is50moves(const Position& p, bool afterMoveLoop) const{
     100              :    // handles chess variants
     101              :    // checking 50MR at 100 or 101 depending on being before or after move loop because it might be reset by checkmate
     102      7239395 :    return p.fifty >= 100 + afterMoveLoop;
     103              : }
        

Generated by: LCOV version 2.0-1