From ca61be3e25ff35aea56d57499f1ac61fc7a4067c Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Sat, 20 Dec 2025 12:07:13 +0100 Subject: [PATCH] Define piece types with ambiguous demotion multiple times The predefined variants now define pieces that demote differently (or not at all) multiple times, as custom pieces. To make this possible add_piece() was changed to allow pieces with the same ID if the synonym is '+'. a new arrays demotedPieceType[PieceType] and a PieceSet isDemotedType are set to record this, for later use. --- src/variant.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++----------- src/variant.h | 3 ++ 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/variant.cpp b/src/variant.cpp index ad97b97..996b153 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -793,6 +793,8 @@ namespace { v->add_piece(ROOK, 'r'); v->add_piece(DRAGON, 'd'); v->add_piece(KING, 'k'); + v->add_piece(CUSTOM_PIECE_1, 'g', "WfF", '+'); + v->add_piece(CUSTOM_PIECE_2, 'g', "WfF", '+'); v->startFen = "rbsgk/4p/5/P4/KGSBR[-] w 0 1"; v->pieceDrops = true; v->capturesToHand = true; @@ -800,10 +802,15 @@ namespace { v->promotionRegion[BLACK] = Rank1BB; v->doubleStep = false; v->castling = false; - v->promotedPieceType[SHOGI_PAWN] = GOLD; - v->promotedPieceType[SILVER] = GOLD; + v->promotedPieceType[SHOGI_PAWN] = CUSTOM_PIECE_1; + v->promotedPieceType[SILVER] = CUSTOM_PIECE_2; v->promotedPieceType[BISHOP] = DRAGON_HORSE; v->promotedPieceType[ROOK] = DRAGON; + v->demotedPieceType[CUSTOM_PIECE_1] = SHOGI_PAWN; + v->demotedPieceType[CUSTOM_PIECE_2] = SILVER; + v->demotedPieceType[DRAGON_HORSE] = BISHOP; + v->demotedPieceType[DRAGON] = ROOK; + v->isPromotedType = piece_set(DRAGON) | DRAGON_HORSE | CUSTOM_PIECE_1 | CUSTOM_PIECE_2; v->dropNoDoubled = SHOGI_PAWN; v->immobilityIllegal = true; v->shogiPawnDropMateIllegal = true; @@ -838,13 +845,19 @@ namespace { v->mandatoryPiecePromotion = true; v->pieceDemotion = true; v->dropPromoted = true; - v->promotedPieceType[LANCE] = GOLD; + v->promotedPieceType[LANCE] = CUSTOM_PIECE_1; v->promotedPieceType[SILVER] = BISHOP; v->promotedPieceType[SHOGI_KNIGHT] = GOLD; v->promotedPieceType[SHOGI_PAWN] = ROOK; v->promotedPieceType[GOLD] = NO_PIECE_TYPE; v->promotedPieceType[BISHOP] = NO_PIECE_TYPE; v->promotedPieceType[ROOK] = NO_PIECE_TYPE; + v->promotedPieceType[CUSTOM_PIECE_1] = NO_PIECE_TYPE; + v->demotedPieceType[GOLD] = SHOGI_KNIGHT; + v->demotedPieceType[BISHOP] = SILVER; + v->demotedPieceType[ROOK] = SHOGI_PAWN; + v->demotedPieceType[CUSTOM_PIECE_1] = LANCE; + v->isPromotedType |= piece_set(ROOK) | BISHOP | GOLD; v->immobilityIllegal = false; v->shogiPawnDropMateIllegal = false; v->dropNoDoubled = NO_PIECE_TYPE; @@ -861,12 +874,18 @@ namespace { v->promotionRegion[BLACK] = AllSquares; v->piecePromotionOnCapture = true; v->promotedPieceType[LANCE] = SILVER; - v->promotedPieceType[BISHOP] = GOLD; + v->promotedPieceType[BISHOP] = CUSTOM_PIECE_1; v->promotedPieceType[ROOK] = GOLD; v->promotedPieceType[SHOGI_PAWN] = SHOGI_KNIGHT; v->promotedPieceType[SILVER] = NO_PIECE_TYPE; v->promotedPieceType[GOLD] = NO_PIECE_TYPE; v->promotedPieceType[SHOGI_KNIGHT] = NO_PIECE_TYPE; + v->promotedPieceType[CUSTOM_PIECE_1] = NO_PIECE_TYPE; + v->demotedPieceType[CUSTOM_PIECE_1] = BISHOP; + v->demotedPieceType[SILVER] = LANCE; + v->demotedPieceType[GOLD] = ROOK; + v->demotedPieceType[SHOGI_KNIGHT] = SHOGI_PAWN; + v->isPromotedType = piece_set(SILVER) | GOLD | SHOGI_KNIGHT | CUSTOM_PIECE_1; return v; } // Dobutsu @@ -919,10 +938,13 @@ namespace { v->maxRank = RANK_6; v->maxFile = FILE_F; v->add_piece(SHOGI_KNIGHT, 'n'); + v->add_piece(CUSTOM_PIECE_3, 'n', "WfF", '+'); v->startFen = "rbnsgk/5p/6/6/P5/KGSNBR[-] w 0 1"; v->promotionRegion[WHITE] = Rank5BB | Rank6BB; v->promotionRegion[BLACK] = Rank2BB | Rank1BB; - v->promotedPieceType[SHOGI_KNIGHT] = GOLD; + v->promotedPieceType[SHOGI_KNIGHT] = CUSTOM_PIECE_3; + v->demotedPieceType[CUSTOM_PIECE_3] = SHOGI_KNIGHT; + v->isPromotedType |= CUSTOM_PIECE_3; return v; } // Tori shogi @@ -952,6 +974,9 @@ namespace { v->castling = false; v->promotedPieceType[SHOGI_PAWN] = CUSTOM_PIECE_6; // swallow promotes to goose v->promotedPieceType[CUSTOM_PIECE_1] = CUSTOM_PIECE_7; // falcon promotes to eagle + v->demotedPieceType[CUSTOM_PIECE_6] = SHOGI_PAWN; + v->demotedPieceType[CUSTOM_PIECE_7] = CUSTOM_PIECE_1; + v->isPromotedType = piece_set(CUSTOM_PIECE_6) | CUSTOM_PIECE_7; v->mandatoryPiecePromotion = true; v->dropNoDoubled = SHOGI_PAWN; v->dropNoDoubledCount = 2; @@ -971,11 +996,14 @@ namespace { v->pieceToCharTable = "PNBR.....G.++++Kpnbr.....g.++++k"; v->maxRank = RANK_8; v->maxFile = FILE_H; - v->add_piece(CUSTOM_PIECE_1, 'n', "fNsW"); + v->add_piece(CUSTOM_PIECE_3, 'n', "fNsW"); + v->add_piece(CUSTOM_PIECE_4, 'n', "WfF", '+'); v->startFen = "1nbgkgn1/1r4b1/pppppppp/8/8/PPPPPPPP/1B4R1/1NGKGBN1[-] w 0 1"; v->promotionRegion[WHITE] = Rank6BB | Rank7BB | Rank8BB; v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB; - v->promotedPieceType[CUSTOM_PIECE_1] = GOLD; + v->promotedPieceType[CUSTOM_PIECE_3] = CUSTOM_PIECE_4; + v->demotedPieceType[CUSTOM_PIECE_4] = CUSTOM_PIECE_3; + v->isPromotedType |= CUSTOM_PIECE_4; v->mandatoryPiecePromotion = true; return v; } @@ -1237,11 +1265,16 @@ namespace { v->maxFile = FILE_I; v->add_piece(LANCE, 'l'); v->add_piece(SHOGI_KNIGHT, 'n'); + v->add_piece(CUSTOM_PIECE_3, 'l', "WfF", '+'); + v->add_piece(CUSTOM_PIECE_4, 'n', "WfF", '+'); v->startFen = "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL[-] w 0 1"; v->promotionRegion[WHITE] = Rank7BB | Rank8BB | Rank9BB; v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB; - v->promotedPieceType[LANCE] = GOLD; - v->promotedPieceType[SHOGI_KNIGHT] = GOLD; + v->promotedPieceType[LANCE] = CUSTOM_PIECE_3; + v->promotedPieceType[SHOGI_KNIGHT] = CUSTOM_PIECE_4; + v->demotedPieceType[CUSTOM_PIECE_3] = LANCE; + v->demotedPieceType[CUSTOM_PIECE_4] = SHOGI_KNIGHT; + v->isPromotedType |= piece_set(CUSTOM_PIECE_4) | CUSTOM_PIECE_3; return v; } // Check-Shogi @@ -1259,11 +1292,13 @@ namespace { v->pieceToCharTable = "PNBRLSE..G.+.++.++Kpnbrlse..g.+.++.++k"; v->remove_piece(KING); v->add_piece(COMMONER, 'k'); - v->add_piece(CUSTOM_PIECE_1, 'e', "FsfW"); // drunk elephant + v->add_piece(CUSTOM_PIECE_5, 'e', "FsfW"); // drunk elephant v->startFen = "lnsgkgsnl/1r2e2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2E2R1/LNSGKGSNL w 0 1"; v->capturesToHand = false; v->pieceDrops = false; - v->promotedPieceType[CUSTOM_PIECE_1] = COMMONER; + v->promotedPieceType[CUSTOM_PIECE_5] = COMMONER; + v->demotedPieceType[COMMONER] = CUSTOM_PIECE_5; + v->isPromotedType |= CUSTOM_PIECE_5; v->castlingKingPiece[WHITE] = v->castlingKingPiece[BLACK] = COMMONER; v->extinctionValue = -VALUE_MATE; v->extinctionPieceTypes = piece_set(COMMONER); @@ -1286,15 +1321,21 @@ namespace { v->add_piece(CUSTOM_PIECE_1, 'n', "fRffN"); // Yari knight v->add_piece(CUSTOM_PIECE_2, 'b', "fFfR"); // Yari bishop v->add_piece(CUSTOM_PIECE_3, 'r', "frlR"); // Yari rook - v->add_piece(CUSTOM_PIECE_4, 'g', "WfFbR"); // Yari gold + v->add_piece(CUSTOM_PIECE_4, 'g', "WfFbR"); // Yari gold +N v->add_piece(CUSTOM_PIECE_5, 's', "fKbR"); // Yari silver + v->add_piece(CUSTOM_PIECE_6, 'g', "WfFbR"); // Yari gold +B v->startFen = "rnnkbbr/7/ppppppp/7/7/7/PPPPPPP/7/RBBKNNR[-] w 0 1"; v->promotionRegion[WHITE] = Rank7BB | Rank8BB | Rank9BB; v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB; v->promotedPieceType[SHOGI_PAWN] = CUSTOM_PIECE_5; v->promotedPieceType[CUSTOM_PIECE_1] = CUSTOM_PIECE_4; - v->promotedPieceType[CUSTOM_PIECE_2] = CUSTOM_PIECE_4; + v->promotedPieceType[CUSTOM_PIECE_2] = CUSTOM_PIECE_6; v->promotedPieceType[CUSTOM_PIECE_3] = ROOK; + v->demotedPieceType[CUSTOM_PIECE_5] = SHOGI_PAWN; + v->demotedPieceType[CUSTOM_PIECE_4] = CUSTOM_PIECE_1; + v->demotedPieceType[CUSTOM_PIECE_6] = CUSTOM_PIECE_2; + v->demotedPieceType[ROOK] = CUSTOM_PIECE_3; + v->isPromotedType = piece_set(ROOK) | CUSTOM_PIECE_4 | CUSTOM_PIECE_5 | CUSTOM_PIECE_6; v->pieceDrops = true; v->capturesToHand = true; v->doubleStep = false; @@ -1314,14 +1355,19 @@ namespace { Variant* v = minishogi_variant_base()->init(); v->maxRank = RANK_10; v->maxFile = FILE_J; - v->add_piece(CUSTOM_PIECE_1, 'l', "vR"); // Vertical slider + v->add_piece(CUSTOM_PIECE_3, 'l', "vR"); // Vertical slider v->add_piece(KNIGHT, 'n'); v->add_piece(QUEEN, 'q'); + v->add_piece(CUSTOM_PIECE_4, 'l', "WfF", '+'); + v->add_piece(CUSTOM_PIECE_5, 'n', "WfF", '+'); v->startFen = "lnsgkqgsnl/1r6b1/pppppppppp/10/10/10/10/PPPPPPPPPP/1B6R1/LNSGQKGSNL[-] w 0 1"; v->promotionRegion[WHITE] = Rank8BB | Rank9BB | Rank10BB; v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB; - v->promotedPieceType[CUSTOM_PIECE_1] = GOLD; - v->promotedPieceType[KNIGHT] = GOLD; + v->promotedPieceType[CUSTOM_PIECE_3] = CUSTOM_PIECE_4; + v->promotedPieceType[KNIGHT] = CUSTOM_PIECE_5; + v->demotedPieceType[CUSTOM_PIECE_4] = CUSTOM_PIECE_3; + v->demotedPieceType[CUSTOM_PIECE_5] = KNIGHT; + v->isPromotedType |= piece_set(CUSTOM_PIECE_4) | CUSTOM_PIECE_5; return v; } // Capablanca chess @@ -1635,6 +1681,7 @@ namespace { v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP; v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP; v->promotedPieceType[PAWN] = CUSTOM_PIECE_3; + v->demotedPieceType[CUSTOM_PIECE_3] = PAWN; v->promotionRegion[WHITE] = Rank10BB; v->promotionRegion[BLACK] = Rank1BB; v->doubleStepRegion[WHITE] = Rank2BB | make_bitboard(SQ_B3, SQ_C3, SQ_F3, SQ_G3); diff --git a/src/variant.h b/src/variant.h index 0e6d44c..cffc8ba 100644 --- a/src/variant.h +++ b/src/variant.h @@ -59,6 +59,8 @@ struct Variant { bool sittuyinPromotion = false; int promotionLimit[PIECE_TYPE_NB] = {}; // 0 means unlimited PieceType promotedPieceType[PIECE_TYPE_NB] = {}; + PieceType demotedPieceType[PIECE_TYPE_NB] = {}; + PieceSet isPromotedType = NO_PIECE_SET; bool piecePromotionOnCapture = false; bool mandatoryPawnPromotion = true; bool mandatoryPiecePromotion = false; @@ -181,6 +183,7 @@ struct Variant { void add_piece(PieceType pt, char c, std::string betza = "", char c2 = ' ') { // Avoid ambiguous definition by removing existing piece with same letter size_t idx; + if(c2 == '+') c2 = ' '; else if ((idx = pieceToChar.find(toupper(c))) != std::string::npos) remove_piece(PieceType(idx)); // Now add new piece -- 1.7.0.4