From: Fabian Fichter Date: Tue, 2 Apr 2019 19:00:14 +0000 (+0200) Subject: Rewrite definition of piece types X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=bb2e88d2a7eef1a7780e346af89cc82a8cd40a99;p=fairystockfish.git Rewrite definition of piece types No functional change. --- diff --git a/src/Makefile b/src/Makefile index c73379f..942049e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,7 +37,7 @@ PGOBENCH = ./$(EXE) bench ### Object files OBJS = benchmark.o bitbase.o bitboard.o endgame.o evaluate.o main.o \ - material.o misc.o movegen.o movepick.o pawns.o position.o psqt.o \ + material.o misc.o movegen.o movepick.o pawns.o piece.o position.o psqt.o \ search.o thread.o timeman.o tt.o uci.o ucioption.o variant.o syzygy/tbprobe.o ### Establish the operating system name diff --git a/src/bitboard.cpp b/src/bitboard.cpp index e812cb8..ec2edc0 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -23,6 +23,7 @@ #include "bitboard.h" #include "misc.h" +#include "piece.h" uint8_t PopCnt16[1 << 16]; uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; @@ -307,19 +308,19 @@ namespace { #endif #ifdef PRECOMPUTED_MAGICS - void init_magics(Bitboard table[], Magic magics[], Direction directions[], Bitboard magicsInit[]); + void init_magics(Bitboard table[], Magic magics[], std::vector directions, Bitboard magicsInit[]); #else - void init_magics(Bitboard table[], Magic magics[], Direction directions[]); + void init_magics(Bitboard table[], Magic magics[], std::vector directions); #endif - Bitboard sliding_attack(Direction directions[], Square sq, Bitboard occupied, int maxDist = FILE_MAX, Color c = WHITE) { + Bitboard sliding_attack(std::vector 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; @@ -374,8 +375,8 @@ void Bitboards::init() { } // Piece moves - Direction RookDirections[5] = { NORTH, EAST, SOUTH, WEST }; - Direction BishopDirections[5] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }; + std::vector RookDirections = { NORTH, EAST, SOUTH, WEST }; + std::vector BishopDirections = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }; #ifdef PRECOMPUTED_MAGICS init_magics(RookTable, RookMagics, RookDirections, RookMagicInit); @@ -385,206 +386,16 @@ void Bitboards::init() { 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) { @@ -592,9 +403,9 @@ void Bitboards::init() { 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) { @@ -602,9 +413,10 @@ void Bitboards::init() { 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) { @@ -624,9 +436,9 @@ namespace { // 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 directions, Bitboard magicsInit[]) { #else - void init_magics(Bitboard table[], Magic magics[], Direction directions[]) { + void init_magics(Bitboard table[], Magic magics[], std::vector directions) { #endif // Optimal PRNG seeds to pick the correct magics in the shortest time diff --git a/src/main.cpp b/src/main.cpp index 68099dd..f5f7ff7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ #include "thread.h" #include "tt.h" #include "uci.h" +#include "piece.h" #include "variant.h" #include "syzygy/tbprobe.h" @@ -37,6 +38,7 @@ int main(int argc, char* argv[]) { std::cout << engine_info() << std::endl; + pieceMap.init(); variants.init(); UCI::init(Options); PSQT::init(variants.find("chess")->second); @@ -51,5 +53,6 @@ int main(int argc, char* argv[]) { Threads.set(0); variants.clear_all(); + pieceMap.clear_all(); return 0; } diff --git a/src/piece.cpp b/src/piece.cpp new file mode 100644 index 0000000..b510bb0 --- /dev/null +++ b/src/piece.cpp @@ -0,0 +1,246 @@ +/* + 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 . +*/ + +#include + +#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(pt, p)); +} + +void PieceMap::clear_all() { + for (auto const& element : *this) + delete element.second; + clear(); +} diff --git a/src/piece.h b/src/piece.h new file mode 100644 index 0000000..a6404e5 --- /dev/null +++ b/src/piece.h @@ -0,0 +1,47 @@ +/* + 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 . +*/ + +#ifndef PIECE_H_INCLUDED +#define PIECE_H_INCLUDED + +#include +#include + +#include "types.h" + + +/// PieceInfo struct stores information about the piece movements. + +struct PieceInfo { + std::vector stepsQuiet = {}; + std::vector stepsCapture = {}; + std::vector sliderQuiet = {}; + std::vector sliderCapture = {}; + + void merge(const PieceInfo* pi); +}; + +struct PieceMap : public std::map { + void init(); + void add(PieceType pt, const PieceInfo* v); + void clear_all(); +}; + +extern PieceMap pieceMap; + +#endif // #ifndef PIECE_H_INCLUDED