: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
: pos.attacks_from(Us, Pt, s);
- // Janggi palace moves
- if (pos.diagonal_lines() & s)
- {
- PieceType diagType = Pt == WAZIR ? FERS : Pt == SOLDIER ? PAWN : Pt == ROOK ? BISHOP : NO_PIECE_TYPE;
- if (diagType)
- b |= attacks_bb(Us, diagType, s, pos.pieces()) & pos.board_bb(Us, Pt) & pos.diagonal_lines();
- else if (Pt == JANGGI_CANNON)
- // TODO: fix for longer diagonals
- b |= attacks_bb(Us, ALFIL, s, pos.pieces()) & ~attacks_bb(Us, ELEPHANT, s, pos.pieces() ^ pos.pieces(JANGGI_CANNON))
- & pos.board_bb(Us, Pt) & pos.diagonal_lines();
- }
-
// Restrict mobility to actual squares of board
b &= pos.board_bb();
if (Pt == SOLDIER && pos.unpromoted_soldier(Us, s))
- {
- b &= file_bb(s);
score -= make_score(PieceValue[MG][Pt], PieceValue[EG][Pt]) / 3;
- }
-
- if (Pt == JANGGI_CANNON)
- {
- b &= ~pos.pieces(Pt);
- b &= attacks_bb(Us, Pt, s, pos.pieces() ^ pos.pieces(Pt));
- }
if (pos.blockers_for_king(Us) & s)
b &= LineBB[pos.square<KING>(Us)][s];
Bitboard b1 = ( (pos.attacks_from(us, pt, from) & pos.pieces())
| (pos.moves_from(us, pt, from) & ~pos.pieces())) & target;
- // Xiangqi soldier
- if (pt == SOLDIER && pos.unpromoted_soldier(us, from))
- b1 &= file_bb(file_of(from));
- if (pt == JANGGI_CANNON)
- {
- b1 &= ~pos.pieces(pt);
- b1 &= attacks_bb(us, pt, from, pos.pieces() ^ pos.pieces(pt));
- }
PieceType prom_pt = pos.promoted_piece_type(pt);
Bitboard b2 = prom_pt && (!pos.promotion_limit(prom_pt) || pos.promotion_limit(prom_pt) > pos.count(us, prom_pt)) ? b1 : Bitboard(0);
Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : Bitboard(0);
}
}
- // Janggi palace moves
- if (pos.diagonal_lines())
- {
- Bitboard diags = pos.pieces(Us) & pos.diagonal_lines();
- while (diags)
- {
- Square from = pop_lsb(&diags);
- PieceType pt = type_of(pos.piece_on(from));
- PieceType movePt = pt == KING ? pos.king_type() : pt;
- Bitboard b = 0;
- PieceType diagType = movePt == WAZIR ? FERS : movePt == SOLDIER ? PAWN : movePt == ROOK ? BISHOP : NO_PIECE_TYPE;
- if (diagType)
- b |= attacks_bb(Us, diagType, from, pos.pieces());
- else if (movePt == JANGGI_CANNON)
- // TODO: fix for longer diagonals
- b |= attacks_bb(Us, ALFIL, from, pos.pieces()) & ~attacks_bb(Us, ELEPHANT, from, pos.pieces() ^ pos.pieces(JANGGI_CANNON));
- b &= pos.board_bb(Us, pt) & target & pos.diagonal_lines();
- while (b)
- moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, from, pop_lsb(&b));
- }
- }
-
return moveList;
}
while (b)
moveList = make_move_and_gating<NORMAL>(pos, moveList, us, ksq, pop_lsb(&b));
- // Janggi king palace moves
- if (pos.diagonal_lines() & ksq)
- {
- PieceType movePt = pos.king_type();
- PieceType diagType = movePt == WAZIR ? FERS : movePt == SOLDIER ? PAWN : movePt == ROOK ? BISHOP : NO_PIECE_TYPE;
- if (diagType)
- {
- b = attacks_bb(us, diagType, ksq, pos.pieces()) & pos.board_bb(us, KING) & pos.diagonal_lines() & ~pos.pieces(us) & ~sliderAttacks;
- if (!more_than_one(pos.checkers()))
- b &= ~pos.checkers();
- while (b)
- moveList = make_move_and_gating<SPECIAL>(pos, moveList, us, ksq, pop_lsb(&b));
- }
- }
-
if (more_than_one(pos.checkers()))
return moveList; // Double check, only a king move can save the day
// For unused piece types, the check squares are left uninitialized
for (PieceType pt : piece_types())
- si->checkSquares[pt] = ksq != SQ_NONE ? attacks_from(~sideToMove, pt, ksq) : Bitboard(0);
+ si->checkSquares[pt] = ksq != SQ_NONE ? attacks_bb(~sideToMove, pt, ksq, pieces()) : Bitboard(0);
si->checkSquares[KING] = 0;
si->shak = si->checkersBB & (byTypeBB[KNIGHT] | byTypeBB[ROOK] | byTypeBB[BERS]);
- si->bikjang = var->bikjangRule && ksq != SQ_NONE ? bool(attacks_from(sideToMove, ROOK, ksq) & pieces(sideToMove, KING)) : false;
+ si->bikjang = var->bikjangRule && ksq != SQ_NONE ? bool(attacks_bb(sideToMove, ROOK, ksq, pieces()) & pieces(sideToMove, KING)) : false;
}
template<PieceType Pt>
inline Bitboard Position::attacks_from(Square s, Color c) const {
- return attacks_bb(c, Pt == KING ? king_type() : Pt, s, byTypeBB[ALL_PIECES]) & board_bb(c, Pt);
+ return attacks_from(c, Pt, s);
}
inline Bitboard Position::attacks_from(Color c, PieceType pt, Square s) const {
- return attacks_bb(c, pt == KING ? king_type() : pt, s, byTypeBB[ALL_PIECES]) & board_bb(c, pt);
+ PieceType movePt = pt == KING ? king_type() : pt;
+ Bitboard b = attacks_bb(c, movePt, s, byTypeBB[ALL_PIECES]);
+ // Xiangqi soldier
+ if (pt == SOLDIER && unpromoted_soldier(c, s))
+ b &= file_bb(file_of(s));
+ // Janggi cannon restrictions
+ if (pt == JANGGI_CANNON)
+ {
+ b &= ~pieces(pt);
+ b &= attacks_bb(c, pt, s, pieces() ^ pieces(pt));
+ }
+ // Janggi palace moves
+ if (diagonal_lines() & s)
+ {
+ PieceType diagType = movePt == WAZIR ? FERS : movePt == SOLDIER ? PAWN : movePt == ROOK ? BISHOP : NO_PIECE_TYPE;
+ if (diagType)
+ b |= attacks_bb(c, diagType, s, pieces()) & diagonal_lines();
+ else if (movePt == JANGGI_CANNON)
+ // TODO: fix for longer diagonals
+ b |= attacks_bb(c, ALFIL, s, pieces())
+ & ~attacks_bb(c, ELEPHANT, s, pieces() ^ pieces(pt))
+ & diagonal_lines();
+ }
+ return b & board_bb(c, pt);
}
inline Bitboard Position::moves_from(Color c, PieceType pt, Square s) const {
- return moves_bb(c, pt == KING ? king_type() : pt, s, byTypeBB[ALL_PIECES]) & board_bb(c, pt);
+ PieceType movePt = pt == KING ? king_type() : pt;
+ Bitboard b = moves_bb(c, movePt, s, byTypeBB[ALL_PIECES]);
+ // Xiangqi soldier
+ if (pt == SOLDIER && unpromoted_soldier(c, s))
+ b &= file_bb(file_of(s));
+ // Janggi cannon restrictions
+ if (pt == JANGGI_CANNON)
+ {
+ b &= ~pieces(pt);
+ b &= attacks_bb(c, pt, s, pieces() ^ pieces(pt));
+ }
+ // Janggi palace moves
+ if (diagonal_lines() & s)
+ {
+ PieceType diagType = movePt == WAZIR ? FERS : movePt == SOLDIER ? PAWN : movePt == ROOK ? BISHOP : NO_PIECE_TYPE;
+ if (diagType)
+ b |= attacks_bb(c, diagType, s, pieces()) & diagonal_lines();
+ else if (movePt == JANGGI_CANNON)
+ // TODO: fix for longer diagonals
+ b |= attacks_bb(c, ALFIL, s, pieces())
+ & ~attacks_bb(c, ELEPHANT, s, pieces() ^ pieces(pt))
+ & diagonal_lines();
+ }
+ return b & board_bb(c, pt);
}
inline Bitboard Position::attackers_to(Square s) const {