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

            Line data    Source code
       1              : #include "kpk.hpp"
       2              : 
       3              : #include "attack.hpp"
       4              : #include "logging.hpp"
       5              : #include "position.hpp"
       6              : 
       7              : namespace KPK {
       8              : 
       9              : #if !defined(WITH_SMALL_MEMORY)
      10              : namespace {
      11              : array1d<uint32_t,KPK::KPKmaxIndex / 32> KPKBitbase;               // force 32bit uint
      12              : FORCE_FINLINE unsigned KPKindex(Color us, Square bksq, Square wksq, Square psq) {
      13           11 :    return wksq | (bksq << 6) | (us << 12) | (SQFILE(psq) << 13) | ((6 - SQRANK(psq)) << 15);
      14              : }
      15              : } // namespace
      16              : 
      17           33 : Square normalizeSquare(const Position& p, const Color strongSide, const Square sq) {
      18           33 :    assert(BB::countBit(p.pieces_const<P_wp>(strongSide)) == 1); // only for KPK !
      19           33 :    const Square nsq = SQFILE(BBTools::SquareFromBitBoard(p.pieces_const<P_wp>(strongSide))) >= File_e ? HFlip(sq) : sq;
      20           33 :    return strongSide == Co_White ? nsq : VFlip(nsq);
      21              : }
      22              : 
      23      4325376 : KPKPosition::KPKPosition(const unsigned idx) :
      24      4325376 :       ksq ({ static_cast<Square>(idx & 0x3F), static_cast<Square>((idx >> 6) & 0x3F) }),
      25      4325376 :       us  (static_cast<Color>((idx >> 12) & 0x01)),
      26      4325376 :       psq (MakeSquare(File((idx >> 13) & 0x3), Rank(6 - ((idx >> 15) & 0x7)))){ // first init
      27      4325376 :    if (chebyshevDistance(ksq[Co_White], ksq[Co_Black]) <= 1 || ksq[Co_White] == psq || ksq[Co_Black] == psq ||
      28      1848264 :        (us == Co_White && (BBTools::mask[psq].pawnAttack[Co_White] & SquareToBitboard(ksq[Co_Black]))))
      29       680504 :       result = kpk_invalid;
      30      3938792 :    else if (us == Co_White && SQRANK(psq) == 6 && ksq[us] != psq + 8 &&
      31       307604 :             (chebyshevDistance(ksq[~us], psq + 8) > 1 || (BBTools::mask[ksq[us]].king & SquareToBitboard(psq + 8))))
      32       280500 :       result = kpk_win;
      33      3364372 :    else if (us == Co_Black && (!(BBTools::mask[ksq[us]].king & ~(BBTools::mask[ksq[~us]].king | BBTools::mask[psq].pawnAttack[~us])) ||
      34      1848066 :                                (BBTools::mask[ksq[us]].king & SquareToBitboard(psq) & ~BBTools::mask[ksq[~us]].king)))
      35       200354 :       result = kpk_draw;
      36              :    else
      37      3164018 :       result = kpk_unknown; // done later
      38      4325376 : }
      39              : 
      40     11293326 : kpk_result KPKPosition::preCompute(const array1d<KPKPosition, KPKmaxIndex>& db) {
      41     11293326 :    return us == Co_White ? preCompute<Co_White>(db) : preCompute<Co_Black>(db);
      42              : }
      43              : 
      44     11293326 : template<Color Us> kpk_result KPKPosition::preCompute(const array1d<KPKPosition, KPKmaxIndex>& db) {
      45              :    constexpr Color      Them = (Us == Co_White ? Co_Black : Co_White);
      46              :    constexpr kpk_result good = (Us == Co_White ? kpk_win : kpk_draw);
      47              :    constexpr kpk_result bad  = (Us == Co_White ? kpk_draw : kpk_win);
      48     11293326 :    kpk_result r = kpk_invalid;
      49     84620316 :    BB::applyOn(BBTools::mask[ksq[us]].king, [&](const Square & k){ r |= (Us == Co_White ? db[KPKindex(Them, ksq[Them], k, psq)] : db[KPKindex(Them, k, ksq[Them], psq)]); });
      50              :    if (Us == Co_White) {
      51      5472720 :       if (SQRANK(psq) < 6) r |= db[KPKindex(Them, ksq[Them], ksq[Us], psq + 8)];
      52      5472720 :       if (SQRANK(psq) == 1 && psq + 8 != ksq[Us] && psq + 8 != ksq[Them]) r |= db[KPKindex(Them, ksq[Them], ksq[Us], psq + 8 + 8)];
      53              :    }
      54     11293326 :    return result = r & good ? good : r & kpk_unknown ? kpk_unknown : bad;
      55              : }
      56              : 
      57           11 : bool probe(Square wksq, const Square wpsq, const Square bksq, const Color us) {
      58           11 :    assert(isValidSquare(wksq));
      59           11 :    assert(isValidSquare(wpsq));
      60           11 :    assert(isValidSquare(bksq));
      61           11 :    assert(SQFILE(wpsq) <= 4);
      62              :    const unsigned idx = KPKindex(us, bksq, wksq, wpsq);
      63           11 :    assert(idx < KPKmaxIndex);
      64           11 :    return KPKBitbase[idx / 32] & (1 << (idx & 0x1F));
      65              : }
      66              : #endif
      67              : 
      68           22 : void init() {
      69              : #if !defined(WITH_SMALL_MEMORY)
      70           22 :    Logging::LogIt(Logging::logInfo) << "KPK init";
      71           22 :    Logging::LogIt(Logging::logInfo) << "KPK table size : " << KPKmaxIndex / 32 * sizeof(uint32_t) / 1024 << "Kb";
      72              :    array1d<KPKPosition, KPKmaxIndex> db;
      73              :    bool repeat = true;
      74      4325398 :    for (unsigned idx = 0; idx < KPKmaxIndex; ++idx) db[idx] = KPKPosition(idx); // init
      75              :    // loop until all the dababase is filled
      76              :    //int count = 0;
      77          352 :    while (repeat){
      78              :       repeat = false;
      79              :       //std::cout << count++ << std::endl;
      80     64880970 :       for (unsigned idx = 0; idx < KPKmaxIndex; ++idx){
      81    126989434 :          repeat |= (db[idx] == kpk_unknown && db[idx].preCompute(db) != kpk_unknown);
      82              :       }
      83              :    }
      84              :    // compress
      85      4325398 :    for (unsigned idx = 0; idx < KPKmaxIndex; ++idx) {
      86      4325376 :       if (db[idx] == kpk_win) { KPKBitbase[idx / 32] |= 1 << (idx & 0x1F); }
      87              :    }
      88              : #endif
      89           22 : }
      90              : 
      91              : } // namespace KPK
        

Generated by: LCOV version 2.0-1