Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Priority drops #805

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,18 @@ Variant* VariantParser<DoCheck>::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);
Expand Down
2 changes: 2 additions & 0 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For efficiency, I think these two new conditions should be checked in reverse order.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is fairly trivial logic and does not depend on other moves, it should be more suitable to validate this in move generation and pseudo-legal validation instead of in legal validation.

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()))
Expand Down
3 changes: 3 additions & 0 deletions src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1532,13 +1533,15 @@ 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];
}

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];
}

Expand Down
1 change: 1 addition & 0 deletions src/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ struct Variant {
bool mustCapture = false;
bool mustDrop = false;
PieceType mustDropType = ALL_PIECES;
bool isPriorityDrop[PIECE_TYPE_NB] = {};
Copy link
Member

@ianfab ianfab Jul 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more consistent and storage efficient to use a PieceSet here, similar as for other properties. This would also simplify the parsing, since it can reuse existing logic. It could perhaps also already be made color-specific, similar as promotionPieceTypes or the like.

bool pieceDrops = false;
bool dropLoop = false;
bool capturesToHand = false;
Expand Down
1 change: 1 addition & 0 deletions src/variants.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down