Invalidate drops and normal moves that result in a piece having no legal move.
Perft looks good now for euroshogi and minishogi, so add them to tests.
uint8_t PopCnt16[1 << 16];
int SquareDistance[SQUARE_NB][SQUARE_NB];
+Bitboard BoardSizeBB[FILE_NB][RANK_NB];
Bitboard SquareBB[SQUARE_NB];
Bitboard FileBB[FILE_NB];
Bitboard RankBB[RANK_NB];
PassedPawnMask[c][s] = ForwardFileBB [c][s] | PawnAttackSpan[c][s];
}
+ for (File f = FILE_A; f <= FILE_H; ++f)
+ for (Rank r = RANK_1; r <= RANK_8; ++r)
+ BoardSizeBB[f][r] = ForwardFileBB[BLACK][make_square(f, r)] | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : 0);
+
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
if (s1 != s2)
extern int SquareDistance[SQUARE_NB][SQUARE_NB];
+extern Bitboard BoardSizeBB[FILE_NB][RANK_NB];
extern Bitboard SquareBB[SQUARE_NB];
extern Bitboard FileBB[FILE_NB];
extern Bitboard RankBB[RANK_NB];
return b & (b - 1);
}
+
+/// board_size_bb() returns a bitboard representing all the squares
+/// on a board with given size.
+
+inline Bitboard board_size_bb(File f, Rank r) {
+ return BoardSizeBB[f][r];
+}
+
+
/// rank_bb() and file_bb() return a bitboard representing all the squares on
/// the given file or rank.
: ( (pos.attacks_from(Us, Pt, s) & pos.pieces())
| (pos.moves_from(Us, Pt, s) & ~pos.pieces()));
+ // Restrict mobility to actual squares of board
+ b &= pos.board_bb();
+
if (pos.blockers_for_king(Us) & s)
b &= LineBB[pos.square<KING>(Us)][s];
assert(!count<KING>(us) || piece_on(square<KING>(us)) == make_piece(us, KING));
// illegal moves to squares outside of board
- if (rank_of(to) > max_rank() || file_of(to) > max_file())
+ if (!(board_bb() & to))
return false;
// illegal checks
}
}
+ // no legal moves from target square
+ if ((type_of(m) == DROP || type_of(m) == NORMAL) && !(moves_bb(us, type_of(moved_piece(m)), to, 0) & board_bb()))
+ return false;
+
// illegal drops
if (piece_drops() && type_of(m) == DROP)
- return pieceCountInHand[us][type_of(moved_piece(m))] && empty(to_sq(m)) && moves_bb(us, type_of(moved_piece(m)), to, 0);
+ return pieceCountInHand[us][type_of(moved_piece(m))] && empty(to_sq(m));
// game end
if (is_variant_end())
const Variant* variant() const;
Rank max_rank() const;
File max_file() const;
+ Bitboard board_bb() const;
const std::set<PieceType>& piece_types() const;
const std::string piece_to_char() const;
Rank promotion_rank() const;
return var->maxFile;
}
+inline Bitboard Position::board_bb() const {
+ assert(var != nullptr);
+ return board_size_bb(var->maxFile, var->maxRank);
+}
+
inline const std::set<PieceType>& Position::piece_types() const {
assert(var != nullptr);
return var->pieceTypes;
expect perft.exp giveaway startpos 5 2732672 > /dev/null
expect perft.exp asean startpos 5 6223994 > /dev/null
expect perft.exp ai-wok startpos 5 13275068 > /dev/null
+expect perft.exp euroshogi startpos 5 9451149 > /dev/null
+expect perft.exp minishogi startpos 5 533203 > /dev/null
rm perft.exp