From 736e2d998c0d310512572df185d36d7132031294 Mon Sep 17 00:00:00 2001 From: RainRat Date: Tue, 4 Apr 2023 05:26:51 -0700 Subject: [PATCH] add kono and fox-and-hounds (#628) --- src/movegen.cpp | 2 +- src/position.cpp | 6 +++--- src/position.h | 6 ++++++ src/variant.cpp | 28 ++++++++++++++++++++++++++++ src/variant.h | 1 + src/variants.ini | 1 + 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 6c852aa..b33d986 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -388,7 +388,7 @@ namespace { target = pos.checkers(); } - // Remove inaccesible squares (outside board + wall squares) + // Remove inaccessible squares (outside board + wall squares) target &= pos.board_bb(); moveList = generate_pawn_moves(pos, moveList, target); diff --git a/src/position.cpp b/src/position.cpp index 72afba8..03b0a9d 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -2675,15 +2675,15 @@ bool Position::is_immediate_game_end(Value& result, int ply) const { // capture the flag if ( capture_the_flag_piece() && flag_move() - && (capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece()))) + && (popcount(capture_the_flag(sideToMove) & pieces(sideToMove, capture_the_flag_piece()))>=flag_piece_count())) { - result = (capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece())) + result = (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count()) && sideToMove == WHITE ? VALUE_DRAW : mate_in(ply); return true; } if ( capture_the_flag_piece() && (!flag_move() || capture_the_flag_piece() == KING) - && (capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))) + && (popcount(capture_the_flag(~sideToMove) & pieces(~sideToMove, capture_the_flag_piece()))>=flag_piece_count()) ) { bool gameEnd = true; // Check whether king can move to CTF zone diff --git a/src/position.h b/src/position.h index 7fe9951..6e179c8 100644 --- a/src/position.h +++ b/src/position.h @@ -201,6 +201,7 @@ public: Bitboard capture_the_flag(Color c) const; bool flag_move() const; bool check_counting() const; + int flag_piece_count() const; int connect_n() const; CheckCount checks_remaining(Color c) const; MaterialCounting material_counting() const; @@ -930,6 +931,11 @@ inline bool Position::flag_move() const { return var->flagMove; } +inline int Position::flag_piece_count() const { + assert(var != nullptr); + return var->flagPieceCount; +} + inline bool Position::check_counting() const { assert(var != nullptr); return var->checkCounting; diff --git a/src/variant.cpp b/src/variant.cpp index 8196915..fd8564f 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -542,6 +542,32 @@ namespace { 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->add_piece(CUSTOM_PIECE_1, 'h', "mfF"); //Hound + v->add_piece(CUSTOM_PIECE_2, 'f', "mF"); //Fox + v->startFen = "1h1h1h1h/8/8/8/8/8/8/4F3 w - - 0 1"; + v->stalemateValue = -VALUE_MATE; + v->flagPiece = CUSTOM_PIECE_2; + v->flagRegion[WHITE] = Rank8BB; + return v; + } + // Three-check chess // Check the king three times to win // https://lichess.org/variant/threeCheck @@ -1789,6 +1815,8 @@ void VariantMap::init() { add("isolation", isolation_variant()); 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 diff --git a/src/variant.h b/src/variant.h index e1a460a..c7df2f7 100644 --- a/src/variant.h +++ b/src/variant.h @@ -143,6 +143,7 @@ struct Variant { int extinctionOpponentPieceCount = 0; PieceType flagPiece = NO_PIECE_TYPE; Bitboard flagRegion[COLOR_NB] = {}; + int flagPieceCount = 1; bool flagMove = false; bool checkCounting = false; int connectN = 0; diff --git a/src/variants.ini b/src/variants.ini index 85be25b..c6f5dd6 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -250,6 +250,7 @@ # flagRegionBlack: black's target region for capture the flag win rule [Bitboard] (default: ) # 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) # 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) -- 1.7.0.4