Support chessgi and pocketknight
authorianfab <ianfab@users.noreply.github.com>
Sun, 8 Jul 2018 15:35:39 +0000 (17:35 +0200)
committerianfab <ianfab@users.noreply.github.com>
Sun, 8 Jul 2018 15:36:20 +0000 (17:36 +0200)
src/movegen.cpp
src/pawns.cpp
src/position.cpp
src/position.h
src/variant.cpp
src/variant.h

index 3010f18..5f0cb89 100644 (file)
@@ -84,7 +84,11 @@ namespace {
     if (pos.count_in_hand(Us, pt))
     {
         if (pt == PAWN)
-            b &= ~(promotion_zone_bb(Us, pos.promotion_rank()) | rank_bb(relative_rank(Us, RANK_1)));
+        {
+            b &= ~promotion_zone_bb(Us, pos.promotion_rank());
+            if (!pos.first_rank_drops())
+                b &= ~rank_bb(relative_rank(Us, RANK_1, pos.max_rank()));
+        }
         if (Checks)
             b &= pos.check_squares(pt);
         while (b)
index 8c5c1dc..78f395b 100644 (file)
@@ -103,10 +103,10 @@ namespace {
         stoppers   = theirPawns & passed_pawn_mask(Us, s);
         lever      = theirPawns & PseudoAttacks[Us][PAWN][s];
         leverPush  = theirPawns & PseudoAttacks[Us][PAWN][s + Up];
-        doubled    = ourPawns   & (s - Up);
+        doubled    = relative_rank(Us, s, pos.max_rank()) > RANK_1 ? ourPawns & (s - Up) : 0;
         neighbours = ourPawns   & adjacent_files_bb(f);
         phalanx    = neighbours & rank_bb(s);
-        supported  = neighbours & rank_bb(s - Up);
+        supported  = relative_rank(Us, s, pos.max_rank()) > RANK_1 ? neighbours & rank_bb(s - Up) : 0;
 
         // A pawn is backward when it is behind all pawns of the same color
         // on the adjacent files and cannot be safely advanced.
@@ -164,7 +164,7 @@ void init() {
   for (int opposed = 0; opposed <= 1; ++opposed)
       for (int phalanx = 0; phalanx <= 1; ++phalanx)
           for (int support = 0; support <= 2; ++support)
-              for (Rank r = RANK_2; r < RANK_8; ++r)
+              for (Rank r = RANK_1; r < RANK_8; ++r)
   {
       int v = 17 * support;
       v += (Seed[r] + (phalanx ? (Seed[r + 1] - Seed[r]) / 2 : 0)) >> opposed;
index 2fe4232..2de52df 100644 (file)
@@ -275,7 +275,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960,
           ++sq;
       }
       // Set flag for promoted pieces
-      else if (piece_drops() && !drop_loop() && token == '~')
+      else if (captures_to_hand() && !drop_loop() && token == '~')
           promotedPieces |= SquareBB[sq - 1];
       // Stop before pieces in hand
       else if (token == '[')
@@ -526,7 +526,7 @@ const string Position::fen() const {
               ss << piece_to_char()[piece_on(make_square(f, r))];
 
               // Set promoted pieces
-              if (piece_drops() && is_promoted(make_square(f, r)))
+              if (captures_to_hand() && is_promoted(make_square(f, r)))
                   ss << "~";
           }
       }
@@ -906,13 +906,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
       else
       {
           st->nonPawnMaterial[them] -= PieceValue[MG][captured];
-          if (piece_drops() && !is_promoted(to))
+          if (captures_to_hand() && !is_promoted(to))
               st->nonPawnMaterial[us] += PieceValue[MG][captured];
       }
 
       // Update board and piece lists
       remove_piece(captured, capsq);
-      if (piece_drops())
+      if (captures_to_hand())
       {
           st->capturedpromoted = is_promoted(to);
           Piece pieceToHand = is_promoted(to) ? make_piece(~color_of(captured), PAWN) : ~captured;
@@ -987,7 +987,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
 
           remove_piece(pc, to);
           put_piece(promotion, to);
-          if (piece_drops() && !drop_loop())
+          if (captures_to_hand() && !drop_loop())
               promotedPieces = promotedPieces | to;
 
           // Update hash keys
@@ -1019,7 +1019,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
 
   // Set capture piece
   st->capturedPiece = captured;
-  if (piece_drops() && !captured)
+  if (captures_to_hand() && !captured)
       st->capturedpromoted = false;
 
   // Update the key with the final value
@@ -1066,7 +1066,7 @@ void Position::undo_move(Move m) {
       remove_piece(pc, to);
       pc = make_piece(us, PAWN);
       put_piece(pc, to);
-      if (piece_drops() && !drop_loop())
+      if (captures_to_hand() && !drop_loop())
           promotedPieces -= to;
   }
 
@@ -1081,7 +1081,7 @@ void Position::undo_move(Move m) {
           undrop_piece(pc, to); // Remove the dropped piece
       else
           move_piece(pc, to, from); // Put the piece back at the source square
-      if (piece_drops() && !drop_loop() && is_promoted(to))
+      if (captures_to_hand() && !drop_loop() && is_promoted(to))
           promotedPieces = (promotedPieces - to) | from;
 
       if (st->capturedPiece)
@@ -1100,7 +1100,7 @@ void Position::undo_move(Move m) {
           }
 
           put_piece(st->capturedPiece, capsq); // Restore the captured piece
-          if (piece_drops())
+          if (captures_to_hand())
           {
               remove_from_hand(~color_of(st->capturedPiece),
                                !drop_loop() && st->capturedpromoted ? PAWN : type_of(st->capturedPiece));
@@ -1192,7 +1192,7 @@ Key Position::key_after(Move m) const {
   if (captured)
   {
       k ^= Zobrist::psq[captured][to];
-      if (piece_drops())
+      if (captures_to_hand())
       {
           Piece removeFromHand = !drop_loop() && is_promoted(to) ? make_piece(~color_of(captured), PAWN) : ~captured;
           k ^= Zobrist::inHand[removeFromHand][pieceCountInHand[color_of(removeFromHand)][type_of(removeFromHand)] + 1]
@@ -1299,7 +1299,7 @@ bool Position::is_draw(int ply) const {
   if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
       return true;
 
-  int end = piece_drops() ? st->pliesFromNull : std::min(st->rule50, st->pliesFromNull);
+  int end = captures_to_hand() ? st->pliesFromNull : std::min(st->rule50, st->pliesFromNull);
 
   if (end < 4)
     return false;
index e225bf7..8331e6c 100644 (file)
@@ -100,6 +100,8 @@ public:
   bool must_capture() const;
   bool piece_drops() const;
   bool drop_loop() const;
+  bool captures_to_hand() const;
+  bool first_rank_drops() const;
   // winning conditions
   Value stalemate_value(int ply = 0) const;
   Value checkmate_value(int ply = 0) const;
@@ -304,6 +306,16 @@ inline bool Position::drop_loop() const {
   return var->dropLoop;
 }
 
+inline bool Position::captures_to_hand() const {
+  assert(var != nullptr);
+  return var->capturesToHand;
+}
+
+inline bool Position::first_rank_drops() const {
+  assert(var != nullptr);
+  return var->firstRankDrops;
+}
+
 inline Value Position::stalemate_value(int ply) const {
   assert(var != nullptr);
   Value v = var->stalemateValue;
index cddc017..cc57253 100644 (file)
@@ -144,15 +144,33 @@ void VariantMap::init() {
         Variant* v = new Variant();
         v->startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[] w KQkq - 0 1";
         v->pieceDrops = true;
+        v->capturesToHand = true;
         return v;
     } ();
     const Variant* loop = [&]{
         Variant* v = new Variant();
         v->startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[] w KQkq - 0 1";
         v->pieceDrops = true;
+        v->capturesToHand = true;
         v->dropLoop = true;
         return v;
     } ();
+    const Variant* chessgi = [&]{
+        Variant* v = new Variant();
+        v->startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[] w KQkq - 0 1";
+        v->pieceDrops = true;
+        v->dropLoop = true;
+        v->capturesToHand = true;
+        v->firstRankDrops = true;
+        return v;
+    } ();
+    const Variant* pocketknight = [&]{
+        Variant* v = new Variant();
+        v->startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[Nn] w KQkq - 0 1";
+        v->pieceDrops = true;
+        v->capturesToHand = false;
+        return v;
+    } ();
     const Variant* euroshogi = [&]{
         Variant* v = new Variant();
         v->reset_pieces();
@@ -164,6 +182,7 @@ void VariantMap::init() {
         v->add_piece(KING, 'k');
         v->startFen = "1nbgkgn1/1r4b1/pppppppp/8/8/PPPPPPPP/1B4R1/1NGKGBN1[-] w 0 1";
         v->pieceDrops = true;
+        v->capturesToHand = true;
         v->promotionRank = RANK_6;
         v->promotionPieceTypes = {};
         v->doubleStep = false;
@@ -184,6 +203,7 @@ void VariantMap::init() {
         v->add_piece(KING, 'k');
         v->startFen = "rbsgk/4p/5/P4/KGSBR[-] w 0 1";
         v->pieceDrops = true;
+        v->capturesToHand = true;
         v->promotionRank = RANK_5;
         v->promotionPieceTypes = {};
         v->doubleStep = false;
@@ -247,6 +267,8 @@ void VariantMap::init() {
     add("5check", fivecheck);
     add("crazyhouse", crazyhouse);
     add("loop", loop);
+    add("chessgi", chessgi);
+    add("pocketknight", pocketknight);
     add("euroshogi", euroshogi);
     add("minishogi", minishogi);
     add("losalamos", losalamos);
index ab58036..8644161 100644 (file)
@@ -48,6 +48,8 @@ struct Variant {
   bool mustCapture = false;
   bool pieceDrops = false;
   bool dropLoop = false;
+  bool capturesToHand = false;
+  bool firstRankDrops = false;
   // game end
   Value stalemateValue = VALUE_DRAW;
   Value checkmateValue = -VALUE_MATE;