Fix handling of pawns in promotion zone
authorFabian Fichter <ianfab@users.noreply.github.com>
Fri, 10 Jan 2020 23:18:20 +0000 (00:18 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 12 Jan 2020 15:23:44 +0000 (16:23 +0100)
- Support shogi-style piece promotion for pawns
- Make pawn drops in promotion zone configurable via `promotionZonePawnDrops`
- Fix parsing of promotionPieceTypes option

src/movegen.cpp
src/parser.cpp
src/position.cpp
src/position.h
src/variant.h
src/variants.ini

index a12c0c0..eb20377 100644 (file)
@@ -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<PROMOTION>(to - D, to, pt);
+        PieceType pt = pos.promoted_piece_type(PAWN);
+        if (pt && !(pos.piece_promotion_on_capture() && pos.empty(to)))
+            *moveList++ = make<PIECE_PROMOTION>(to - D, to);
+    }
 
     return moveList;
   }
index 8ed6074..ad14701 100644 (file)
@@ -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);
index 8b9aaea..63e37df 100644 (file)
@@ -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];
index 67c2586..bec0dc0 100644 (file)
@@ -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()));
   }
index 5e599d9..fc5d370 100644 (file)
@@ -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;
index c2cd752..86e846e 100644 (file)
 # 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