Skip to content

Commit

Permalink
flagPieceSafe, Squatter (fairy-stockfish#719)
Browse files Browse the repository at this point in the history
  • Loading branch information
RainRat authored Sep 26, 2023
1 parent 994eb7b commit b8274a7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ Variant* VariantParser<DoCheck>::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);
Expand Down Expand Up @@ -598,6 +599,8 @@ Variant* VariantParser<DoCheck>::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;
}
Expand Down
33 changes: 32 additions & 1 deletion src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
25 changes: 12 additions & 13 deletions src/variants.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit b8274a7

Please sign in to comment.