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;
}
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);
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);
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];
// 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()));
}
bool dropLoop = false;
bool capturesToHand = false;
bool firstRankPawnDrops = false;
+ bool promotionZonePawnDrops = false;
bool dropOnTop = false;
Bitboard whiteDropRegion = AllSquares;
Bitboard blackDropRegion = AllSquares;
# 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]
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