From a2b8b9013cea10ef122bfa469aa3ce51fbe9b950 Mon Sep 17 00:00:00 2001 From: Peter Karpov Date: Thu, 4 Jul 2024 15:26:55 +0300 Subject: [PATCH] Initial implementation of priority drops --- src/parser.cpp | 12 ++++++++++++ src/position.cpp | 2 ++ src/position.h | 3 +++ src/variant.h | 1 + src/variants.ini | 1 + 5 files changed, 19 insertions(+) diff --git a/src/parser.cpp b/src/parser.cpp index 3ebf1b16f..f7f6d87ac 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -410,6 +410,18 @@ Variant* VariantParser::parse(Variant* v) { if (DoCheck && (idx == std::string::npos || idx2 == std::string::npos)) std::cerr << "promotedPieceType - Invalid piece type: " << token << std::endl; } + // priority drops + const auto& it_pr_drop = config.find("priorityDropTypes"); + if (it_pr_drop != config.end()) + { + char token; + size_t idx = 0; + std::stringstream ss(it_pr_drop->second); + while (ss >> token && ((idx = v->pieceToChar.find(toupper(token))) != std::string::npos)) + v->isPriorityDrop[PieceType(idx)] = true; + if (DoCheck && idx == std::string::npos && token != '-') + std::cerr << "priorityDropTypes - Invalid piece type: " << token << std::endl; + } parse_attribute("piecePromotionOnCapture", v->piecePromotionOnCapture); parse_attribute("mandatoryPawnPromotion", v->mandatoryPawnPromotion); parse_attribute("mandatoryPiecePromotion", v->mandatoryPiecePromotion); diff --git a/src/position.cpp b/src/position.cpp index b9f34be44..752e97da5 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1086,6 +1086,8 @@ bool Position::legal(Move m) const { if (popcount((DarkSquares & to ? DarkSquares : ~DarkSquares) & pieces(us, BISHOP)) + 1 > (count_with_hand(us, BISHOP) + 1) / 2) return false; } + if (type_of(m) == DROP && (!var->isPriorityDrop[type_of(moved_piece(m))]) && priorityDropCountInHand[us] > 0) + return false; // No legal moves from target square if (immobility_illegal() && (type_of(m) == DROP || type_of(m) == NORMAL) && !(PseudoMoves[0][us][type_of(moved_piece(m))][to] & board_bb())) diff --git a/src/position.h b/src/position.h index adaeeb6ad..b9256f456 100644 --- a/src/position.h +++ b/src/position.h @@ -369,6 +369,7 @@ class Position { bool tsumeMode; bool chess960; int pieceCountInHand[COLOR_NB][PIECE_TYPE_NB]; + int priorityDropCountInHand[COLOR_NB]; int virtualPieces; Bitboard promotedPieces; void add_to_hand(Piece pc); @@ -1532,6 +1533,7 @@ inline void Position::add_to_hand(Piece pc) { if (variant()->freeDrops) return; pieceCountInHand[color_of(pc)][type_of(pc)]++; pieceCountInHand[color_of(pc)][ALL_PIECES]++; + priorityDropCountInHand[color_of(pc)] += var->isPriorityDrop[type_of(pc)]; psq += PSQT::psq[pc][SQ_NONE]; } @@ -1539,6 +1541,7 @@ inline void Position::remove_from_hand(Piece pc) { if (variant()->freeDrops) return; pieceCountInHand[color_of(pc)][type_of(pc)]--; pieceCountInHand[color_of(pc)][ALL_PIECES]--; + priorityDropCountInHand[color_of(pc)] -= var->isPriorityDrop[type_of(pc)]; psq -= PSQT::psq[pc][SQ_NONE]; } diff --git a/src/variant.h b/src/variant.h index aa2738356..6de41dc74 100644 --- a/src/variant.h +++ b/src/variant.h @@ -90,6 +90,7 @@ struct Variant { bool mustCapture = false; bool mustDrop = false; PieceType mustDropType = ALL_PIECES; + bool isPriorityDrop[PIECE_TYPE_NB] = {}; bool pieceDrops = false; bool dropLoop = false; bool capturesToHand = false; diff --git a/src/variants.ini b/src/variants.ini index 0810312c6..eb60f3dbb 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -212,6 +212,7 @@ # mustCapture: captures are mandatory (check evasion still takes precedence) [bool] (default: false) # mustDrop: drops are mandatory (e.g., for Sittuyin setup phase) [bool] (default: false) # mustDropType: piece type for which piece drops are mandatory [PieceType] (default: *) +# priorityDropTypes: piece types that must be dropped before dropping the other pieces [PieceType] (default: none) # pieceDrops: enable piece drops [bool] (default: false) # dropLoop: captures promoted pieces are not demoted [bool] (default: false) # capturesToHand: captured pieces go to opponent's hand [bool] (default: false)