Simplify usages of piece types and sets
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 25 Mar 2023 16:26:04 +0000 (17:26 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 25 Mar 2023 17:09:41 +0000 (18:09 +0100)
No functional change.

src/position.cpp
src/types.h
src/variant.cpp
src/variant.h

index 7daec3a..3c1ff5d 100644 (file)
@@ -183,9 +183,9 @@ void Position::init() {
   std::memset(cuckooMove, 0, sizeof(cuckooMove));
   int count = 0;
   for (Color c : {WHITE, BLACK})
-      for (PieceType pt = KNIGHT; pt <= QUEEN || pt == KING; pt != QUEEN ? ++pt : pt = KING)
+      for (PieceSet ps = CHESS_PIECES & ~piece_set(PAWN); ps;)
       {
-      Piece pc = make_piece(c, pt);
+      Piece pc = make_piece(c, pop_lsb(ps));
       for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
           for (Square s2 = Square(s1 + 1); s2 <= SQ_MAX; ++s2)
               if ((type_of(pc) != PAWN) && (attacks_bb(c, type_of(pc), s1, 0) & s2))
index ef99c4a..0c39841 100644 (file)
@@ -396,14 +396,19 @@ enum PieceType {
   SOLDIER, HORSE, ELEPHANT, JANGGI_ELEPHANT, BANNER,
   WAZIR, COMMONER, CENTAUR,
 
-  CUSTOM_PIECES,
-  FAIRY_PIECES = QUEEN + 1,
-  FAIRY_PIECES_END = CUSTOM_PIECES - 1,
+  CUSTOM_PIECE_1, CUSTOM_PIECE_2, CUSTOM_PIECE_3, CUSTOM_PIECE_4,
+  CUSTOM_PIECE_5, CUSTOM_PIECE_6, CUSTOM_PIECE_7, CUSTOM_PIECE_8,
+
   PIECE_TYPE_NB = 1 << PIECE_TYPE_BITS,
   KING = PIECE_TYPE_NB - 1,
+
+  // Aliases
+  CUSTOM_PIECES = CUSTOM_PIECE_1,
   CUSTOM_PIECES_END = KING - 1,
   CUSTOM_PIECES_ROYAL = CUSTOM_PIECES_END,
   CUSTOM_PIECES_NB = CUSTOM_PIECES_END - CUSTOM_PIECES + 1,
+  FAIRY_PIECES = QUEEN + 1,
+  FAIRY_PIECES_END = CUSTOM_PIECES - 1,
   ALL_PIECES = 0,
 };
 static_assert(KING < PIECE_TYPE_NB, "KING exceeds PIECE_TYPE_NB.");
@@ -420,7 +425,12 @@ enum Piece {
 };
 
 enum PieceSet : uint64_t {
-  NO_PIECE_SET = 0
+  NO_PIECE_SET = 0,
+  CHESS_PIECES = (1ULL << PAWN) | (1ULL << KNIGHT) | (1ULL << BISHOP) | (1ULL << ROOK) | (1ULL << QUEEN) | (1ULL << KING),
+  COMMON_FAIRY_PIECES = (1ULL << IMMOBILE_PIECE) | (1ULL << COMMONER) | (1ULL << ARCHBISHOP) | (1ULL << CHANCELLOR),
+  SHOGI_PIECES = (1ULL << SHOGI_PAWN) | (1ULL << GOLD) | (1ULL << SILVER) | (1ULL << SHOGI_KNIGHT) | (1ULL << LANCE)
+                | (1ULL << DRAGON)| (1ULL << DRAGON_HORSE) | (1ULL << KING),
+  COMMON_STEP_PIECES = (1ULL << COMMONER) | (1ULL << FERS) | (1ULL << WAZIR) | (1ULL << BREAKTHROUGH_PIECE),
 };
 
 enum RiderType : int {
index ee9f67f..05e381f 100644 (file)
@@ -85,11 +85,11 @@ namespace {
     Variant* berolina_variant() {
         Variant* v = chess_variant_base()->init();
         v->remove_piece(PAWN);
-        v->add_piece(CUSTOM_PIECES, 'p', "mfFcfeWimfnA");
-        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECES;
-        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECES);
+        v->add_piece(CUSTOM_PIECE_1, 'p', "mfFcfeWimfnA");
+        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1;
+        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
         return v;
     }
     // Pawnsideways
@@ -97,11 +97,11 @@ namespace {
     Variant* pawnsideways_variant() {
         Variant* v = chess_variant_base()->init();
         v->remove_piece(PAWN);
-        v->add_piece(CUSTOM_PIECES, 'p', "fsmWfceFifmnD");
-        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECES;
-        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECES);
+        v->add_piece(CUSTOM_PIECE_1, 'p', "fsmWfceFifmnD");
+        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1;
+        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
         return v;
     }
     // Pawnback
@@ -109,13 +109,13 @@ namespace {
     Variant* pawnback_variant() {
         Variant* v = chess_variant_base()->init();
         v->remove_piece(PAWN);
-        v->add_piece(CUSTOM_PIECES, 'p', "fbmWfceFifmnD");
-        v->mobilityRegion[WHITE][CUSTOM_PIECES] = (Rank2BB | Rank3BB | Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB);
-        v->mobilityRegion[BLACK][CUSTOM_PIECES] = (Rank7BB | Rank6BB | Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB);
-        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECES;
-        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECES);
+        v->add_piece(CUSTOM_PIECE_1, 'p', "fbmWfceFifmnD");
+        v->mobilityRegion[WHITE][CUSTOM_PIECE_1] = (Rank2BB | Rank3BB | Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB);
+        v->mobilityRegion[BLACK][CUSTOM_PIECE_1] = (Rank7BB | Rank6BB | Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB);
+        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1;
+        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
         return v;
     }
     // Legan Chess
@@ -123,12 +123,12 @@ namespace {
     Variant* legan_variant() {
         Variant* v =  chess_variant_base()->init();
         v->remove_piece(PAWN);
-        v->add_piece(CUSTOM_PIECES, 'p', "mflFcflW");
+        v->add_piece(CUSTOM_PIECE_1, 'p', "mflFcflW");
         v->promotionRegion[WHITE] = make_bitboard(SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_A7, SQ_A6, SQ_A5);
         v->promotionRegion[BLACK] = make_bitboard(SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_H2, SQ_H3, SQ_H4);
-        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECES;
-        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECES);
+        v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1;
+        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
         v->startFen = "knbrp3/bqpp4/npp5/rp1p3P/p3P1PR/5PPN/4PPQB/3PRBNK w - - 0 1";
         v->doubleStep = false;
         return v;
@@ -279,18 +279,18 @@ namespace {
     Variant* nightrider_variant() {
         Variant* v = chess_variant_base()->init();
         v->remove_piece(KNIGHT);
-        v->add_piece(CUSTOM_PIECES, 'n', "NN");
-        v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | ROOK | BISHOP | CUSTOM_PIECES;
-        v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | ROOK | BISHOP | CUSTOM_PIECES;
+        v->add_piece(CUSTOM_PIECE_1, 'n', "NN");
+        v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | ROOK | BISHOP | CUSTOM_PIECE_1;
+        v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | ROOK | BISHOP | CUSTOM_PIECE_1;
         return v;
     }
     // Grasshopper chess
     // https://en.wikipedia.org/wiki/Grasshopper_chess
     Variant* grasshopper_variant() {
         Variant* v = chess_variant_base()->init();
-        v->add_piece(CUSTOM_PIECES, 'g', "gQ");
-        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECES;
-        v->promotionPieceTypes[BLACK] |= CUSTOM_PIECES;
+        v->add_piece(CUSTOM_PIECE_1, 'g', "gQ");
+        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECE_1;
+        v->promotionPieceTypes[BLACK] |= CUSTOM_PIECE_1;
         v->startFen = "rnbqkbnr/gggggggg/pppppppp/8/8/PPPPPPPP/GGGGGGGG/RNBQKBNR w KQkq - 0 1";
         v->doubleStep = false;
         return v;
@@ -500,7 +500,7 @@ namespace {
         v->maxRank = RANK_8;
         v->maxFile = FILE_F;
         v->reset_pieces();
-        v->add_piece(CUSTOM_PIECES, 'p', "mK"); //move as a King, but can't capture
+        v->add_piece(CUSTOM_PIECE_1, 'p', "mK"); //move as a King, but can't capture
         v->startFen = "2p3/6/6/6/6/6/6/3P2 w - - 0 1";
         v->stalemateValue = -VALUE_MATE;
         v->staticGating = true;
@@ -522,7 +522,7 @@ namespace {
         v->maxRank = RANK_7;
         v->maxFile = FILE_G;
         v->reset_pieces();
-        v->add_piece(CUSTOM_PIECES, 'p', "mK"); //move as a King, but can't capture
+        v->add_piece(CUSTOM_PIECE_1, 'p', "mK"); //move as a King, but can't capture
         v->startFen = "6p/7/7/7/7/7/P6 w - - 0 1";
         v->stalemateValue = -VALUE_MATE;
         v->pastGating = true;
@@ -533,7 +533,7 @@ namespace {
         //This page mainly describes a variant where position on home row is randomized, but also a variant where they start in the centre(implemented here)
         Variant* v = chess_variant_base()->init();
         v->reset_pieces();
-        v->add_piece(CUSTOM_PIECES, 'n', "mN"); //move as a Knight, but can't capture
+        v->add_piece(CUSTOM_PIECE_1, 'n', "mN"); //move as a Knight, but can't capture
         v->startFen = "8/8/8/4n3/3N4/8/8/8 w - - 0 1";
         v->stalemateValue = -VALUE_MATE;
         v->pastGating = true;
@@ -714,9 +714,9 @@ namespace {
     Variant* paradigm_variant() {
         Variant *v = chess_variant_base()->init();
         v->remove_piece(BISHOP);
-        v->add_piece(CUSTOM_PIECES, 'b', "BnN");
-        v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | CUSTOM_PIECES | ROOK | KNIGHT;
-        v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | CUSTOM_PIECES | ROOK | KNIGHT;
+        v->add_piece(CUSTOM_PIECE_1, 'b', "BnN");
+        v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | CUSTOM_PIECE_1 | ROOK | KNIGHT;
+        v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | CUSTOM_PIECE_1 | ROOK | KNIGHT;
         return v;
     }
     // Base used for most shogi variants
@@ -877,13 +877,13 @@ namespace {
         v->reset_pieces();
         v->add_piece(SHOGI_PAWN, 's');
         v->add_piece(KING, 'k');
-        v->add_piece(CUSTOM_PIECES, 'f', "FsfW"); // falcon
-        v->add_piece(CUSTOM_PIECES + 1, 'c', "FvW"); // crane
-        v->add_piece(CUSTOM_PIECES + 2, 'l', "fRrbBlbF"); // left quail
-        v->add_piece(CUSTOM_PIECES + 3, 'r', "fRlbBrbF"); // right quail
-        v->add_piece(CUSTOM_PIECES + 4, 'p', "bFfD"); // pheasant
-        v->add_piece(CUSTOM_PIECES + 5, 'g', "fAbD"); // goose
-        v->add_piece(CUSTOM_PIECES + 6, 'e', "KbRfBbF2"); // eagle
+        v->add_piece(CUSTOM_PIECE_1, 'f', "FsfW"); // falcon
+        v->add_piece(CUSTOM_PIECE_2, 'c', "FvW"); // crane
+        v->add_piece(CUSTOM_PIECE_3, 'l', "fRrbBlbF"); // left quail
+        v->add_piece(CUSTOM_PIECE_4, 'r', "fRlbBrbF"); // right quail
+        v->add_piece(CUSTOM_PIECE_5, 'p', "bFfD"); // pheasant
+        v->add_piece(CUSTOM_PIECE_6, 'g', "fAbD"); // goose
+        v->add_piece(CUSTOM_PIECE_7, 'e', "KbRfBbF2"); // eagle
         v->startFen = "rpckcpl/3f3/sssssss/2s1S2/SSSSSSS/3F3/LPCKCPR[-] w 0 1";
         v->pieceDrops = true;
         v->capturesToHand = true;
@@ -891,8 +891,8 @@ namespace {
         v->promotionRegion[BLACK] = Rank2BB | Rank1BB;
         v->doubleStep = false;
         v->castling = false;
-        v->promotedPieceType[SHOGI_PAWN]    = CUSTOM_PIECES + 5; // swallow promotes to goose
-        v->promotedPieceType[CUSTOM_PIECES] = CUSTOM_PIECES + 6; // falcon promotes to eagle
+        v->promotedPieceType[SHOGI_PAWN]    = CUSTOM_PIECE_6; // swallow promotes to goose
+        v->promotedPieceType[CUSTOM_PIECE_1] = CUSTOM_PIECE_7; // falcon promotes to eagle
         v->mandatoryPiecePromotion = true;
         v->dropNoDoubled = SHOGI_PAWN;
         v->dropNoDoubledCount = 2;
@@ -912,11 +912,11 @@ namespace {
         v->pieceToCharTable = "PNBR.....G.++++Kpnbr.....g.++++k";
         v->maxRank = RANK_8;
         v->maxFile = FILE_H;
-        v->add_piece(CUSTOM_PIECES, 'n', "fNsW");
+        v->add_piece(CUSTOM_PIECE_1, 'n', "fNsW");
         v->startFen = "1nbgkgn1/1r4b1/pppppppp/8/8/PPPPPPPP/1B4R1/1NGKGBN1[-] w 0 1";
         v->promotionRegion[WHITE] = Rank6BB | Rank7BB | Rank8BB;
         v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB;
-        v->promotedPieceType[CUSTOM_PIECES] = GOLD;
+        v->promotedPieceType[CUSTOM_PIECE_1] = GOLD;
         v->mandatoryPiecePromotion = true;
         return v;
     }
@@ -994,14 +994,14 @@ namespace {
         Variant* v = threekings_variant()->init();
         v->add_piece(DRAGON, 'g');
         v->add_piece(ARCHBISHOP, 'w');
-        v->add_piece(CUSTOM_PIECES, 'h', "fmFfcWimA");
-        v->add_piece(CUSTOM_PIECES + 1, 'l', "FAsmW");
-        v->add_piece(CUSTOM_PIECES + 2, 'c', "WD");
+        v->add_piece(CUSTOM_PIECE_1, 'h', "fmFfcWimA");
+        v->add_piece(CUSTOM_PIECE_2, 'l', "FAsmW");
+        v->add_piece(CUSTOM_PIECE_3, 'c', "WD");
         v->startFen = "lgkcckwl/hhhhhhhh/8/8/8/8/PPPPPPPP/RNBQKBNR w KQ - 0 1";
-        v->promotionPawnType[BLACK] = CUSTOM_PIECES;
-        v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECES);
-        v->promotionPieceTypes[BLACK] = piece_set(COMMONER) | DRAGON | ARCHBISHOP | (CUSTOM_PIECES + 1) | (CUSTOM_PIECES + 2);
+        v->promotionPawnType[BLACK] = CUSTOM_PIECE_1;
+        v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
+        v->promotionPieceTypes[BLACK] = piece_set(COMMONER) | DRAGON | ARCHBISHOP | CUSTOM_PIECE_2 | CUSTOM_PIECE_3;
         v->promotionLimit[COMMONER] = 2;
         v->enPassantRegion = 0;
         v->extinctionPieceCount = 0;
@@ -1078,7 +1078,7 @@ namespace {
         v->maxRank = RANK_7;
         v->maxFile = FILE_G;
         v->reset_pieces();
-        v->add_piece(CUSTOM_PIECES, 'p', "mDmNmA");
+        v->add_piece(CUSTOM_PIECE_1, 'p', "mDmNmA");
         v->startFen = "P5p/7/7/7/7/7/p5P w 0 1";
         v->pieceDrops = true;
         v->doubleStep = false;
@@ -1175,11 +1175,11 @@ namespace {
         v->pieceToCharTable = "PNBRLSE..G.+.++.++Kpnbrlse..g.+.++.++k";
         v->remove_piece(KING);
         v->add_piece(COMMONER, 'k');
-        v->add_piece(CUSTOM_PIECES, 'e', "FsfW"); // drunk elephant
+        v->add_piece(CUSTOM_PIECE_1, 'e', "FsfW"); // drunk elephant
         v->startFen = "lnsgkgsnl/1r2e2b1/ppppppppp/9/9/9/PPPPPPPPP/1B2E2R1/LNSGKGSNL w 0 1";
         v->capturesToHand = false;
         v->pieceDrops = false;
-        v->promotedPieceType[CUSTOM_PIECES] = COMMONER;
+        v->promotedPieceType[CUSTOM_PIECE_1] = COMMONER;
         v->castlingKingPiece[WHITE] = v->castlingKingPiece[BLACK] = COMMONER;
         v->extinctionValue = -VALUE_MATE;
         v->extinctionPieceTypes = piece_set(COMMONER);
@@ -1199,18 +1199,18 @@ namespace {
         v->add_piece(KING, 'k');
         v->add_piece(SHOGI_PAWN, 'p');
         v->add_piece(ROOK, 'l');
-        v->add_piece(CUSTOM_PIECES, 'n', "fRffN"); // Yari knight
-        v->add_piece(CUSTOM_PIECES + 1, 'b', "fFfR"); // Yari bishop
-        v->add_piece(CUSTOM_PIECES + 2, 'r', "frlR"); // Yari rook
-        v->add_piece(CUSTOM_PIECES + 3, 'g', "WfFbR"); // Yari gold
-        v->add_piece(CUSTOM_PIECES + 4, 's', "fKbR"); // Yari silver
+        v->add_piece(CUSTOM_PIECE_1, 'n', "fRffN"); // Yari knight
+        v->add_piece(CUSTOM_PIECE_2, 'b', "fFfR"); // Yari bishop
+        v->add_piece(CUSTOM_PIECE_3, 'r', "frlR"); // Yari rook
+        v->add_piece(CUSTOM_PIECE_4, 'g', "WfFbR"); // Yari gold
+        v->add_piece(CUSTOM_PIECE_5, 's', "fKbR"); // Yari silver
         v->startFen = "rnnkbbr/7/ppppppp/7/7/7/PPPPPPP/7/RBBKNNR[-] w 0 1";
         v->promotionRegion[WHITE] = Rank7BB | Rank8BB | Rank9BB;
         v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB;
-        v->promotedPieceType[SHOGI_PAWN] = CUSTOM_PIECES + 4;
-        v->promotedPieceType[CUSTOM_PIECES] = CUSTOM_PIECES + 3;
-        v->promotedPieceType[CUSTOM_PIECES + 1] = CUSTOM_PIECES + 3;
-        v->promotedPieceType[CUSTOM_PIECES + 2] = ROOK;
+        v->promotedPieceType[SHOGI_PAWN] = CUSTOM_PIECE_5;
+        v->promotedPieceType[CUSTOM_PIECE_1] = CUSTOM_PIECE_4;
+        v->promotedPieceType[CUSTOM_PIECE_2] = CUSTOM_PIECE_4;
+        v->promotedPieceType[CUSTOM_PIECE_3] = ROOK;
         v->pieceDrops = true;
         v->capturesToHand = true;
         v->doubleStep = false;
@@ -1230,13 +1230,13 @@ namespace {
         Variant* v = minishogi_variant_base()->init();
         v->maxRank = RANK_10;
         v->maxFile = FILE_J;
-        v->add_piece(CUSTOM_PIECES, 'l', "vR"); // Vertical slider
+        v->add_piece(CUSTOM_PIECE_1, 'l', "vR"); // Vertical slider
         v->add_piece(KNIGHT, 'n');
         v->add_piece(QUEEN, 'q');
         v->startFen = "lnsgkqgsnl/1r6b1/pppppppppp/10/10/10/10/PPPPPPPPPP/1B6R1/LNSGQKGSNL[-] w 0 1";
         v->promotionRegion[WHITE] = Rank8BB | Rank9BB | Rank10BB;
         v->promotionRegion[BLACK] = Rank3BB | Rank2BB | Rank1BB;
-        v->promotedPieceType[CUSTOM_PIECES] = GOLD;
+        v->promotedPieceType[CUSTOM_PIECE_1] = GOLD;
         v->promotedPieceType[KNIGHT] = GOLD;
         return v;
     }
@@ -1463,18 +1463,18 @@ namespace {
         Variant* v = grand_variant()->init();
         v->pieceToCharTable = "PNBRQ..AC....W.......LKpnbrq..ac....w.......lk";
         v->remove_piece(KNIGHT);
-        v->add_piece(CUSTOM_PIECES, 'n', "NW");
-        v->add_piece(CUSTOM_PIECES + 1, 'w', "CF");
-        v->add_piece(CUSTOM_PIECES + 2, 'l', "FDH");
+        v->add_piece(CUSTOM_PIECE_1, 'n', "NW");
+        v->add_piece(CUSTOM_PIECE_2, 'w', "CF");
+        v->add_piece(CUSTOM_PIECE_3, 'l', "FDH");
         v->startFen = "rw6wr/clbnqknbla/pppppppppp/10/10/10/10/PPPPPPPPPP/CLBNQKNBLA/RW6WR w - - 0 1";
         v->promotionPieceTypes[WHITE] &= ~piece_set(KNIGHT);
-        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECES;
-        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECES + 1;
-        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECES + 2;
+        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECE_1;
+        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECE_2;
+        v->promotionPieceTypes[WHITE] |= CUSTOM_PIECE_3;
         v->promotionPieceTypes[BLACK] = v->promotionPieceTypes[WHITE];
-        v->promotionLimit[CUSTOM_PIECES] = 2;
-        v->promotionLimit[CUSTOM_PIECES + 1] = 2;
-        v->promotionLimit[CUSTOM_PIECES + 2] = 2;
+        v->promotionLimit[CUSTOM_PIECE_1] = 2;
+        v->promotionLimit[CUSTOM_PIECE_2] = 2;
+        v->promotionLimit[CUSTOM_PIECE_3] = 2;
         return v;
     }
     // Tencubed
@@ -1487,8 +1487,8 @@ namespace {
         v->startFen = "2cwamwc2/1rnbqkbnr1/pppppppppp/10/10/10/10/PPPPPPPPPP/1RNBQKBNR1/2CWAMWC2 w - - 0 1";
         v->add_piece(ARCHBISHOP, 'a');
         v->add_piece(CHANCELLOR, 'm');
-        v->add_piece(CUSTOM_PIECES, 'c', "DAW"); // Champion
-        v->add_piece(CUSTOM_PIECES + 1, 'w', "CF"); // Wizard
+        v->add_piece(CUSTOM_PIECE_1, 'c', "DAW"); // Champion
+        v->add_piece(CUSTOM_PIECE_2, 'w', "CF"); // Wizard
         v->promotionPieceTypes[WHITE] = piece_set(ARCHBISHOP) | CHANCELLOR | QUEEN;
         v->promotionPieceTypes[BLACK] = piece_set(ARCHBISHOP) | CHANCELLOR | QUEEN;
         v->promotionRegion[WHITE] = Rank10BB;
@@ -1507,15 +1507,15 @@ namespace {
         v->maxRank = RANK_10;
         v->maxFile = FILE_L;
         v->startFen = "w**********w/*crnbqkbnrc*/*pppppppppp*/*10*/*10*/*10*/*10*/*PPPPPPPPPP*/*CRNBQKBNRC*/W**********W w KQkq - 0 1";
-        v->add_piece(CUSTOM_PIECES, 'c', "DAW"); // Champion
-        v->add_piece(CUSTOM_PIECES + 1, 'w', "CF"); // Wizard
+        v->add_piece(CUSTOM_PIECE_1, 'c', "DAW"); // Champion
+        v->add_piece(CUSTOM_PIECE_2, 'w', "CF"); // Wizard
         v->castlingKingsideFile = FILE_I;
         v->castlingQueensideFile = FILE_E;
         v->castlingRank = RANK_2;
         v->promotionRegion[WHITE] = Rank9BB | Rank10BB;
         v->promotionRegion[BLACK] = Rank2BB | Rank1BB;
-        v->promotionPieceTypes[WHITE] = piece_set(CUSTOM_PIECES + 1) | CUSTOM_PIECES | QUEEN | ROOK | BISHOP | KNIGHT;
-        v->promotionPieceTypes[BLACK] = piece_set(CUSTOM_PIECES + 1) | CUSTOM_PIECES | QUEEN | ROOK | BISHOP | KNIGHT;
+        v->promotionPieceTypes[WHITE] = piece_set(CUSTOM_PIECE_2) | CUSTOM_PIECE_1 | QUEEN | ROOK | BISHOP | KNIGHT;
+        v->promotionPieceTypes[BLACK] = piece_set(CUSTOM_PIECE_2) | CUSTOM_PIECE_1 | QUEEN | ROOK | BISHOP | KNIGHT;
         v->doubleStepRegion[WHITE] = Rank3BB;
         v->doubleStepRegion[BLACK] = Rank8BB;
         return v;
@@ -1542,21 +1542,21 @@ namespace {
         v->remove_piece(KNIGHT);
         v->add_piece(CHANCELLOR, 'w'); // wolf
         v->add_piece(ARCHBISHOP, 'f'); // fox
-        v->add_piece(CUSTOM_PIECES, 's', "fKifmnD"); // seargent
-        v->add_piece(CUSTOM_PIECES + 1, 'n', "NN"); // nightrider
-        v->add_piece(CUSTOM_PIECES + 2, 'e', "NNQ"); // elephant
+        v->add_piece(CUSTOM_PIECE_1, 's', "fKifmnD"); // seargent
+        v->add_piece(CUSTOM_PIECE_2, 'n', "NN"); // nightrider
+        v->add_piece(CUSTOM_PIECE_3, 'e', "NNQ"); // elephant
         v->startFen = "qwfrbbnk/pssppssp/1pp2pp1/8/8/8/8/1PP2PP1/PSSPPSSP/KNBBRFWQ w - - 0 1";
         v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = PAWN;
-        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(PAWN) | piece_set(CUSTOM_PIECES);
+        v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(PAWN) | piece_set(CUSTOM_PIECE_1);
         v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP;
         v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP;
-        v->promotedPieceType[PAWN] = CUSTOM_PIECES + 2;
+        v->promotedPieceType[PAWN] = CUSTOM_PIECE_3;
         v->promotionRegion[WHITE] = Rank10BB;
         v->promotionRegion[BLACK] = Rank1BB;
         v->doubleStepRegion[WHITE] = Rank2BB | make_bitboard(SQ_B3, SQ_C3, SQ_F3, SQ_G3);
         v->doubleStepRegion[BLACK] = Rank9BB | make_bitboard(SQ_B8, SQ_C8, SQ_F8, SQ_G8);
         v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(PAWN);
-        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(PAWN) | piece_set(CUSTOM_PIECES);
+        v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(PAWN) | piece_set(CUSTOM_PIECE_1);
         v->castling = false;
         return v;
     }
@@ -1613,7 +1613,7 @@ namespace {
         v->maxRank = RANK_10;
         v->maxFile = FILE_J;
         v->reset_pieces();
-        v->add_piece(CUSTOM_PIECES, 'q', "mQ");
+        v->add_piece(CUSTOM_PIECE_1, 'q', "mQ");
         v->startFen = "3q2q3/10/10/q8q/10/10/Q8Q/10/10/3Q2Q3 w - - 0 1";
         v->stalemateValue = -VALUE_MATE;
         v->arrowGating = true;
index d4e2745..d316779 100644 (file)
@@ -45,7 +45,7 @@ struct Variant {
   bool twoBoards = false;
   int pieceValue[PHASE_NB][PIECE_TYPE_NB] = {};
   std::string customPiece[CUSTOM_PIECES_NB] = {};
-  PieceSet pieceTypes = piece_set(PAWN) | KNIGHT | BISHOP | ROOK | QUEEN | KING;
+  PieceSet pieceTypes = CHESS_PIECES;
   std::string pieceToChar =  " PNBRQ" + std::string(KING - QUEEN - 1, ' ') + "K" + std::string(PIECE_TYPE_NB - KING - 1, ' ')
                            + " pnbrq" + std::string(KING - QUEEN - 1, ' ') + "k" + std::string(PIECE_TYPE_NB - KING - 1, ' ');
   std::string pieceToCharSynonyms = std::string(PIECE_NB, ' ');
@@ -215,29 +215,24 @@ struct Variant {
       if (!doubleStepRegion[WHITE] && !doubleStepRegion[BLACK])
           doubleStep = false;
 
-      fastAttacks = !cambodianMoves && !diagonalLines;
-      for (PieceSet ps = pieceTypes; fastAttacks && ps;)
+      // Determine optimizations
+      bool restrictedMobility = false;
+      for (PieceSet ps = pieceTypes; !restrictedMobility && ps;)
       {
           PieceType pt = pop_lsb(ps);
-          if (!(   pt < FAIRY_PIECES
-                || pt == COMMONER || pt == IMMOBILE_PIECE
-                || pt == ARCHBISHOP || pt == CHANCELLOR
-                || (pt == KING && kingType == KING))
-              || (mobilityRegion[WHITE][pt] || mobilityRegion[BLACK][pt]))
-            fastAttacks = false;
-      }
-      fastAttacks2 = !cambodianMoves && !diagonalLines;
-      for (PieceSet ps = pieceTypes; fastAttacks2 && ps;)
-      {
-          PieceType pt = pop_lsb(ps);
-          if (!(   pt < FAIRY_PIECES
-                || pt == COMMONER || pt == FERS || pt == WAZIR || pt == BREAKTHROUGH_PIECE
-                || pt == SHOGI_PAWN || pt == GOLD || pt == SILVER || pt == SHOGI_KNIGHT
-                || pt == DRAGON || pt == DRAGON_HORSE || pt == LANCE
-                || (pt == KING && kingType == KING))
-              || (mobilityRegion[WHITE][pt] || mobilityRegion[BLACK][pt]))
-            fastAttacks2 = false;
+          if (mobilityRegion[WHITE][pt] || mobilityRegion[BLACK][pt])
+            restrictedMobility = true;
       }
+      fastAttacks =  !(pieceTypes & ~(CHESS_PIECES | COMMON_FAIRY_PIECES))
+                   && kingType == KING
+                   && !restrictedMobility
+                   && !cambodianMoves
+                   && !diagonalLines;
+      fastAttacks2 =  !(pieceTypes & ~(SHOGI_PIECES | COMMON_STEP_PIECES))
+                    && kingType == KING
+                    && !restrictedMobility
+                    && !cambodianMoves
+                    && !diagonalLines;
 
       // Initialize calculated NNUE properties
       nnueKing =  pieceTypes & KING ? KING
@@ -319,13 +314,8 @@ struct Variant {
                     && !blastOnCapture
                     && !capturesToHand
                     && !twoBoards
+                    && !restrictedMobility
                     && kingType == KING;
-      for (PieceSet ps = pieceTypes; endgameEval && ps;)
-      {
-          PieceType pt = pop_lsb(ps);
-          if (mobilityRegion[WHITE][pt] || mobilityRegion[BLACK][pt])
-              endgameEval = false;
-      }
 
       shogiStylePromotions = false;
       for (PieceType current: promotedPieceType)