#include "bitboard.h"
#include "misc.h"
+#include "piece.h"
uint8_t PopCnt16[1 << 16];
uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
#endif
#ifdef PRECOMPUTED_MAGICS
- void init_magics(Bitboard table[], Magic magics[], Direction directions[], Bitboard magicsInit[]);
+ void init_magics(Bitboard table[], Magic magics[], std::vector<Direction> directions, Bitboard magicsInit[]);
#else
- void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
+ void init_magics(Bitboard table[], Magic magics[], std::vector<Direction> directions);
#endif
- Bitboard sliding_attack(Direction directions[], Square sq, Bitboard occupied, int maxDist = FILE_MAX, Color c = WHITE) {
+ Bitboard sliding_attack(std::vector<Direction> directions, Square sq, Bitboard occupied, Color c = WHITE) {
Bitboard attack = 0;
- for (int i = 0; directions[i]; ++i)
- for (Square s = sq + (c == WHITE ? directions[i] : -directions[i]);
- is_ok(s) && distance(s, s - (c == WHITE ? directions[i] : -directions[i])) == 1 && distance(s, sq) <= maxDist;
- s += (c == WHITE ? directions[i] : -directions[i]))
+ for (Direction d : directions)
+ for (Square s = sq + (c == WHITE ? d : -d);
+ is_ok(s) && distance(s, s - (c == WHITE ? d : -d)) == 1;
+ s += (c == WHITE ? d : -d))
{
attack |= s;
}
// Piece moves
- Direction RookDirections[5] = { NORTH, EAST, SOUTH, WEST };
- Direction BishopDirections[5] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
+ std::vector<Direction> RookDirections = { NORTH, EAST, SOUTH, WEST };
+ std::vector<Direction> BishopDirections = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
#ifdef PRECOMPUTED_MAGICS
init_magics(RookTable, RookMagics, RookDirections, RookMagicInit);
init_magics(BishopTable, BishopMagics, BishopDirections);
#endif
- int stepsCapture[][13] = {
- {}, // NO_PIECE_TYPE
- { NORTH_WEST, NORTH_EAST }, // pawn
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
- {}, // bishop
- {}, // rook
- {}, // queen
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
- { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
- {}, // knibis
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // biskni
- { NORTH }, // shogi pawn
- {}, // lance
- { 2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
- { WEST, EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
- { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
- { SOUTH, WEST, EAST, NORTH }, // horse
- { SOUTH, WEST, EAST, NORTH }, // clobber
- { NORTH_WEST, NORTH_EAST }, // breakthrough
- {}, // immobile
- { SOUTH, WEST, EAST, NORTH }, // wazir
- { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
- { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
- };
- int stepsQuiet[][13] = {
- {}, // NO_PIECE_TYPE
- { NORTH }, // pawn
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
- {}, // bishop
- {}, // rook
- {}, // queen
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
- { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
- { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
- { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
- NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knibis
- {}, // biskni
- { NORTH }, // shogi pawn
- {}, // lance
- { 2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
- { WEST, EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
- { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
- { SOUTH, WEST, EAST, NORTH }, // horse
- {}, // clobber
- { NORTH_WEST, NORTH, NORTH_EAST }, // breakthrough
- {}, // immobile
- { SOUTH, WEST, EAST, NORTH }, // wazir
- { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
- { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
- };
- Direction sliderCapture[][9] = {
- {}, // NO_PIECE_TYPE
- {}, // pawn
- {}, // knight
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
- { NORTH, EAST, SOUTH, WEST }, // rook
- { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
- {}, // fers/met
- {}, // alfil
- {}, // silver/khon
- { NORTH, EAST, SOUTH, WEST }, // aiwok
- { NORTH, EAST, SOUTH, WEST }, // bers/dragon
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
- { NORTH, EAST, SOUTH, WEST }, // chancellor
- { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // knibis
- {}, // biskni
- {}, // shogi pawn
- { NORTH }, // lance
- {}, // shogi knight
- {}, // euroshogi knight
- {}, // gold
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
- {}, // clobber
- {}, // breakthrough
- {}, // immobile
- {}, // wazir
- {}, // commoner
- {} // king
- };
- Direction sliderQuiet[][9] = {
- {}, // NO_PIECE_TYPE
- {}, // pawn
- {}, // knight
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
- { NORTH, EAST, SOUTH, WEST }, // rook
- { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
- {}, // fers/met
- {}, // alfil
- {}, // silver/khon
- { NORTH, EAST, SOUTH, WEST }, // aiwok
- { NORTH, EAST, SOUTH, WEST }, // bers/dragon
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
- { NORTH, EAST, SOUTH, WEST }, // chancellor
- { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
- {}, // knibis
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // biskni
- {}, // shogi pawn
- { NORTH }, // lance
- {}, // shogi knight
- {}, // euroshogi knight
- {}, // gold
- { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
- {}, // clobber
- {}, // breakthrough
- {}, // immobile
- {}, // wazir
- {}, // commoner
- {} // king
- };
- int sliderDistCapture[] = {
- 0, // NO_PIECE_TYPE
- 0, // pawn
- 0, // knight
- FILE_MAX, // bishop
- FILE_MAX, // rook
- FILE_MAX, // queen
- 0, // fers/met
- 0, // alfil
- 0, // silver/khon
- FILE_MAX, // aiwok
- FILE_MAX, // bers/dragon
- FILE_MAX, // archbishop
- FILE_MAX, // chancellor
- FILE_MAX, // amazon
- FILE_MAX, // knibis
- 0, // biskni
- 0, // shogi pawn
- FILE_MAX, // lance
- 0, // shogi knight
- 0, // euroshogi knight
- 0, // gold
- FILE_MAX, // horse
- 0, // clobber
- 0, // breakthrough
- 0, // immobile
- 0, // wazir
- 0, // commoner
- 0 // king
- };
- int sliderDistQuiet[] = {
- 0, // NO_PIECE_TYPE
- 0, // pawn
- 0, // knight
- FILE_MAX, // bishop
- FILE_MAX, // rook
- FILE_MAX, // queen
- 0, // fers/met
- 0, // alfil
- 0, // silver/khon
- FILE_MAX, // aiwok
- FILE_MAX, // bers/dragon
- FILE_MAX, // archbishop
- FILE_MAX, // chancellor
- FILE_MAX, // amazon
- 0, // knibis
- FILE_MAX, // biskni
- 0, // shogi pawn
- FILE_MAX, // lance
- 0, // shogi knight
- 0, // euroshogi knight
- 0, // gold
- FILE_MAX, // horse
- 0, // clobber
- 0, // breakthrough
- 0, // immobile
- 0, // wazir
- 0, // commoner
- 0 // king
- };
-
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
+ {
+ const PieceInfo* pi = pieceMap.find(pt)->second;
+
for (Square s = SQ_A1; s <= SQ_MAX; ++s)
{
- for (int i = 0; stepsCapture[pt][i]; ++i)
+ for (Direction d : pi->stepsCapture)
{
- Square to = s + Direction(c == WHITE ? stepsCapture[pt][i] : -stepsCapture[pt][i]);
+ Square to = s + Direction(c == WHITE ? d : -d);
if (is_ok(to) && distance(s, to) < 4)
{
LeaperAttacks[c][pt][s] |= to;
}
}
- for (int i = 0; stepsQuiet[pt][i]; ++i)
+ for (Direction d : pi->stepsQuiet)
{
- Square to = s + Direction(c == WHITE ? stepsQuiet[pt][i] : -stepsQuiet[pt][i]);
+ Square to = s + Direction(c == WHITE ? d : -d);
if (is_ok(to) && distance(s, to) < 4)
{
LeaperMoves[c][pt][s] |= to;
}
}
- PseudoAttacks[c][pt][s] |= sliding_attack(sliderCapture[pt], s, 0, sliderDistCapture[pt], c);
- PseudoMoves[c][pt][s] |= sliding_attack(sliderQuiet[pt], s, 0, sliderDistQuiet[pt], c);
+ PseudoAttacks[c][pt][s] |= sliding_attack(pi->sliderCapture, s, 0, c);
+ PseudoMoves[c][pt][s] |= sliding_attack(pi->sliderQuiet, s, 0, c);
}
+ }
for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
{
// called "fancy" approach.
#ifdef PRECOMPUTED_MAGICS
- void init_magics(Bitboard table[], Magic magics[], Direction directions[], Bitboard magicsInit[]) {
+ void init_magics(Bitboard table[], Magic magics[], std::vector<Direction> directions, Bitboard magicsInit[]) {
#else
- void init_magics(Bitboard table[], Magic magics[], Direction directions[]) {
+ void init_magics(Bitboard table[], Magic magics[], std::vector<Direction> directions) {
#endif
// Optimal PRNG seeds to pick the correct magics in the shortest time
--- /dev/null
+/*
+ Fairy-Stockfish, a UCI chess variant playing engine derived from Stockfish
+ Copyright (C) 2018-2019 Fabian Fichter
+
+ Fairy-Stockfish is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fairy-Stockfish is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string>
+
+#include "types.h"
+#include "piece.h"
+
+PieceMap pieceMap; // Global object
+
+void PieceInfo::merge(const PieceInfo* pi) {
+ stepsQuiet.insert(stepsQuiet.end(), pi->stepsQuiet.begin(), pi->stepsQuiet.end());
+ stepsCapture.insert(stepsCapture.end(), pi->stepsCapture.begin(), pi->stepsCapture.end());
+ sliderQuiet.insert(sliderQuiet.end(), pi->sliderQuiet.begin(), pi->sliderQuiet.end());
+ sliderCapture.insert(sliderCapture.end(), pi->sliderCapture.begin(), pi->sliderCapture.end());
+}
+
+namespace {
+ PieceInfo* pawn_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {NORTH};
+ p->stepsCapture = {NORTH_WEST, NORTH_EAST};
+ return p;
+ }
+ PieceInfo* knight_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST };
+ p->stepsCapture = {2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST };
+ return p;
+ }
+ PieceInfo* bishop_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->sliderQuiet = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
+ p->sliderCapture = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
+ return p;
+ }
+ PieceInfo* rook_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->sliderQuiet = {NORTH, EAST, SOUTH, WEST};
+ p->sliderCapture = {NORTH, EAST, SOUTH, WEST};
+ return p;
+ }
+ PieceInfo* queen_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->sliderQuiet = {NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
+ p->sliderCapture = {NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
+ return p;
+ }
+ PieceInfo* king_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ p->stepsCapture = {SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ return p;
+ }
+ PieceInfo* fers_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST};
+ p->stepsCapture = {SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST};
+ return p;
+ }
+ PieceInfo* wazir_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {SOUTH, WEST, EAST, NORTH};
+ p->stepsCapture = {SOUTH, WEST, EAST, NORTH};
+ return p;
+ }
+ PieceInfo* alfil_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST};
+ p->stepsCapture = {2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST};
+ return p;
+ }
+ PieceInfo* silver_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ p->stepsCapture = {SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ return p;
+ }
+ PieceInfo* aiwok_piece() {
+ PieceInfo* p = rook_piece();
+ PieceInfo* p2 = knight_piece();
+ PieceInfo* p3 = fers_piece();
+ p->merge(p2);
+ p->merge(p3);
+ delete p2;
+ delete p3;
+ return p;
+ }
+ PieceInfo* bers_piece() {
+ PieceInfo* p = rook_piece();
+ PieceInfo* p2 = fers_piece();
+ p->merge(p2);
+ delete p2;
+ return p;
+ }
+ PieceInfo* archbishop_piece() {
+ PieceInfo* p = bishop_piece();
+ PieceInfo* p2 = knight_piece();
+ p->merge(p2);
+ delete p2;
+ return p;
+ }
+ PieceInfo* chancellor_piece() {
+ PieceInfo* p = rook_piece();
+ PieceInfo* p2 = knight_piece();
+ p->merge(p2);
+ delete p2;
+ return p;
+ }
+ PieceInfo* amazon_piece() {
+ PieceInfo* p = queen_piece();
+ PieceInfo* p2 = knight_piece();
+ p->merge(p2);
+ delete p2;
+ return p;
+ }
+ PieceInfo* knibis_piece() {
+ PieceInfo* p = bishop_piece();
+ PieceInfo* p2 = knight_piece();
+ p->merge(p2);
+ delete p2;
+ p->stepsCapture = {};
+ p->sliderQuiet = {};
+ return p;
+ }
+ PieceInfo* biskni_piece() {
+ PieceInfo* p = bishop_piece();
+ PieceInfo* p2 = knight_piece();
+ p->merge(p2);
+ delete p2;
+ p->stepsQuiet = {};
+ p->sliderCapture = {};
+ return p;
+ }
+ PieceInfo* shogi_pawn_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {NORTH};
+ p->stepsCapture = {NORTH};
+ return p;
+ }
+ PieceInfo* lance_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->sliderQuiet = {NORTH};
+ p->sliderCapture = {NORTH};
+ return p;
+ }
+ PieceInfo* shogi_knight_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {2 * NORTH + WEST, 2 * NORTH + EAST};
+ p->stepsCapture = {2 * NORTH + WEST, 2 * NORTH + EAST};
+ return p;
+ }
+ PieceInfo* euroshogi_knight_piece() {
+ PieceInfo* p = shogi_knight_piece();
+ p->stepsQuiet.push_back(WEST);
+ p->stepsQuiet.push_back(EAST);
+ p->stepsCapture.push_back(WEST);
+ p->stepsCapture.push_back(EAST);
+ return p;
+ }
+ PieceInfo* gold_piece() {
+ PieceInfo* p = new PieceInfo();
+ p->stepsQuiet = {SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ p->stepsCapture = {SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST};
+ return p;
+ }
+ PieceInfo* horse_piece() {
+ PieceInfo* p = bishop_piece();
+ PieceInfo* p2 = wazir_piece();
+ p->merge(p2);
+ delete p2;
+ return p;
+ }
+ PieceInfo* clobber_piece() {
+ PieceInfo* p = wazir_piece();
+ p->stepsQuiet = {};
+ return p;
+ }
+ PieceInfo* breakthrough_piece() {
+ PieceInfo* p = pawn_piece();
+ p->stepsQuiet.push_back(NORTH_WEST);
+ p->stepsQuiet.push_back(NORTH_EAST);
+ return p;
+ }
+ PieceInfo* immobile_piece() {
+ PieceInfo* p = new PieceInfo();
+ return p;
+ }
+}
+
+void PieceMap::init() {
+ add(PAWN, pawn_piece());
+ add(KNIGHT, knight_piece());
+ add(BISHOP, bishop_piece());
+ add(ROOK, rook_piece());
+ add(QUEEN, queen_piece());
+ add(FERS, fers_piece());
+ add(ALFIL, alfil_piece());
+ add(SILVER, silver_piece());
+ add(AIWOK, aiwok_piece());
+ add(BERS, bers_piece());
+ add(ARCHBISHOP, archbishop_piece());
+ add(CHANCELLOR, chancellor_piece());
+ add(AMAZON, amazon_piece());
+ add(KNIBIS, knibis_piece());
+ add(BISKNI, biskni_piece());
+ add(SHOGI_PAWN, shogi_pawn_piece());
+ add(LANCE, lance_piece());
+ add(SHOGI_KNIGHT, shogi_knight_piece());
+ add(EUROSHOGI_KNIGHT, euroshogi_knight_piece());
+ add(GOLD, gold_piece());
+ add(HORSE, horse_piece());
+ add(CLOBBER_PIECE, clobber_piece());
+ add(BREAKTHROUGH_PIECE, breakthrough_piece());
+ add(IMMOBILE_PIECE, immobile_piece());
+ add(WAZIR, wazir_piece());
+ add(COMMONER, king_piece());
+ add(KING, king_piece());
+}
+
+void PieceMap::add(PieceType pt, const PieceInfo* p) {
+ insert(std::pair<PieceType, const PieceInfo*>(pt, p));
+}
+
+void PieceMap::clear_all() {
+ for (auto const& element : *this)
+ delete element.second;
+ clear();
+}