- [Breakthrough](https://en.wikipedia.org/wiki/Breakthrough_(board_game))
- [Clobber](https://en.wikipedia.org/wiki/Clobber)
- [Cfour](https://en.wikipedia.org/wiki/Connect_Four), [Tic-tac-toe](https://en.wikipedia.org/wiki/Tic-tac-toe)
+- [Five Field Kono](https://en.wikipedia.org/wiki/Five_Field_Kono)
- [Flipersi](https://en.wikipedia.org/wiki/Reversi), [Flipello](https://en.wikipedia.org/wiki/Reversi#Othello)
+- [Fox and Hounds](https://boardgamegeek.com/boardgame/148180/fox-and-hounds)
- [Isolation](https://boardgamegeek.com/boardgame/1875/isolation)
- [Joust](https://www.chessvariants.com/programs.dir/joust.html)
- [Snailtrail](https://boardgamegeek.com/boardgame/37135/snailtrail)
parse_attribute("flagRegionWhite", v->flagRegion[WHITE]);
parse_attribute("flagRegionBlack", v->flagRegion[BLACK]);
parse_attribute("flagPieceCount", v->flagPieceCount);
+ parse_attribute("flagPieceBlockedWin", v->flagPieceBlockedWin);
parse_attribute("flagMove", v->flagMove);
parse_attribute("checkCounting", v->checkCounting);
parse_attribute("connectN", v->connectN);
// capture the flag
if ( capture_the_flag_piece()
&& flag_move()
- && (popcount(capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece()))>=flag_piece_count()))
- {
- result = (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count())
- && sideToMove == WHITE ? VALUE_DRAW : mate_in(ply);
+ && (
+ (popcount(capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece()))>=flag_piece_count()) // opponent has >= number of pieces needed to win
+ || //-or-
+ (
+ (flag_piece_blocked_win()) //flagPieceBlockedWin variant option true
+ && //-and-
+ (capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece())) //at least one piece in flag zone
+ && //-and-
+ !(capture_the_flag(sideToMove) & ~pieces()) //no empty squares in flag zone
+ )
+ )
+ )
+ {
+ result =
+ (
+ (
+ (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count()) // you have >= number of pieces needed to win
+ || //-or-
+ (
+ (flag_piece_blocked_win()) //flagPieceBlockedWin variant option true
+ && //-and-
+ (capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece())) //at least one piece in flag zone
+ && //-and-
+ !(capture_the_flag(~sideToMove) & ~pieces()) //no empty squares in flag zone
+ )
+ )
+ &&
+ (sideToMove == WHITE) //opponent is white
+ )
+ ? VALUE_DRAW : mate_in(ply); //then it's a draw, otherwise, win
return true;
}
if ( capture_the_flag_piece()
- && (!flag_move() || capture_the_flag_piece() == KING)
- && (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count()) )
+ && (!flag_move() || capture_the_flag_piece() == KING) //if black doesn't get an extra move to draw, or flag piece is king,
+ && ( //-and-
+ (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count()) // you have >= number of pieces needed to win
+ || //-or-
+ (
+ (flag_piece_blocked_win()) //flagPieceBlockedWin variant option true
+ && //-and-
+ (capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece())) //at least one piece in flag zone
+ && //-and-
+ !(capture_the_flag(~sideToMove) & ~pieces()) //no empty squares in flag zone
+ )
+ )
+ )
{
bool gameEnd = true;
// Check whether king can move to CTF zone
bool flag_move() const;
bool check_counting() const;
int flag_piece_count() const;
+ bool flag_piece_blocked_win() const;
int connect_n() const;
CheckCount checks_remaining(Color c) const;
MaterialCounting material_counting() const;
return var->flagPieceCount;
}
+inline bool Position::flag_piece_blocked_win() const {
+ assert(var != nullptr);
+ return var->flagPieceBlockedWin;
+}
+
inline bool Position::check_counting() const {
assert(var != nullptr);
return var->checkCounting;
return v;
}
- Variant* kono_variant() { //https://en.wikipedia.org/wiki/Five_Field_Kono
- Variant* v = chess_variant_base()->init();
- v->maxRank = RANK_5;
- v->maxFile = FILE_E;
- v->reset_pieces();
- v->add_piece(CUSTOM_PIECE_1, 'p', "mF"); //diagonally, no capture
- v->startFen = "ppppp/p3p/5/P3P/PPPPP w - - 0 1";
- v->flagPiece = CUSTOM_PIECE_1;
- v->flagRegion[WHITE] = make_bitboard(SQ_A5, SQ_B5, SQ_C5, SQ_D5, SQ_E5, SQ_A4, SQ_E4);
- v->flagRegion[BLACK] = make_bitboard(SQ_A1, SQ_B1, SQ_C1, SQ_D1, SQ_E1, SQ_A2, SQ_E2);
- v->flagPieceCount = 7;
- return v;
- }
-
Variant* fox_and_hounds_variant() { //https://boardgamegeek.com/boardgame/148180/fox-and-hounds
Variant* v = chess_variant_base()->init();
v->reset_pieces();
v->remove_piece(KNIGHT);
v->add_piece(CHANCELLOR, 'w'); // wolf
v->add_piece(ARCHBISHOP, 'f'); // fox
- v->add_piece(CUSTOM_PIECE_1, 's', "fKifmnD"); // seargent
+ v->add_piece(CUSTOM_PIECE_1, 's', "fKifmnD"); // sergeant
v->add_piece(CUSTOM_PIECE_2, 'n', "NN"); // nightrider
v->add_piece(CUSTOM_PIECE_3, 'e', "NNQ"); // elephant
v->startFen = "qwfrbbnk/pssppssp/1pp2pp1/8/8/8/8/1PP2PP1/PSSPPSSP/KNBBRFWQ w - - 0 1";
add("isolation7x7", isolation7x7_variant());
add("snailtrail", snailtrail_variant());
add("fox-and-hounds", fox_and_hounds_variant());
- add("kono", kono_variant());
#ifdef ALLVARS
add("duck", duck_variant());
#endif
PieceType flagPiece = NO_PIECE_TYPE;
Bitboard flagRegion[COLOR_NB] = {};
int flagPieceCount = 1;
+ bool flagPieceBlockedWin = false;
bool flagMove = false;
bool checkCounting = false;
int connectN = 0;
# [PieceSet]: multiple piece types [letters defined for pieces, e.g., nbrq]
# [Bitboard]: list of squares [e.g., d4 e4 d5 e5]. * can be used as wildcard for files (e.g., *1 is the first rank)
# [Value]: game result for the side to move [win, loss, draw]
-# [MaterialCounting]: material couting rules for adjudication [janggi, unweighted, whitedrawodds, blackdrawodds, none]
+# [MaterialCounting]: material counting rules for adjudication [janggi, unweighted, whitedrawodds, blackdrawodds, none]
# [CountingRule]: makruk, cambodian, or ASEAN counting rules [makruk, cambodian, asean, none]
# [ChasingRule]: xiangqi chasing rules [axf, none]
# [EnclosingRule]: reversi or ataxx enclosing rules [reversi, ataxx, none]
# flagMove: black gets one more move after white captures the flag [bool] (default: false)
# checkCounting: enable check count win rule (check count is communicated via FEN, see 3check) [bool] (default: false)
# flagPieceCount: number of flag pieces that have to be in the flag zone [int] (default: 1)
+# flagPieceBlockedWin: for flagPieceCount > 1. if at least one piece in flag zone and all others occupied by opponent pieces, win. [bool] (default: false)
# connectN: number of aligned pieces for win [int] (default: 0)
# materialCounting: enable material counting rules [MaterialCounting] (default: none)
# countingRule: enable counting rules [CountingRule] (default: none)
promotionRegionBlack = *9 *8 *7 *6 *5 *4 *3 *2 *1
# Chess vs Hoppel-Poppel
-# Assymetrical game, Chess army vs Hoppel Poppel army. Credits to Procyon for the definition.
+# Asymmetrical game, Chess army vs Hoppel Poppel army. Credits to Procyon for the definition.
# Variant defined in Pychess discord and previously playable with Chessboi bot.
[chessvshp:chess]
soldier = s
startFen = rijqkjir/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
# Orda vs Empire
-# Assymetrical game, Empire army vs Orda army. Empire (as Black again), no Soldiers, 8 x Imperial Pawns but on the 3rd rank. Empire rules in place. Yurt is a mNcK. Credits to Procyon for the definition.
+# Asymmetrical game, Empire army vs Orda army. Empire (as Black again), no Soldiers, 8 x Imperial Pawns but on the 3rd rank. Empire rules in place. Yurt is a mNcK. Credits to Procyon for the definition.
# Variant defined in Pychess discord and previously playable with Chessboi bot.
[ordavsempire:chess]
centaur = h
duckGating = true
stalemateValue = win
+[kono]
+maxRank = 5
+maxFile = e
+customPiece1 = p:mF
+startFen = ppppp/p3p/5/P3P/PPPPP w - - 0 1
+flagPiece = p
+flagRegionWhite = a5 b5 c5 d5 e5 a4 e4
+flagRegionBlack = a1 b1 c1 d1 e1 a2 e2
+flagPieceCount = 7
+flagPieceBlockedWin = true
+
+#https://www.chessvariants.com/large.dir/xhess.html
+[xhess:chess]
+pieceToCharTable = HNBRQ......CI........Khnbrq......ci........k
+maxRank = 10
+maxFile = j
+promotionRegionWhite = *10
+promotionPieceTypes = nbrqci
+flagPiece = k
+flagRegionWhite = *10
+flagRegionBlack = *1
+pawnTypes = h
+cannon = c
+customPiece1 = i:NN
+customPiece2 = h:mfWcfFfhmnN
+startFen = r8r/3nkqn3/hcb1ii1bch/1hhhhhhhh1/10/10/1HHHHHHHH1/HCB1II1BCH/3NKQN3/R8R
+#technically not needed because of initial setup
+##enPassantRegion = 0
+##castling = false
+
+#https://boardgamegeek.com/boardgame/32/buffalo-chess
+[buffalo]
+pieceToCharTable = B...D................Cb...d................c
+maxRank = 7
+maxFile = k
+customPiece1 = b:mfW
+customPiece2 = c:K
+customPiece3 = d:mQ
+startFen = bbbbbbbbbbb/11/11/11/11/3DDCDD3/11 w - - 0 1
+flagPiece = b
+flagRegionBlack = *1
+mobilityRegionWhiteCustomPiece2 = *2 *3 *4 *5 *6
+mobilityRegionWhiteCustomPiece3 = *2 *3 *4 *5 *6
+extinctionValue = loss
+extinctionPieceTypes = *
+stalemateValue = loss
+
+#https://www.zillions-of-games.com/cgi-bin/zilligames/submissions.cgi?do=show;id=1596
+[knights-halma]
+maxRank = 8
+maxFile = h
+customPiece1 = n:mN
+startFen = 5nnn/5nnn/5nnn/8/8/NNN5/NNN5/NNN5 w
+flagPiece = n
+flagRegionWhite = f8 g8 h8 f7 g7 h7 g6 g6 h8
+flagRegionBlack = a3 b3 c3 a2 b2 c2 a1 b1 c1
+flagPieceCount = 9
+stalemateValue = loss
+nFoldRule = 2
+nFoldValue = loss
+nMoveRule = 0
+
#https://www.zillions-of-games.com/cgi-bin/zilligames/submissions.cgi/76202?do=show;id=83
#pawns can be caught in the blast in this one
[allexplodeatomic:nocheckatomic]