From bddaaf2904599bae7df7970528b1b25ff840304d Mon Sep 17 00:00:00 2001 From: alperatalayn Date: Mon, 12 Feb 2024 18:06:44 +0300 Subject: [PATCH 01/12] added custom pieces and commit gates --- README.md | 1 + src/parser.cpp | 3 +- src/position.cpp | 87 ++++++++++++++++++++++++++++++++++++++++-------- src/position.h | 36 ++++++++++++++++++++ src/variant.cpp | 33 ++++++++++++++++++ 5 files changed, 145 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f118cf304..f6057f10b 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ The games currently supported besides chess are listed below. Fairy-Stockfish ca - [Crazyhouse](https://en.wikipedia.org/wiki/Crazyhouse), [Loop](https://en.wikipedia.org/wiki/Crazyhouse#Variations), [Chessgi](https://en.wikipedia.org/wiki/Crazyhouse#Variations), [Pocket Knight](http://www.chessvariants.com/other.dir/pocket.html), Capablanca-Crazyhouse - [Bughouse](https://en.wikipedia.org/wiki/Bughouse_chess), [Koedem](http://schachclub-oetigheim.de/wp-content/uploads/2016/04/Koedem-rules.pdf) - [Seirawan](https://en.wikipedia.org/wiki/Seirawan_chess), Seirawan-Crazyhouse, [Dragon Chess](https://www.edami.com/dragonchess/) +- [Musketeer](https://www.musketeerchess.net) - [Amazon](https://www.chessvariants.com/diffmove.dir/amazone.html), [Chigorin](https://www.chessvariants.com/diffsetup.dir/chigorin.html), [Almost chess](https://en.wikipedia.org/wiki/Almost_Chess) - [Hoppel-Poppel](http://www.chessvariants.com/diffmove.dir/hoppel-poppel.html), New Zealand - [Antichess](https://lichess.org/variant/antichess), [Giveaway](http://www.chessvariants.com/diffobjective.dir/giveaway.old.html), [Suicide](https://www.freechess.org/Help/HelpFiles/suicide_chess.html), [Losers](https://www.chessclub.com/help/Wild17), [Codrus](http://www.binnewirtz.com/Schlagschach1.htm) diff --git a/src/parser.cpp b/src/parser.cpp index 9d2b55b98..5ce0284b2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -472,7 +472,8 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("wallingRegionBlack", v->wallingRegion[BLACK]); parse_attribute("wallingRegion", v->wallingRegion[WHITE]); parse_attribute("wallingRegion", v->wallingRegion[BLACK]); - parse_attribute("seirawanGating", v->seirawanGating); + parse_attribute("seirawanGating", v->seirawanGating); + parse_attribute("commitGates", v->commitGates); parse_attribute("cambodianMoves", v->cambodianMoves); parse_attribute("diagonalLines", v->diagonalLines); parse_attribute("pass", v->pass[WHITE]); diff --git a/src/position.cpp b/src/position.cpp index bf6e60f28..c35595eb2 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -267,10 +267,13 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, Rank r = max_rank(); Square sq = SQ_A1 + r * NORTH; + int commitFile = 0; + int rank = 0; + // 1. Piece placement while ((ss >> token) && !isspace(token)) - { - if (isdigit(token)) + { + if (isdigit(token) && (!commit_gates() || (rank != 0 && rank != max_rank() + 2))) { #ifdef LARGEBOARDS if (isdigit(ss.peek())) @@ -283,12 +286,14 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, } else if (token == '/') - { - sq = SQ_A1 + --r * NORTH; + { + if(!commit_gates() || (rank != 0 && rank <= max_rank())) sq += 2 * SOUTH + (FILE_MAX - max_file()) * EAST; + ++rank; + commitFile = 0; if (!is_ok(sq)) break; } - + else if(token == '*') ++commitFile; // Stop before pieces in hand else if (token == '[') break; @@ -309,8 +314,15 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, { if (ss.peek() == '~') ss >> token; - put_piece(Piece(idx), sq, token == '~'); - ++sq; + + if(v->commitGates && (rank == 0 || rank == max_rank() + 2)){ + commit_piece(Piece(idx), File(commitFile)); + ++commitFile; + } + else{ + put_piece(Piece(idx), sq, token == '~'); + ++sq; + } } // Promoted shogi pieces @@ -319,6 +331,16 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, ss >> token; put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq, true, Piece(idx)); ++sq; + if(v->commitGates && (rank == 0 || rank == max_rank() + 2)){ + //std::cout << "C\n"; + commit_piece(Piece(idx), File(commitFile)); + //std::cout << "D\n"; + ++commitFile; + } + else { + put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq, true, Piece(idx)); + ++sq; + } } } // Pieces in hand @@ -377,7 +399,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, } // Set gates (and skip castling rights) - if (gating()) + if (gating() && !commit_gates()) { st->gatesBB[c] |= rsq; if (token == 'K' || token == 'Q') @@ -604,6 +626,7 @@ void Position::set_state(StateInfo* si) const { si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO; si->checkersBB = count(sideToMove) ? attackers_to(square(sideToMove), ~sideToMove) : Bitboard(0); si->move = MOVE_NONE; + si->removedGatingType = NO_PIECE_TYPE; set_check_info(si); @@ -680,6 +703,13 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string int emptyCnt; std::ostringstream ss; + if(commit_gates()){ + for(File f = FILE_A; f < max_file(); ++f){ + if(has_committed_piece(BLACK, f)) ss << piece_to_char()[make_piece(BLACK, committedGates[BLACK][f])]; + else ss << "*"; + } + ss << "/"; + } for (Rank r = max_rank(); r >= RANK_1; --r) { @@ -713,7 +743,13 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string if (r > RANK_1) ss << '/'; } - + if(commit_gates()){ + ss << "/"; + for(File f = FILE_A; f <= max_file(); ++f){ + if(has_committed_piece(WHITE, f)) ss << piece_to_char()[make_piece(WHITE, committedGates[WHITE][f])]; + else ss << "*"; + } + } // SFEN if (sfen) { @@ -732,8 +768,8 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string return ss.str(); } - // pieces in hand - if (!variant()->freeDrops && (piece_drops() || seirawan_gating())) + // pieces in hand TODO: Check if this is correct + if (piece_drops() || (seirawan_gating() && !commit_gates()) || arrow_gating()) { ss << '['; if (holdings != "-") @@ -760,7 +796,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string if (can_castle(WHITE_OOO)) ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OOO))) : 'Q'); - if (gating() && gates(WHITE) && (!seirawan_gating() || count_in_hand(WHITE, ALL_PIECES) > 0 || captures_to_hand())) + if (gating() && !commit_gates() && gates(WHITE) && (!seirawan_gating() || count_in_hand(WHITE, ALL_PIECES) > 0 || captures_to_hand())) for (File f = FILE_A; f <= max_file(); ++f) if ( (gates(WHITE) & file_bb(f)) // skip gating flags redundant with castling flags @@ -779,6 +815,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string if (can_castle(BLACK_OOO)) ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OOO))) : 'q'); + // TODO: Check line 799, apply same to here if needed if (gating() && gates(BLACK) && (!seirawan_gating() || count_in_hand(BLACK, ALL_PIECES) > 0 || captures_to_hand())) for (File f = FILE_A; f <= max_file(); ++f) if ( (gates(BLACK) & file_bb(f)) @@ -788,8 +825,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string && !(can_castle(BLACK_OOO) && f == file_of(castling_rook_square(BLACK_OOO)))) ss << char('a' + f); - if (!can_castle(ANY_CASTLING) && !(gating() && (gates(WHITE) | gates(BLACK)))) - ss << '-'; + if (!can_castle(ANY_CASTLING) && !(gating() && !commit_gates() && (gates(WHITE) | gates(BLACK)))) // Counting limit or ep-square if (st->countingLimit) @@ -1943,7 +1979,20 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->materialKey ^= Zobrist::psq[gating_piece][pieceCount[gating_piece]]; st->nonPawnMaterial[us] += PieceValue[MG][gating_piece]; } + if(st->removedGatingType > NO_PIECE_TYPE){ + commit_piece(piece_on(from), file_of(from)); + } + // Musketeer gating + if(commit_gates()){ + Rank r = rank_of(from); + if(r == RANK_1 && has_committed_piece(WHITE, file_of(from))){ + st->removedGatingType = drop_committed_piece(WHITE, file_of(from)); + } else if(r == max_rank() && has_committed_piece(BLACK, file_of(from))){ + st->removedGatingType = drop_committed_piece(BLACK, file_of(from)); + } + else st->removedGatingType = NO_PIECE_TYPE; + } // Remove gates if (gating()) { @@ -2167,6 +2216,10 @@ void Position::undo_move(Move m) { st->gatesBB[us] |= gating_square(m); } + if(st->removedGatingType > NO_PIECE_TYPE){ + commit_piece(piece_on(from), file_of(from)); + } + if (type_of(m) == PROMOTION) { assert((promotion_zone(us) & to) || sittuyin_promotion()); @@ -2260,6 +2313,12 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ Piece castlingKingPiece = piece_on(Do ? from : to); Piece castlingRookPiece = piece_on(Do ? rfrom : rto); + if(commit_gates()){ + if(has_committed_piece(us, file_of(rfrom))){ + drop_committed_piece(us, file_of(rfrom)); + } + } + if (Do && Eval::useNNUE) { auto& dp = st->dirtyPiece; diff --git a/src/position.h b/src/position.h index 4ee936657..8cbdd8891 100644 --- a/src/position.h +++ b/src/position.h @@ -83,6 +83,7 @@ struct StateInfo { bool pass; Move move; int repetition; + PieceType removedGatingType; // Used by NNUE Eval::NNUE::Accumulator accumulator; @@ -180,6 +181,7 @@ class Position { bool walling() const; WallingRule walling_rule() const; bool seirawan_gating() const; + bool commit_gates() const; bool cambodian_moves() const; Bitboard diagonal_lines() const; bool pass(Color c) const; @@ -367,12 +369,17 @@ class Position { bool tsumeMode; bool chess960; int pieceCountInHand[COLOR_NB][PIECE_TYPE_NB]; + PieceType committedGates[COLOR_NB][FILE_NB]; int virtualPieces; Bitboard promotedPieces; void add_to_hand(Piece pc); void remove_from_hand(Piece pc); void drop_piece(Piece pc_hand, Piece pc_drop, Square s); void undrop_piece(Piece pc_hand, Square s); + void commit_piece(Piece pc, File fl); + void uncommit_piece(Color cl, File fl); + bool has_committed_piece(Color cl, File fl) const; + PieceType drop_committed_piece(Color cl, File fl); Bitboard find_drop_region(Direction dir, Square s, Bitboard occupied) const; }; @@ -797,6 +804,11 @@ inline WallingRule Position::walling_rule() const { return var->wallingRule; } +inline bool Position::commit_gates() const { + assert(var != nullptr); + return var->seirawanGating; +} + inline bool Position::seirawan_gating() const { assert(var != nullptr); return var->seirawanGating; @@ -1549,6 +1561,30 @@ inline bool Position::can_drop(Color c, PieceType pt) const { return variant()->freeDrops || count_in_hand(c, pt) > 0; } +inline void Position::commit_piece(Piece pc, File fl){ + committedGates[color_of(pc)][fl] = type_of(pc); +} + +inline void Position::uncommit_piece(Color cl, File fl){ + //std::cout << "uncommit_piece\n"; + committedGates[cl][fl] = NO_PIECE_TYPE; +} + +inline bool Position::has_committed_piece(Color cl, File fl) const { + return committedGates[cl][fl] > NO_PIECE_TYPE; +} + +inline PieceType Position::drop_committed_piece(Color cl, File fl){ + if(has_committed_piece(cl, fl)){ + Square dropSquare = make_square(fl, (cl == WHITE)? RANK_1 : max_rank()); + PieceType committedPieceType = committedGates[cl][fl]; + put_piece(make_piece(cl, committedPieceType), dropSquare, false, NO_PIECE); + uncommit_piece(cl, fl); + return committedPieceType; + } + else return NO_PIECE_TYPE; +} + } // namespace Stockfish #endif // #ifndef POSITION_H_INCLUDED diff --git a/src/variant.cpp b/src/variant.cpp index 386c21d5d..008f9ec58 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1207,6 +1207,38 @@ namespace { return v; } #ifdef LARGEBOARDS + // Musketeer Chess + // https://musketeerchess.net + // A Seirawan-inspired variant with unique gating mechanics. + // Pieces are introduced to predefined squares, chosen before game start, this is named Gating Selection = Where the chosen piece is going to be gated + // Gating of the additional pieces is activated when first-rank pieces move for the first time. Only the additional piece waiting to be gated on that specific square can be introduced. + // Features a variety of new pieces, thus there is a piece selection step where both players must agree to chose the additional piece combination. + // In Fairy Stockfish the Piece Selection is determined at the PieceToCharTable, this default combination can be changed in variant.ini + Variant* musketeer_variant() { + Variant* v = chess_variant(); + v->variantTemplate = "seirawan"; + v->pieceToCharTable = "PNBRQ.C..........LO..Kpnbrq.c..........lo..k"; // The default piece combo in Musketeer Chess is Leopard L and Musketeer Cannon O + v->add_piece(ARCHBISHOP, 'a'); + v->add_piece(CHANCELLOR, 'c'); + v->add_piece(AMAZON, 'd'); // also called Dragon in Musketeer, but Amazon is the most accurate + v->add_piece(CUSTOM_PIECE_1, 'l', "F2N"); // Leopard + v->add_piece(CUSTOM_PIECE_2, 'h', "ADGH"); // Hawk + v->add_piece(CUSTOM_PIECE_3, 'u', "NC"); // Unicorn + V->add_piece(CUSTOM_PIECE_4, 's', "B2ND"); // Spider + v->add_piece(CUSTOM_PIECE_5, 'f', "B3vND"); // Fortress + v->add_piece(CUSTOM_PIECE_6, 'e', "FWDA"); // Musketeer Elephant + v->add_piece(CUSTOM_PIECE_7, 'o', "FWDsN"); // Musketeer Cannon + + //"********/rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/******** w KQkq - 0 1" + v->startFen = "********/rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/******** w KQkq - 0 1"; + + // TODO: Confirm the following + v->gating = true; + v->commitGates = true; + v->promotionPieceTypes[BLACK] = piece_set(CUSTOM_PIECE_1) | CUSTOM_PIECE_7 | QUEEN | ROOK | BISHOP | KNIGHT; + v->promotionPieceTypes[WHITE] = piece_set(CUSTOM_PIECE_1) | CUSTOM_PIECE_7 | QUEEN | ROOK | BISHOP | KNIGHT; + return v; + } // Shogi (Japanese chess) // https://en.wikipedia.org/wiki/Shogi Variant* shogi_variant() { @@ -1849,6 +1881,7 @@ void VariantMap::init() { add("placement", placement_variant()); add("sittuyin", sittuyin_variant()); add("seirawan", seirawan_variant()); + add("musketeer", musketeer_variant()); add("shouse", shouse_variant()); add("dragon", dragon_variant()); add("paradigm", paradigm_variant()); From 5dd721b329721ac56124dad51434a27fd734ff68 Mon Sep 17 00:00:00 2001 From: alperatalayn Date: Tue, 20 Feb 2024 06:06:12 +0300 Subject: [PATCH 02/12] fixed gating and initializing --- src/position.cpp | 2 +- src/position.h | 2 +- src/variant.cpp | 2 +- src/variant.h | 1 + src/variants.ini | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index c35595eb2..8761a29c4 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -769,7 +769,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string } // pieces in hand TODO: Check if this is correct - if (piece_drops() || (seirawan_gating() && !commit_gates()) || arrow_gating()) + if (!variant()->freeDrops && (piece_drops() || seirawan_gating()) && !commit_gates()) { ss << '['; if (holdings != "-") diff --git a/src/position.h b/src/position.h index 8cbdd8891..4c2d2db47 100644 --- a/src/position.h +++ b/src/position.h @@ -806,7 +806,7 @@ inline WallingRule Position::walling_rule() const { inline bool Position::commit_gates() const { assert(var != nullptr); - return var->seirawanGating; + return var->commitGates; } inline bool Position::seirawan_gating() const { diff --git a/src/variant.cpp b/src/variant.cpp index 008f9ec58..1858abcc6 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1881,7 +1881,6 @@ void VariantMap::init() { add("placement", placement_variant()); add("sittuyin", sittuyin_variant()); add("seirawan", seirawan_variant()); - add("musketeer", musketeer_variant()); add("shouse", shouse_variant()); add("dragon", dragon_variant()); add("paradigm", paradigm_variant()); @@ -1911,6 +1910,7 @@ void VariantMap::init() { add("minixiangqi", minixiangqi_variant()); add("raazuvaa", raazuvaa_variant()); #ifdef LARGEBOARDS + add("musketeer", musketeer_variant()); add("shogi", shogi_variant()); add("shoshogi", shoshogi_variant()); add("yarishogi", yarishogi_variant()); diff --git a/src/variant.h b/src/variant.h index ec1991859..a0e1b9cb9 100644 --- a/src/variant.h +++ b/src/variant.h @@ -109,6 +109,7 @@ struct Variant { WallingRule wallingRule = NO_WALLING; Bitboard wallingRegion[COLOR_NB] = {AllSquares, AllSquares}; bool seirawanGating = false; + bool commitGates = false; bool cambodianMoves = false; Bitboard diagonalLines = 0; bool pass[COLOR_NB] = {false, false}; diff --git a/src/variants.ini b/src/variants.ini index abc2c7099..23fd69857 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -233,6 +233,7 @@ # wallingRegionWhite: mask where wall squares (including duck) can be placed by white [Bitboard] (default: all squares) # wallingRegionBlack: mask where wall squares (including duck) can be placed by black [Bitboard] (default: all squares) # seirawanGating: allow gating of pieces in hand like in S-Chess, requires "gating = true" [bool] (default: false) +# commitGates: gating pieces are committed to gating squares like in Musketeer chess [bool] (default: false) # cambodianMoves: enable special moves of cambodian chess, requires "gating = true" [bool] (default: false) # diagonalLines: enable special moves along diagonal for specific squares (Janggi) [Bitboard] # pass: allow passing [bool] (default: false) From 06a794f398bb5aea46ae21fd01cf5509357ef169 Mon Sep 17 00:00:00 2001 From: alperatalayn Date: Tue, 5 Mar 2024 14:12:57 +0300 Subject: [PATCH 03/12] cleaned up debug logs and comments --- src/position.cpp | 5 +---- src/position.h | 1 - src/variant.cpp | 2 -- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 8761a29c4..ec70dcc23 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -332,9 +332,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq, true, Piece(idx)); ++sq; if(v->commitGates && (rank == 0 || rank == max_rank() + 2)){ - //std::cout << "C\n"; commit_piece(Piece(idx), File(commitFile)); - //std::cout << "D\n"; ++commitFile; } else { @@ -768,7 +766,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string return ss.str(); } - // pieces in hand TODO: Check if this is correct + // pieces in hand if (!variant()->freeDrops && (piece_drops() || seirawan_gating()) && !commit_gates()) { ss << '['; @@ -815,7 +813,6 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string if (can_castle(BLACK_OOO)) ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OOO))) : 'q'); - // TODO: Check line 799, apply same to here if needed if (gating() && gates(BLACK) && (!seirawan_gating() || count_in_hand(BLACK, ALL_PIECES) > 0 || captures_to_hand())) for (File f = FILE_A; f <= max_file(); ++f) if ( (gates(BLACK) & file_bb(f)) diff --git a/src/position.h b/src/position.h index 4c2d2db47..4827186af 100644 --- a/src/position.h +++ b/src/position.h @@ -1566,7 +1566,6 @@ inline void Position::commit_piece(Piece pc, File fl){ } inline void Position::uncommit_piece(Color cl, File fl){ - //std::cout << "uncommit_piece\n"; committedGates[cl][fl] = NO_PIECE_TYPE; } diff --git a/src/variant.cpp b/src/variant.cpp index 1858abcc6..44ba9b66c 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1231,8 +1231,6 @@ namespace { //"********/rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/******** w KQkq - 0 1" v->startFen = "********/rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/******** w KQkq - 0 1"; - - // TODO: Confirm the following v->gating = true; v->commitGates = true; v->promotionPieceTypes[BLACK] = piece_set(CUSTOM_PIECE_1) | CUSTOM_PIECE_7 | QUEEN | ROOK | BISHOP | KNIGHT; From 9d1d1a44804de0ccd63bd57dd8a9575ca770b846 Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Thu, 28 Mar 2024 20:44:46 +0000 Subject: [PATCH 04/12] typos fixed --- src/position.cpp | 1 + src/variant.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/position.cpp b/src/position.cpp index 9b03a29a7..bd381632d 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -823,6 +823,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string ss << char('a' + f); if (!can_castle(ANY_CASTLING) && !(gating() && !commit_gates() && (gates(WHITE) | gates(BLACK)))) + ss << '-'; // Counting limit or ep-square if (st->countingLimit) diff --git a/src/variant.cpp b/src/variant.cpp index 8c18582b8..9a249d227 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1226,7 +1226,7 @@ namespace { v->add_piece(CUSTOM_PIECE_1, 'l', "F2N"); // Leopard v->add_piece(CUSTOM_PIECE_2, 'h', "ADGH"); // Hawk v->add_piece(CUSTOM_PIECE_3, 'u', "NC"); // Unicorn - V->add_piece(CUSTOM_PIECE_4, 's', "B2ND"); // Spider + v->add_piece(CUSTOM_PIECE_4, 's', "B2ND"); // Spider v->add_piece(CUSTOM_PIECE_5, 'f', "B3vND"); // Fortress v->add_piece(CUSTOM_PIECE_6, 'e', "FWDA"); // Musketeer Elephant v->add_piece(CUSTOM_PIECE_7, 'o', "FWDsN"); // Musketeer Cannon From bbb0bf1059606bc5beefa256a1128d7caa4d456d Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Fri, 29 Mar 2024 10:00:08 +0000 Subject: [PATCH 05/12] uninitialized removedGatingType fix --- src/position.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index bd381632d..435105075 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1978,12 +1978,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->materialKey ^= Zobrist::psq[gating_piece][pieceCount[gating_piece]]; st->nonPawnMaterial[us] += PieceValue[MG][gating_piece]; } - if(st->removedGatingType > NO_PIECE_TYPE){ - commit_piece(piece_on(from), file_of(from)); - } // Musketeer gating if(commit_gates()){ + + if(st->removedGatingType > NO_PIECE_TYPE){ + commit_piece(piece_on(from), file_of(from)); + } Rank r = rank_of(from); if(r == RANK_1 && has_committed_piece(WHITE, file_of(from))){ st->removedGatingType = drop_committed_piece(WHITE, file_of(from)); @@ -2216,7 +2217,7 @@ void Position::undo_move(Move m) { st->gatesBB[us] |= gating_square(m); } - if(st->removedGatingType > NO_PIECE_TYPE){ + if(commit_gates() && st->removedGatingType > NO_PIECE_TYPE){ commit_piece(piece_on(from), file_of(from)); } From 0ba2501df6436e1eb009b6155c6feb0e88a5bf54 Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Fri, 29 Mar 2024 12:18:44 +0000 Subject: [PATCH 06/12] Position regression bugfixes --- src/position.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 435105075..4698582bc 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -286,14 +286,20 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, } else if (token == '/') - { - if(!commit_gates() || (rank != 0 && rank <= max_rank())) sq += 2 * SOUTH + (FILE_MAX - max_file()) * EAST; - ++rank; - commitFile = 0; + { + if(commit_gates()) { + if(rank != 0 && rank <= max_rank()) { + sq += 2 * SOUTH + (FILE_MAX - max_file()) * EAST; + } + ++rank; + commitFile = 0; + } else { + sq = SQ_A1 + --r * NORTH; + } if (!is_ok(sq)) break; } - else if(token == '*') ++commitFile; + // Stop before pieces in hand else if (token == '[') break; @@ -302,12 +308,17 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, else if (!is_ok(sq) || file_of(sq) > max_file() || rank_of(sq) > r) continue; - // Wall square else if (token == '*') { - st->wallSquares |= sq; - byTypeBB[ALL_PIECES] |= sq; - ++sq; + if(commit_gates()) { + // musketeer + ++commitFile; + } else { + // Wall square + st->wallSquares |= sq; + byTypeBB[ALL_PIECES] |= sq; + ++sq; + } } else if ((idx = piece_to_char().find(token)) != string::npos || (idx = piece_to_char_synonyms().find(token)) != string::npos) @@ -329,8 +340,6 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, else if (token == '+' && (idx = piece_to_char().find(ss.peek())) != string::npos && promoted_piece_type(type_of(Piece(idx)))) { ss >> token; - put_piece(make_piece(color_of(Piece(idx)), promoted_piece_type(type_of(Piece(idx)))), sq, true, Piece(idx)); - ++sq; if(v->commitGates && (rank == 0 || rank == max_rank() + 2)){ commit_piece(Piece(idx), File(commitFile)); ++commitFile; From fa7b1da420800f0c6c48c02d7c76cdc0669b280e Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Fri, 29 Mar 2024 12:55:00 +0000 Subject: [PATCH 07/12] musketeer board geometry override --- src/variant.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/variant.cpp b/src/variant.cpp index 9a249d227..7a95349b8 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1220,6 +1220,8 @@ namespace { Variant* v = chess_variant(); v->variantTemplate = "seirawan"; v->pieceToCharTable = "PNBRQ.C..........LO..Kpnbrq.c..........lo..k"; // The default piece combo in Musketeer Chess is Leopard L and Musketeer Cannon O + v->maxRank = RANK_10; + v->castlingRank = RANK_2; v->add_piece(ARCHBISHOP, 'a'); v->add_piece(CHANCELLOR, 'c'); v->add_piece(AMAZON, 'd'); // also called Dragon in Musketeer, but Amazon is the most accurate From 27f2c23b9b888df351c6449d7139b22eb86e83cf Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Fri, 29 Mar 2024 16:37:50 +0000 Subject: [PATCH 08/12] more musketeer board geometry fixes --- src/apiutil.h | 28 +++++++++++++++++++++------- src/position.cpp | 2 +- src/variant.cpp | 2 -- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/apiutil.h b/src/apiutil.h index d39102fcd..ade738197 100644 --- a/src/apiutil.h +++ b/src/apiutil.h @@ -564,8 +564,13 @@ inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, { if (c == ' ' || c == '[') break; - if (c == '*') - ++fileIdx; + if (c == '*') { + if (v->commitGates) { + // just ignore? + } else { + ++fileIdx; + } + } else if (isdigit(c)) { fileIdx += c - '0'; @@ -575,14 +580,23 @@ inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, } else if (c == '/') { - ++rankIdx; - if (fileIdx != board.get_nb_files()) - { - std::cerr << "curRankWidth != nbFiles: " << fileIdx << " != " << board.get_nb_files() << std::endl; - return NOK; + if (v->commitGates && rankIdx == 0 && fileIdx == 0) { + // ignore starting '********/' + } else { + ++rankIdx; + if (fileIdx != board.get_nb_files()) + { + std::cerr << "curRankWidth != nbFiles: " << fileIdx << " != " << board.get_nb_files() << std::endl; + return NOK; + } } if (rankIdx == board.get_nb_ranks()) + { + if (v->commitGates) { + rankIdx--; // pretend we didn't see the ending '/********' + } break; + } fileIdx = 0; } else if (!contains(validSpecialCharactersFirstField, c)) diff --git a/src/position.cpp b/src/position.cpp index 4698582bc..a8e361706 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -711,7 +711,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string int emptyCnt; std::ostringstream ss; if(commit_gates()){ - for(File f = FILE_A; f < max_file(); ++f){ + for(File f = FILE_A; f <= max_file(); ++f){ if(has_committed_piece(BLACK, f)) ss << piece_to_char()[make_piece(BLACK, committedGates[BLACK][f])]; else ss << "*"; } diff --git a/src/variant.cpp b/src/variant.cpp index 7a95349b8..9a249d227 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -1220,8 +1220,6 @@ namespace { Variant* v = chess_variant(); v->variantTemplate = "seirawan"; v->pieceToCharTable = "PNBRQ.C..........LO..Kpnbrq.c..........lo..k"; // The default piece combo in Musketeer Chess is Leopard L and Musketeer Cannon O - v->maxRank = RANK_10; - v->castlingRank = RANK_2; v->add_piece(ARCHBISHOP, 'a'); v->add_piece(CHANCELLOR, 'c'); v->add_piece(AMAZON, 'd'); // also called Dragon in Musketeer, but Amazon is the most accurate From 6e98eec74df40bc772aadf775e7134fbd7c2b47a Mon Sep 17 00:00:00 2001 From: cross_of_north Date: Fri, 29 Mar 2024 17:23:02 +0000 Subject: [PATCH 09/12] formatting --- src/apiutil.h | 15 +++++++++----- src/position.cpp | 51 ++++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/apiutil.h b/src/apiutil.h index ade738197..1b3580b28 100644 --- a/src/apiutil.h +++ b/src/apiutil.h @@ -565,9 +565,11 @@ inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, if (c == ' ' || c == '[') break; if (c == '*') { - if (v->commitGates) { + if (v->commitGates) + { // just ignore? - } else { + } + else { ++fileIdx; } } @@ -580,9 +582,11 @@ inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, } else if (c == '/') { - if (v->commitGates && rankIdx == 0 && fileIdx == 0) { + if (v->commitGates && rankIdx == 0 && fileIdx == 0) + { // ignore starting '********/' - } else { + } + else { ++rankIdx; if (fileIdx != board.get_nb_files()) { @@ -592,7 +596,8 @@ inline Validation fill_char_board(CharBoard& board, const std::string& fenBoard, } if (rankIdx == board.get_nb_ranks()) { - if (v->commitGates) { + if (v->commitGates) + { rankIdx--; // pretend we didn't see the ending '/********' } break; diff --git a/src/position.cpp b/src/position.cpp index a8e361706..c46d32059 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -272,8 +272,8 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, // 1. Piece placement while ((ss >> token) && !isspace(token)) - { - if (isdigit(token) && (!commit_gates() || (rank != 0 && rank != max_rank() + 2))) + { + if (isdigit(token) && (!commit_gates() || (rank != 0 && rank != max_rank() + 2))) { #ifdef LARGEBOARDS if (isdigit(ss.peek())) @@ -287,14 +287,16 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, else if (token == '/') { - if(commit_gates()) { - if(rank != 0 && rank <= max_rank()) { - sq += 2 * SOUTH + (FILE_MAX - max_file()) * EAST; - } - ++rank; - commitFile = 0; - } else { - sq = SQ_A1 + --r * NORTH; + if(commit_gates()) + { + if(rank != 0 && rank <= max_rank()){ + sq += 2 * SOUTH + (FILE_MAX - max_file()) * EAST; + } + ++rank; + commitFile = 0; + } + else { + sq = SQ_A1 + --r * NORTH; } if (!is_ok(sq)) break; @@ -310,14 +312,16 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, else if (token == '*') { - if(commit_gates()) { - // musketeer - ++commitFile; - } else { - // Wall square - st->wallSquares |= sq; - byTypeBB[ALL_PIECES] |= sq; - ++sq; + if(commit_gates()) + { + // musketeer + ++commitFile; + } + else { + // Wall square + st->wallSquares |= sq; + byTypeBB[ALL_PIECES] |= sq; + ++sq; } } @@ -326,13 +330,14 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, if (ss.peek() == '~') ss >> token; - if(v->commitGates && (rank == 0 || rank == max_rank() + 2)){ - commit_piece(Piece(idx), File(commitFile)); - ++commitFile; + if(v->commitGates && (rank == 0 || rank == max_rank() + 2)) + { + commit_piece(Piece(idx), File(commitFile)); + ++commitFile; } else{ - put_piece(Piece(idx), sq, token == '~'); - ++sq; + put_piece(Piece(idx), sq, token == '~'); + ++sq; } } From baac2dc3595757b1ee2061fc78e5cda598e99334 Mon Sep 17 00:00:00 2001 From: cross-of-north Date: Sat, 30 Mar 2024 01:20:51 +0700 Subject: [PATCH 10/12] actions for test --- .github/workflows/fairy.yml | 1 + .github/workflows/ffishjs.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/stockfish.yml | 1 + .github/workflows/wheels.yml | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fairy.yml b/.github/workflows/fairy.yml index 6dd8ae70a..715ad1b69 100644 --- a/.github/workflows/fairy.yml +++ b/.github/workflows/fairy.yml @@ -3,6 +3,7 @@ on: push: branches: - master + - test3 pull_request: branches: - master diff --git a/.github/workflows/ffishjs.yml b/.github/workflows/ffishjs.yml index 612e0274f..27e07859a 100644 --- a/.github/workflows/ffishjs.yml +++ b/.github/workflows/ffishjs.yml @@ -2,7 +2,7 @@ name: ffishjs on: push: - branches: [ master ] + branches: [ master, test3 ] pull_request: branches: [ master ] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 889814ff5..52f011022 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Release on: push: - branches: [ master ] + branches: [ master, test3 ] pull_request: branches: [ master ] diff --git a/.github/workflows/stockfish.yml b/.github/workflows/stockfish.yml index 3a40bf7d0..96484f461 100644 --- a/.github/workflows/stockfish.yml +++ b/.github/workflows/stockfish.yml @@ -3,6 +3,7 @@ on: push: branches: - master + - test3 - tools - github_ci pull_request: diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index ed14ee97a..967e1398c 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -4,6 +4,7 @@ on: push: branches: - master + - test3 pull_request: branches: - master From 529ac13ba5ebe9b568e767d5a3dca43d6bc09598 Mon Sep 17 00:00:00 2001 From: cross-of-north Date: Sat, 30 Mar 2024 01:32:19 +0700 Subject: [PATCH 11/12] actions for test --- .github/workflows/fairy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/fairy.yml b/.github/workflows/fairy.yml index 715ad1b69..0f2c9ec25 100644 --- a/.github/workflows/fairy.yml +++ b/.github/workflows/fairy.yml @@ -1,5 +1,6 @@ name: fairy on: + workflow_dispatch push: branches: - master From f0cd87b244250c3c66b7a513ebdb130880cbbea7 Mon Sep 17 00:00:00 2001 From: cross-of-north Date: Sat, 30 Mar 2024 01:35:25 +0700 Subject: [PATCH 12/12] Revert "actions for test" This reverts commit 529ac13ba5ebe9b568e767d5a3dca43d6bc09598. Revert "actions for test" This reverts commit baac2dc3595757b1ee2061fc78e5cda598e99334. --- .github/workflows/fairy.yml | 2 -- .github/workflows/ffishjs.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/stockfish.yml | 1 - .github/workflows/wheels.yml | 1 - 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/fairy.yml b/.github/workflows/fairy.yml index 0f2c9ec25..6dd8ae70a 100644 --- a/.github/workflows/fairy.yml +++ b/.github/workflows/fairy.yml @@ -1,10 +1,8 @@ name: fairy on: - workflow_dispatch push: branches: - master - - test3 pull_request: branches: - master diff --git a/.github/workflows/ffishjs.yml b/.github/workflows/ffishjs.yml index 27e07859a..612e0274f 100644 --- a/.github/workflows/ffishjs.yml +++ b/.github/workflows/ffishjs.yml @@ -2,7 +2,7 @@ name: ffishjs on: push: - branches: [ master, test3 ] + branches: [ master ] pull_request: branches: [ master ] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52f011022..889814ff5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Release on: push: - branches: [ master, test3 ] + branches: [ master ] pull_request: branches: [ master ] diff --git a/.github/workflows/stockfish.yml b/.github/workflows/stockfish.yml index 96484f461..3a40bf7d0 100644 --- a/.github/workflows/stockfish.yml +++ b/.github/workflows/stockfish.yml @@ -3,7 +3,6 @@ on: push: branches: - master - - test3 - tools - github_ci pull_request: diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 967e1398c..ed14ee97a 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -4,7 +4,6 @@ on: push: branches: - master - - test3 pull_request: branches: - master