From 2ca06be76e19a665682f07a365291f0da63af3a9 Mon Sep 17 00:00:00 2001 From: ianfab Date: Sun, 22 Jul 2018 13:12:49 +0200 Subject: [PATCH] Fix move validation for minishogi 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. --- src/bitboard.cpp | 5 +++++ src/bitboard.h | 10 ++++++++++ src/evaluate.cpp | 3 +++ src/position.cpp | 8 ++++++-- src/position.h | 6 ++++++ tests/perft.sh | 2 ++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 534e4a3..a722a73 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -26,6 +26,7 @@ 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]; @@ -131,6 +132,10 @@ void Bitboards::init() { 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) diff --git a/src/bitboard.h b/src/bitboard.h index 4abfd80..cc2852c 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -62,6 +62,7 @@ constexpr Bitboard Rank8BB = Rank1BB << (8 * 7); 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]; @@ -147,6 +148,15 @@ constexpr bool more_than_one(Bitboard b) { 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. diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 43f30bc..079b57a 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -314,6 +314,9 @@ namespace { : ( (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(Us)][s]; diff --git a/src/position.cpp b/src/position.cpp index bb54593..b2509f3 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -638,7 +638,7 @@ bool Position::legal(Move m) const { assert(!count(us) || piece_on(square(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 @@ -662,9 +662,13 @@ bool Position::legal(Move m) const { } } + // 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()) diff --git a/src/position.h b/src/position.h index bf53546..a5b18c5 100644 --- a/src/position.h +++ b/src/position.h @@ -91,6 +91,7 @@ public: const Variant* variant() const; Rank max_rank() const; File max_file() const; + Bitboard board_bb() const; const std::set& piece_types() const; const std::string piece_to_char() const; Rank promotion_rank() const; @@ -265,6 +266,11 @@ inline File Position::max_file() 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& Position::piece_types() const { assert(var != nullptr); return var->pieceTypes; diff --git a/tests/perft.sh b/tests/perft.sh index 97ca01b..60bcee1 100755 --- a/tests/perft.sh +++ b/tests/perft.sh @@ -44,6 +44,8 @@ expect perft.exp antichess startpos 5 2732672 > /dev/null 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 -- 1.7.0.4