Support microshogi
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 17 Feb 2019 13:23:28 +0000 (14:23 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 17 Feb 2019 13:23:28 +0000 (14:23 +0100)
https://en.wikipedia.org/wiki/Micro_shogi

No functional change for other variants.

src/movegen.cpp
src/position.cpp
src/position.h
src/variant.cpp
src/variant.h

index 18fb999..751685e 100644 (file)
@@ -301,7 +301,14 @@ namespace {
         {
             Bitboard promotion_zone = promotion_zone_bb(us, pos.promotion_rank(), pos.max_rank());
             if (pos.mandatory_piece_promotion())
-                b1 &= promotion_zone & from ? 0 : ~promotion_zone;
+                b1 &= (promotion_zone & from ? 0 : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : 0);
+            // Exclude quiet promotions/demotions
+            if (pos.piece_promotion_on_capture())
+            {
+                b2 &= pos.pieces();
+                b3 &= pos.pieces();
+            }
+            // Consider promotions/demotions into promotion zone
             if (!(promotion_zone & from))
             {
                 b2 &= promotion_zone;
index 646dd2d..6f88c07 100644 (file)
@@ -836,7 +836,8 @@ bool Position::pseudo_legal(const Move m) const {
   // Handle the case where a mandatory piece promotion/demotion is not taken
   if (    mandatory_piece_promotion()
       && (is_promoted(from) ? piece_demotion() : promoted_piece_type(type_of(pc)) != NO_PIECE_TYPE)
-      && (promotion_zone_bb(us, promotion_rank(), max_rank()) & (SquareBB[from] | to)))
+      && (   (promotion_zone_bb(us, promotion_rank(), max_rank()) & (SquareBB[from] | to))
+          || (piece_promotion_on_capture() && !capture(m))))
       return false;
 
   // Is not a promotion, so promotion piece must be empty
index e2b779e..486fbb6 100644 (file)
@@ -100,6 +100,7 @@ public:
   const std::set<PieceType, std::greater<PieceType> >& promotion_piece_types() const;
   bool sittuyin_promotion() const;
   PieceType promoted_piece_type(PieceType pt) const;
+  bool piece_promotion_on_capture() const;
   bool mandatory_piece_promotion() const;
   bool piece_demotion() const;
   bool endgame_eval() const;
@@ -332,6 +333,11 @@ inline PieceType Position::promoted_piece_type(PieceType pt) const {
   return var->promotedPieceType[pt];
 }
 
+inline bool Position::piece_promotion_on_capture() const {
+  assert(var != nullptr);
+  return var->piecePromotionOnCapture;
+}
+
 inline bool Position::mandatory_piece_promotion() const {
   assert(var != nullptr);
   return var->mandatoryPiecePromotion;
index e57165a..56b55e3 100644 (file)
@@ -311,6 +311,21 @@ VariantMap variants; // Global object
         v->shogiDoubledPawn = true;
         return v;
     }
+    Variant* microshogi_variant() {
+        Variant* v = kyotoshogi_variant();
+        v->maxFile = FILE_D;
+        v->startFen = "kb+r+l/p3/4/3P/+L+RBK[-] w 0 1";
+        v->promotionRank = RANK_1;
+        v->piecePromotionOnCapture = true;
+        v->promotedPieceType[LANCE]        = SILVER;
+        v->promotedPieceType[BISHOP]       = GOLD;
+        v->promotedPieceType[ROOK]         = GOLD;
+        v->promotedPieceType[SHOGI_PAWN]   = SHOGI_KNIGHT;
+        v->promotedPieceType[SILVER]       = NO_PIECE_TYPE;
+        v->promotedPieceType[GOLD]         = NO_PIECE_TYPE;
+        v->promotedPieceType[SHOGI_KNIGHT] = NO_PIECE_TYPE;
+        return v;
+    }
     Variant* dobutsu_variant() {
         Variant* v = minishogi_variant_base();
         v->maxRank = RANK_4;
@@ -580,6 +595,7 @@ void VariantMap::init() {
     add("minishogi", minishogi_variant());
     add("mini", minishogi_variant());
     add("kyotoshogi", kyotoshogi_variant());
+    add("micro", microshogi_variant());
     add("dobutsu", dobutsu_variant());
     add("gorogoro", gorogoroshogi_variant());
     add("judkins", judkinsshogi_variant());
index e285731..85abe9d 100644 (file)
@@ -44,6 +44,7 @@ struct Variant {
   std::set<PieceType, std::greater<PieceType> > promotionPieceTypes = { QUEEN, ROOK, BISHOP, KNIGHT };
   bool sittuyinPromotion = false;
   PieceType promotedPieceType[PIECE_TYPE_NB] = {};
+  bool piecePromotionOnCapture = false;
   bool mandatoryPiecePromotion = false;
   bool pieceDemotion = false;
   bool endgameEval = false;