From 0db865dcec2fb24cef0100d86bbfd6a8a3d6b717 Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sun, 17 Feb 2019 14:23:28 +0100 Subject: [PATCH] Support microshogi https://en.wikipedia.org/wiki/Micro_shogi No functional change for other variants. --- src/movegen.cpp | 9 ++++++++- src/position.cpp | 3 ++- src/position.h | 6 ++++++ src/variant.cpp | 16 ++++++++++++++++ src/variant.h | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 18fb9991e..751685e18 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -301,7 +301,14 @@ namespace { { Bitboard promotion_zone = promotion_zone_bb(us, pos.promotion_rank(), pos.max_rank()); if (pos.mandatory_piece_promotion()) - b1 &= promotion_zone & from ? 0 : ~promotion_zone; + b1 &= (promotion_zone & from ? 0 : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : 0); + // Exclude quiet promotions/demotions + if (pos.piece_promotion_on_capture()) + { + b2 &= pos.pieces(); + b3 &= pos.pieces(); + } + // Consider promotions/demotions into promotion zone if (!(promotion_zone & from)) { b2 &= promotion_zone; diff --git a/src/position.cpp b/src/position.cpp index 646dd2deb..6f88c07e4 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -836,7 +836,8 @@ bool Position::pseudo_legal(const Move m) const { // Handle the case where a mandatory piece promotion/demotion is not taken if ( mandatory_piece_promotion() && (is_promoted(from) ? piece_demotion() : promoted_piece_type(type_of(pc)) != NO_PIECE_TYPE) - && (promotion_zone_bb(us, promotion_rank(), max_rank()) & (SquareBB[from] | to))) + && ( (promotion_zone_bb(us, promotion_rank(), max_rank()) & (SquareBB[from] | to)) + || (piece_promotion_on_capture() && !capture(m)))) return false; // Is not a promotion, so promotion piece must be empty diff --git a/src/position.h b/src/position.h index e2b779e35..486fbb62c 100644 --- a/src/position.h +++ b/src/position.h @@ -100,6 +100,7 @@ class Position { const std::set >& promotion_piece_types() const; bool sittuyin_promotion() const; PieceType promoted_piece_type(PieceType pt) const; + bool piece_promotion_on_capture() const; bool mandatory_piece_promotion() const; bool piece_demotion() const; bool endgame_eval() const; @@ -332,6 +333,11 @@ inline PieceType Position::promoted_piece_type(PieceType pt) const { return var->promotedPieceType[pt]; } +inline bool Position::piece_promotion_on_capture() const { + assert(var != nullptr); + return var->piecePromotionOnCapture; +} + inline bool Position::mandatory_piece_promotion() const { assert(var != nullptr); return var->mandatoryPiecePromotion; diff --git a/src/variant.cpp b/src/variant.cpp index e57165a7b..56b55e38a 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -311,6 +311,21 @@ VariantMap variants; // Global object v->shogiDoubledPawn = true; return v; } + Variant* microshogi_variant() { + Variant* v = kyotoshogi_variant(); + v->maxFile = FILE_D; + v->startFen = "kb+r+l/p3/4/3P/+L+RBK[-] w 0 1"; + v->promotionRank = RANK_1; + v->piecePromotionOnCapture = true; + v->promotedPieceType[LANCE] = SILVER; + v->promotedPieceType[BISHOP] = GOLD; + 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; + return v; + } Variant* dobutsu_variant() { Variant* v = minishogi_variant_base(); v->maxRank = RANK_4; @@ -580,6 +595,7 @@ void VariantMap::init() { add("minishogi", minishogi_variant()); add("mini", minishogi_variant()); add("kyotoshogi", kyotoshogi_variant()); + add("micro", microshogi_variant()); add("dobutsu", dobutsu_variant()); add("gorogoro", gorogoroshogi_variant()); add("judkins", judkinsshogi_variant()); diff --git a/src/variant.h b/src/variant.h index e28573145..85abe9dcc 100644 --- a/src/variant.h +++ b/src/variant.h @@ -44,6 +44,7 @@ struct Variant { std::set > promotionPieceTypes = { QUEEN, ROOK, BISHOP, KNIGHT }; bool sittuyinPromotion = false; PieceType promotedPieceType[PIECE_TYPE_NB] = {}; + bool piecePromotionOnCapture = false; bool mandatoryPiecePromotion = false; bool pieceDemotion = false; bool endgameEval = false;