Simplify move generation for Janggi
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 5 Apr 2020 13:39:56 +0000 (15:39 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 5 Apr 2020 13:39:56 +0000 (15:39 +0200)
janggi
LLR: 3.04 (-2.94,2.94) [-10.00,5.00]
Total: 1036 W: 489 L: 433 D: 114

xiangqi
LLR: 2.98 (-2.94,2.94) [-10.00,5.00]
Total: 751 W: 252 L: 207 D: 292

chess
LLR: 2.96 (-2.94,2.94) [-10.00,5.00]
Total: 3003 W: 639 L: 610 D: 1754
http://www.variantfishtest.org:6543/tests/view/5e88bc986e23db4f73614b89

src/evaluate.cpp
src/movegen.cpp
src/position.cpp
src/position.h

index 12c7067..a1bf1ee 100644 (file)
@@ -300,32 +300,11 @@ namespace {
           : 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];
index f3c0e08..665ce4b 100644 (file)
@@ -265,14 +265,6 @@ namespace {
 
         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);
@@ -393,28 +385,6 @@ namespace {
         }
     }
 
-    // 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;
   }
 
@@ -525,21 +495,6 @@ ExtMove* generate<EVASIONS>(const Position& pos, ExtMove* 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
 
index 873b18f..1619b6f 100644 (file)
@@ -496,10 +496,10 @@ void Position::set_check_info(StateInfo* si) const {
 
   // 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;
 }
 
 
index c9c6087..ad3879f 100644 (file)
@@ -840,15 +840,61 @@ inline Square Position::castling_rook_square(CastlingRights cr) const {
 
 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 {