From 9aff7001a0b9bda95404ed559046be8771d0db7c Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Sat, 11 Jan 2020 00:18:20 +0100 Subject: [PATCH] Fix handling of pawns in promotion zone - Support shogi-style piece promotion for pawns - Make pawn drops in promotion zone configurable via `promotionZonePawnDrops` - Fix parsing of promotionPieceTypes option --- src/movegen.cpp | 5 +++++ src/parser.cpp | 2 ++ src/position.cpp | 13 +++++++++---- src/position.h | 3 ++- src/variant.h | 1 + src/variants.ini | 20 ++++++++++++++++++++ 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index a12c0c0..eb20377 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -47,9 +47,14 @@ namespace { ExtMove* make_promotions(const Position& pos, ExtMove* moveList, Square to) { if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS) + { for (PieceType pt : pos.promotion_piece_types()) if (!pos.promotion_limit(pt) || pos.promotion_limit(pt) > pos.count(c, pt)) *moveList++ = make(to - D, to, pt); + PieceType pt = pos.promoted_piece_type(PAWN); + if (pt && !(pos.piece_promotion_on_capture() && pos.empty(to))) + *moveList++ = make(to - D, to); + } return moveList; } diff --git a/src/parser.cpp b/src/parser.cpp index 8ed6074..ad14701 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -131,6 +131,7 @@ Variant* VariantParser::parse(Variant* v) { const auto& it_prom = config.find("promotionPieceTypes"); if (it_prom != config.end()) { + v->promotionPieceTypes = {}; char token; size_t idx; std::stringstream ss(it_prom->second); @@ -180,6 +181,7 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("dropLoop", v->dropLoop); parse_attribute("capturesToHand", v->capturesToHand); parse_attribute("firstRankPawnDrops", v->firstRankPawnDrops); + parse_attribute("promotionZonePawnDrops", v->promotionZonePawnDrops); parse_attribute("dropOnTop", v->dropOnTop); parse_attribute("whiteDropRegion", v->whiteDropRegion); parse_attribute("blackDropRegion", v->blackDropRegion); diff --git a/src/position.cpp b/src/position.cpp index 8b9aaea..63e37df 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1300,17 +1300,22 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { k ^= Zobrist::enpassant[file_of(st->epSquare)]; } - else if (type_of(m) == PROMOTION) + else if (type_of(m) == PROMOTION || type_of(m) == PIECE_PROMOTION) { - Piece promotion = make_piece(us, promotion_type(m)); + Piece promotion = make_piece(us, type_of(m) == PROMOTION ? promotion_type(m) : promoted_piece_type(PAWN)); assert(relative_rank(us, to, max_rank()) >= promotion_rank() || sittuyin_promotion()); assert(type_of(promotion) >= KNIGHT && type_of(promotion) < KING); remove_piece(pc, to); put_piece(promotion, to); - if (captures_to_hand() && !drop_loop()) - promotedPieces = promotedPieces | to; + if (type_of(m) == PIECE_PROMOTION) + { + promotedPieces |= to; + unpromotedBoard[to] = pc; + } + else if (captures_to_hand() && !drop_loop()) + promotedPieces |= to; // Update hash keys k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to]; diff --git a/src/position.h b/src/position.h index 67c2586..bec0dc0 100644 --- a/src/position.h +++ b/src/position.h @@ -508,7 +508,8 @@ inline Bitboard Position::drop_region(Color c, PieceType pt) const { // Pawns on back ranks if (pt == PAWN) { - b &= ~promotion_zone_bb(c, promotion_rank(), max_rank()); + if (!var->promotionZonePawnDrops) + b &= ~promotion_zone_bb(c, promotion_rank(), max_rank()); if (!first_rank_pawn_drops()) b &= ~rank_bb(relative_rank(c, RANK_1, max_rank())); } diff --git a/src/variant.h b/src/variant.h index 5e599d9..fc5d370 100644 --- a/src/variant.h +++ b/src/variant.h @@ -73,6 +73,7 @@ struct Variant { bool dropLoop = false; bool capturesToHand = false; bool firstRankPawnDrops = false; + bool promotionZonePawnDrops = false; bool dropOnTop = false; Bitboard whiteDropRegion = AllSquares; Bitboard blackDropRegion = AllSquares; diff --git a/src/variants.ini b/src/variants.ini index c2cd752..86e846e 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -128,6 +128,7 @@ # dropLoop: captures promoted pieces are not demoted [bool] (default: false) # capturesToHand: captured pieces are go to opponent's hand [bool] (default: false) # firstRankPawnDrops: allow pawn drops to first rank [bool] (default: false) +# promotionZonePawnDrops: allow pawn drops in promotion zone [bool] (default: false) # dropOnTop: piece drops need to be on top of pieces on board (e.g., for connect4) [bool] (default: false) # whiteDropRegion: restrict region for piece drops of all white pieces [Bitboard] # blackDropRegion: restrict region for piece drops of all black pieces [Bitboard] @@ -287,3 +288,22 @@ stalemateValue = draw immobilityIllegal = false connectN = 4 nMoveRule = 0 + +[shogun:crazyhouse] +variantTemplate = shogi +pieceToCharTable = PNBR.D.....++++.+Kpnbr.d.....++++.+k +pocketSize = 8 +startFen = rnb+dkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNB+DKBNR w KQkq - 0 1 +commoner = c +centaur = g +archbishop = a +chancellor = m +fers = d +promotionRank = 6 +promotionLimit = c:1 g:1 a:1 m:1 q:1 +promotionPieceTypes = - +promotedPieceType = p:c n:g b:a r:m d:q +mandatoryPawnPromotion = false +firstRankPawnDrops = true +promotionZonePawnDrops = true +immobilityIllegal = true -- 1.7.0.4