Fix move validation for minishogi
authorianfab <ianfab@users.noreply.github.com>
Sun, 22 Jul 2018 11:12:49 +0000 (13:12 +0200)
committerianfab <ianfab@users.noreply.github.com>
Sun, 22 Jul 2018 11:12:49 +0000 (13:12 +0200)
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
src/bitboard.h
src/evaluate.cpp
src/position.cpp
src/position.h
tests/perft.sh

index 534e4a3..a722a73 100644 (file)
@@ -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)
index 4abfd80..cc2852c 100644 (file)
@@ -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.
 
index 43f30bc..079b57a 100644 (file)
@@ -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<KING>(Us)][s];
 
index bb54593..b2509f3 100644 (file)
@@ -638,7 +638,7 @@ bool Position::legal(Move m) const {
   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
@@ -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())
index bf53546..a5b18c5 100644 (file)
@@ -91,6 +91,7 @@ public:
   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;
@@ -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<PieceType>& Position::piece_types() const {
   assert(var != nullptr);
   return var->pieceTypes;
index 97ca01b..60bcee1 100755 (executable)
@@ -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