From b8274a7ac6cc850e712ad8fb25397d090a511a86 Mon Sep 17 00:00:00 2001 From: RainRat Date: Tue, 26 Sep 2023 02:44:24 -0700 Subject: [PATCH] flagPieceSafe, Squatter (#719) --- src/parser.cpp | 3 +++ src/position.h | 33 ++++++++++++++++++++++++++++++++- src/variant.h | 1 + src/variants.ini | 25 ++++++++++++------------- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index 3d822ebb4..48b8cc9af 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -496,6 +496,7 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("flagPieceCount", v->flagPieceCount); parse_attribute("flagPieceBlockedWin", v->flagPieceBlockedWin); parse_attribute("flagMove", v->flagMove); + parse_attribute("flagPieceSafe", v->flagPieceSafe); parse_attribute("checkCounting", v->checkCounting); parse_attribute("connectN", v->connectN); parse_attribute("connectHorizontal", v->connectHorizontal); @@ -598,6 +599,8 @@ Variant* VariantParser::parse(Variant* v) { if (v->mutuallyImmuneTypes) std::cerr << "Can not use kings or pseudo-royal with mutuallyImmuneTypes." << std::endl; } + if (v->flagPieceSafe && v->blastOnCapture) + std::cerr << "Can not use flagPieceSafe with blastOnCapture (flagPieceSafe uses simple assessment that does not see blast)." << std::endl; } return v; } diff --git a/src/position.h b/src/position.h index 2311776da..7b9b4cd8d 100644 --- a/src/position.h +++ b/src/position.h @@ -962,9 +962,40 @@ inline bool Position::flag_move() const { inline bool Position::flag_reached(Color c) const { assert(var != nullptr); - return (flag_region(c) & pieces(c, flag_piece(c))) + bool simpleResult = + (flag_region(c) & pieces(c, flag_piece(c))) && ( popcount(flag_region(c) & pieces(c, flag_piece(c))) >= var->flagPieceCount || (var->flagPieceBlockedWin && !(flag_region(c) & ~pieces()))); + + if (simpleResult&&var->flagPieceSafe) + { + Bitboard piecesInFlagZone = flag_region(c) & pieces(c, flag_piece(c)); + int potentialPieces = (popcount(piecesInFlagZone)); + /* + There isn't a variant that uses it, but in the hypothetical game where the rules say I need 3 + pieces in the flag zone and they need to be safe: If I have 3 pieces there, but one is under + threat, I don't think I can declare victory. If I have 4 there, but one is under threat, I + think that's victory. + */ + while (piecesInFlagZone) + { + Square sr = pop_lsb(piecesInFlagZone); + Bitboard flagAttackers = attackers_to(sr, ~c); + + if ((potentialPieces < var->flagPieceCount) || (potentialPieces >= var->flagPieceCount + 1)) break; + while (flagAttackers) + { + Square currentAttack = pop_lsb(flagAttackers); + if (legal(make_move(currentAttack, sr))) + { + potentialPieces--; + break; + } + } + } + return potentialPieces >= var->flagPieceCount; + } + return simpleResult; } inline bool Position::check_counting() const { diff --git a/src/variant.h b/src/variant.h index cb2fe0514..e8899f397 100644 --- a/src/variant.h +++ b/src/variant.h @@ -147,6 +147,7 @@ struct Variant { int flagPieceCount = 1; bool flagPieceBlockedWin = false; bool flagMove = false; + bool flagPieceSafe = false; bool checkCounting = false; int connectN = 0; bool connectHorizontal = true; diff --git a/src/variants.ini b/src/variants.ini index e3bdf0dad..73bf9e99c 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -263,6 +263,7 @@ # flagPieceCount: number of flag pieces that have to be in the flag zone [int] (default: 1) # flagPieceBlockedWin: for flagPieceCount > 1, win if at least one flag piece in flag zone and all others occupied by pieces [bool] (default: false) # flagMove: the other side gets one more move after one reaches the flag zone [bool] (default: false) +# flagPieceSafe: the flag piece must be safe to win [bool] (default: false) # checkCounting: enable check count win rule (check count is communicated via FEN, see 3check) [bool] (default: false) # connectN: number of aligned pieces for win [int] (default: 0) # connectVertical: connectN looks at Vertical rows [bool] (default: true) @@ -1558,26 +1559,18 @@ nFoldRule = 2 [alapo:chess] #https://www.chessvariants.org/small.dir/alapo.html -#Reaching the opponent's back row such that the piece isn't immediately -#captured is a win. Let's promote to a victory piece (Amazon), then, moving -#that piece to anywhere not on the back row is a victory. There's nothing about -#the Amazon in the rules, just a powerful piece. -pieceToCharTable = ..BRQ........AFW.....K..brq........afw.....k +pieceToCharTable = ..BRQ.........FW.....K..brq.........fw.....k maxRank = 6 maxFile = f wazir = w fers = f -amazon = a king = - commoner = k startFen = rbqqbr/wfkkfw/6/6/WFKKFW/RBQQBR -promotionRegionWhite = *6 -promotionRegionBlack = *1 -promotedPieceType = w:a r:a f:a b:a k:a q:a -mandatoryPiecePromotion = true -flagPiece = a -flagRegionWhite = *5 *4 *3 *2 *1 -flagRegionBlack = *6 *5 *4 *3 *2 +flagRegionWhite = *6 +flagRegionBlack = *1 +flagPieceSafe = true +flagMove = true stalemateValue = loss nMoveRule = 0 nFoldRule = 0 @@ -1740,6 +1733,12 @@ castlingRank = 2 [castle:chess] castlingWins = q +#https://github.com/yagu0/vchess/blob/master/client/src/translations/rules/Squatter1/en.pug +[squatter:chess] +flagRegionWhite = *8 +flagRegionBlack = *1 +flagPieceSafe = true + [opposite-castling:chess] oppositeCastling = true