commit 67c3102f90a864a87055d35c03d2b17f41fa99fd
parent b3231023f2f855d0f1b27d7e834bba800bb6da5a
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Mon, 14 Aug 2023 16:58:21 +0200
Fix performance issue, slight problem with engine...
Diffstat:
9 files changed, 143 insertions(+), 150 deletions(-)
diff --git a/src/board/board.cpp b/src/board/board.cpp
@@ -23,28 +23,16 @@ U64 Board::get_bitboard_occupancy(void) const {
U64 Board::get_bitboard_piece(piece::Type piece) const { return pieces[to_underlying(piece)]; }
-U64 Board::get_bitboard_piece(const piece::Piece &piece) const {
- return get_bitboard_piece(piece.type, piece.color);
-}
-
U64 Board::get_bitboard_piece(piece::Type piece, Color color) const {
return pieces[to_underlying(piece)] & colors[to_underlying(color)];
}
-U64 Board::get_bitboard_piece_attacks(piece::Type piece, Color color, Square square) const {
- return get_bitboard_piece_attacks(piece::get(piece, color), square);
-}
-
-U64 Board::get_bitboard_piece_attacks(const piece::Piece &piece, Square square) const {
- return piece(square, get_bitboard_occupancy());
+U64 Board::get_bitboard_piece_attacks(piece::Type type, Color color, Square from) const {
+ return piece::get_attack(type, color, from, get_bitboard_occupancy());
}
-U64 Board::get_bitboard_piece_moves(piece::Type piece, Color color, Square square) const {
- return get_bitboard_piece_moves(piece::get(piece, color), square);
-}
-
-U64 Board::get_bitboard_piece_moves(const piece::Piece &piece, Square square) const {
- return get_bitboard_piece_attacks(piece, square) & ~get_bitboard_color(piece.color);
+U64 Board::get_bitboard_piece_moves(piece::Type type, Color color, Square square) const {
+ return get_bitboard_piece_attacks(type, color, square) & ~get_bitboard_color(color);
}
Color Board::get_square_piece_color(Square square) const {
@@ -57,7 +45,7 @@ piece::Type Board::get_square_piece_type(Square square) const {
for (piece::Type type : piece::TypeIter()) {
if (bit_get(pieces[to_underlying(type)], to_underlying(square))) return type;
}
- throw std::exception();
+ return piece::Type::NONE;
}
const piece::Piece *Board::get_square_piece(Square square) const {
@@ -93,22 +81,22 @@ void Board::set_bitboard_color(Color color, Square square) {
bit_set(colors[to_underlying(color)], to_underlying(square));
}
-void Board::pop_bitboard_piece(const piece::Piece &piece, Square square) {
- bit_pop(pieces[to_underlying(piece.type)], to_underlying(square));
+void Board::pop_bitboard_piece(piece::Type type, Square square) {
+ bit_pop(pieces[to_underlying(type)], to_underlying(square));
}
-void Board::set_bitboard_piece(const piece::Piece &piece, Square square) {
- bit_set(pieces[to_underlying(piece.type)], to_underlying(square));
+void Board::set_bitboard_piece(piece::Type type, Square square) {
+ bit_set(pieces[to_underlying(type)], to_underlying(square));
}
-void Board::pop_piece(const piece::Piece &piece, Square square) {
- pop_bitboard_color(piece.color, square);
- pop_bitboard_piece(piece, square);
+void Board::pop_piece(piece::Type type, Color side, Square square) {
+ pop_bitboard_color(side, square);
+ pop_bitboard_piece(type, square);
}
-void Board::set_piece(const piece::Piece &piece, Square square) {
- set_bitboard_color(piece.color, square);
- set_bitboard_piece(piece, square);
+void Board::set_piece(piece::Type type, Color side, Square square) {
+ set_bitboard_color(side, square);
+ set_bitboard_piece(type, square);
}
/* Queries */
@@ -121,16 +109,16 @@ bool Board::is_square_attacked(Square square, Color side) const {
Color side_other = (side == Color::BLACK) ? Color::WHITE : Color::BLACK;
for (piece::Type type : piece::TypeIter()) {
- if (get_bitboard_piece_attacks(piece::get(type, side_other), square) &
- get_bitboard_piece(piece::get(type, side)))
+ if (get_bitboard_piece_attacks(type, side_other, square) & get_bitboard_piece(type, side)) {
return 1;
+ }
}
return 0;
}
-bool Board::is_piece_attack_square(const piece::Piece &piece, Square source, Square target) const {
- return get_bitboard_piece_attacks(piece, source) & (C64(1) << to_underlying(target));
+bool Board::is_piece_attack_square(piece::Type type, Color color, Square source, Square target) const {
+ return get_bitboard_piece_attacks(type, color, source) & (C64(1) << to_underlying(target));
}
bool Board::is_check(void) const {
@@ -144,7 +132,8 @@ Board::Board(const std::string &fen) {
int file = 0, rank = 7, i;
for (i = 0; fen[i] != ' '; i++) {
if (isalpha(fen[i])) {
- set_piece(piece::get_from_code(fen[i]), static_cast<Square>(rank * 8 + file));
+ const piece::Piece &piece = piece::get_from_code(fen[i]);
+ set_piece(piece.type, piece.color, static_cast<Square>(rank * 8 + file));
file++;
} else if (isdigit(fen[i])) {
file += fen[i] - '0';
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
@@ -23,7 +23,7 @@ Board board;
TTable ttable(C64(0x400000));
Move pv_table[MAX_PLY][MAX_PLY];
Move killer[2][MAX_PLY];
-U32 history[16][64];
+U32 history[12][64];
int pv_length[MAX_PLY];
bool follow_pv;
U64 nodes;
@@ -31,8 +31,8 @@ U32 ply;
Move move_list_best_move;
U32 inline move_list_score(Move move) {
- const piece::Type type = move.piece().type;
- if (move.is_capture()) return piece::score(type, move.piece_capture().type) + 10000;
+ const piece::Type type = move.piece();
+ if (move.is_capture()) return piece::score(type, move.captured()) + 10000;
if (killer[0][ply] == move) return 9000;
if (killer[1][ply] == move) return 8000;
return history[to_underlying(type)][to_underlying(move.target())];
@@ -268,7 +268,8 @@ int negamax(int alpha, int beta, int depth, bool null) {
if (score > alpha) {
if (!move.is_capture()) {
- history[move.piece().index][to_underlying(move.target())] += depth;
+ int index = piece::get(move.piece(), board.get_side()).index;
+ history[index][to_underlying(move.target())] += depth;
}
alpha = score;
@@ -302,7 +303,7 @@ int negamax(int alpha, int beta, int depth, bool null) {
void move_print_UCI(Move move) {
std::cout << square_to_coordinates(move.source()) << square_to_coordinates(move.target());
- if (move.is_promote()) std::cout << move.piece_promote().code;
+ // if (move.is_promote()) std::cout << move.piece_promote().code;
}
void search_position(int depth) {
@@ -413,7 +414,8 @@ Move parse_move(char *move_string) {
const Move move = list[i];
if (move.source() == source && move.target() == target) {
if (move_string[4]) {
- if (tolower(move.piece_promote().code) != move_string[4]) continue;
+ char code = piece::get(move.promoted(), board.get_side()).code;
+ if (tolower(code) != move_string[4]) continue;
}
return move;
}
diff --git a/src/include/board.hpp b/src/include/board.hpp
@@ -33,12 +33,9 @@ class Board {
U64 get_bitboard_piece(piece::Type piece) const;
U64 get_bitboard_piece(piece::Type piece, Color color) const;
- U64 get_bitboard_piece(const piece::Piece &piece) const;
- U64 get_bitboard_piece_attacks(piece::Type piece, Color color, Square square) const;
- U64 get_bitboard_piece_attacks(const piece::Piece &piece, Square square) const;
- U64 get_bitboard_piece_moves(piece::Type piece, Color color, Square square) const;
- U64 get_bitboard_piece_moves(const piece::Piece &piece, Square square) const;
+ U64 get_bitboard_piece_attacks(piece::Type piece, Color color, Square from) const;
+ U64 get_bitboard_piece_moves(piece::Type piece, Color color, Square from) const;
Color get_square_piece_color(Square square) const;
piece::Type get_square_piece_type(Square square) const;
@@ -54,17 +51,17 @@ class Board {
void pop_bitboard_color(Color color, Square square);
void set_bitboard_color(Color color, Square square);
- void pop_bitboard_piece(const piece::Piece &piece, Square square);
- void set_bitboard_piece(const piece::Piece &piece, Square square);
+ void pop_bitboard_piece(piece::Type type, Square square);
+ void set_bitboard_piece(piece::Type type, Square square);
- void pop_piece(const piece::Piece &piece, Square square);
- void set_piece(const piece::Piece &piece, Square square);
+ void pop_piece(piece::Type type, Color side, Square square);
+ void set_piece(piece::Type type, Color side, Square square);
/* Queries */
bool is_square_attacked(Square Square, Color side) const;
bool is_square_occupied(Square Square) const;
- bool is_piece_attack_square(const piece::Piece &piece, Square source, Square target) const;
+ bool is_piece_attack_square(piece::Type type, Color color, Square source, Square target) const;
bool is_check(void) const;
private:
diff --git a/src/include/move.hpp b/src/include/move.hpp
@@ -11,12 +11,11 @@
struct Move {
Move() = default;
- Move(Square source, Square target, const piece::Piece *piece, const piece::Piece *capture,
- const piece::Piece *promote, bool dbl, bool enpassant, bool castle)
- : source_i(to_underlying(source)), target_i(to_underlying(target)), piece_i(piece->index),
- piece_capture_i(capture ? capture->index : 0), piece_promote_i(promote ? promote->index : 0),
- dbl(dbl), enpassant(enpassant), castle(castle), capture(capture != NULL), promote(promote != NULL) {
- }
+ Move(Square source, Square target, piece::Type piece, piece::Type capture, piece::Type promote, bool dbl,
+ bool enpassant, bool castle)
+ : source_i(to_underlying(source)), target_i(to_underlying(target)), piece_i(to_underlying(piece)),
+ capture_i(to_underlying(capture)), promote_i(to_underlying(promote)), dbl(dbl),
+ enpassant(enpassant), castle(castle) {}
bool operator==(const Move &m) const = default;
@@ -26,32 +25,30 @@ struct Move {
bool is_double(void) const { return dbl; }
bool is_enpassant(void) const { return enpassant; }
bool is_castle(void) const { return castle; }
- bool is_capture(void) const { return capture; }
- bool is_promote(void) const { return promote; }
+ bool is_capture(void) const { return capture_i != to_underlying(piece::Type::NONE); }
+ bool is_promote(void) const { return promote_i != to_underlying(piece::Type::NONE); }
- const piece::Piece &piece(void) const { return piece::get_from_index(piece_i); }
- const piece::Piece &piece_capture(void) const { return piece::get_from_index(piece_capture_i); }
- const piece::Piece &piece_promote(void) const { return piece::get_from_index(piece_promote_i); }
+ const piece::Type piece(void) const { return static_cast<piece::Type>(piece_i); }
+ const piece::Type captured(void) const { return static_cast<piece::Type>(capture_i); }
+ const piece::Type promoted(void) const { return static_cast<piece::Type>(promote_i); }
bool make(Board &board, bool attack_only) const;
friend std::ostream &operator<<(std::ostream &os, Move move);
private:
- inline void piece_remove(Board &board, const piece::Piece &piece, Square square) const;
- inline void piece_set(Board &board, const piece::Piece &piece, Square square) const;
- inline void piece_move(Board &board, const piece::Piece &piece, Square source, Square target) const;
+ inline void piece_remove(Board &board, piece::Type type, Color color, Square square) const;
+ inline void piece_set(Board &board, piece::Type type, Color color, Square square) const;
+ inline void piece_move(Board &board, piece::Type type, Color color, Square source, Square target) const;
unsigned source_i : 6;
unsigned target_i : 6;
- unsigned piece_i : 5;
- unsigned piece_capture_i : 5;
- unsigned piece_promote_i : 5;
+ unsigned piece_i : 3;
+ unsigned capture_i : 3;
+ unsigned promote_i : 3;
bool dbl : 1;
bool enpassant : 1;
bool castle : 1;
- bool capture : 1;
- bool promote : 1;
};
#endif
diff --git a/src/include/piece.hpp b/src/include/piece.hpp
@@ -15,7 +15,7 @@ enum class Type {
ROOK,
QUEEN,
KING,
- TypeSIZE
+ NONE = 7,
};
typedef Iterator<Type, Type::PAWN, Type::KING> TypeIter;
@@ -96,6 +96,12 @@ constexpr const Piece &get(Type type, Color color) {
return table[static_cast<int>(color)][static_cast<int>(type)];
}
+constexpr const U64 get_attack(Type type, Color color, Square from, U64 occupancy) {
+ return get(type, color)(from, occupancy);
+}
+
+constexpr const char get_code(Type type, Color color = Color::WHITE) { return get(type, color).code; }
+constexpr const U64 get_index(Type type, Color color) { return get(type, color).index; }
constexpr const Piece &get_from_code(char code) {
Color color = isupper(code) ? Color::WHITE : Color::BLACK;
diff --git a/src/include/zobrist.hpp b/src/include/zobrist.hpp
@@ -16,8 +16,8 @@ class Zobrist {
static inline constexpr U64 key_side(void) { return keys_side; }
static inline constexpr U64 key_castle(int exp) { return keys_castle[exp]; }
static inline constexpr U64 key_enpassant(Square square) { return keys_enpassant[to_underlying(square)]; }
- static inline constexpr U64 key_piece(const piece::Piece &piece, Square square) {
- return keys_piece[piece.index][to_underlying(square)];
+ static inline constexpr U64 key_piece(piece::Type type, Color color, Square square) {
+ return keys_piece[piece::get_index(type, color)][to_underlying(square)];
}
static inline U64 hash(const Board &board) {
@@ -25,18 +25,14 @@ class Zobrist {
uint8_t square;
for (piece::Type type : piece::TypeIter()) {
- const piece::Piece &piece_white = piece::get(type, Color::WHITE);
- int piece_white_index = piece_white.index;
- U64 bitboard_white = board.get_bitboard_piece(piece_white);
-
+ int piece_white_index = piece::get_index(type, Color::WHITE);
+ U64 bitboard_white = board.get_bitboard_piece(type, Color::WHITE);
bitboard_for_each_bit(square, bitboard_white) {
key_final ^= keys_piece[piece_white_index][square];
}
- const piece::Piece &piece_black = piece::get(type, Color::BLACK);
- int piece_black_index = piece_black.index;
- U64 bitboard_black = board.get_bitboard_piece(piece_black);
-
+ int piece_black_index = piece::get_index(type, Color::BLACK);
+ U64 bitboard_black = board.get_bitboard_piece(type, Color::BLACK);
bitboard_for_each_bit(square, bitboard_black) {
key_final ^= keys_piece[piece_black_index][square];
}
diff --git a/src/move/move.cpp b/src/move/move.cpp
@@ -5,21 +5,23 @@
#include <algorithm>
#include <iomanip>
-void Move::piece_remove(Board &board, const piece::Piece &piece, Square square) const {
- board.pop_piece(piece, square);
- board.xor_hash(Zobrist::key_piece(piece, square));
+void Move::piece_remove(Board &board, piece::Type type, Color color, Square square) const {
+ board.pop_piece(type, color, square);
+ board.xor_hash(Zobrist::key_piece(type, color, square));
}
-void Move::piece_set(Board &board, const piece::Piece &piece, Square square) const {
- board.set_piece(piece, square);
- board.xor_hash(Zobrist::key_piece(piece, square));
+void Move::piece_set(Board &board, piece::Type type, Color color, Square square) const {
+ board.set_piece(type, color, square);
+ board.xor_hash(Zobrist::key_piece(type, color, square));
}
-void Move::piece_move(Board &board, const piece::Piece &piece, Square source, Square target) const {
- piece_remove(board, piece, source);
- piece_set(board, piece, target);
+void Move::piece_move(Board &board, piece::Type type, Color color, Square source, Square target) const {
+ piece_remove(board, type, color, source);
+ piece_set(board, type, color, target);
}
+using piece::Type::ROOK;
+
bool Move::make(Board &board, bool attack_only) const {
static constexpr const int castling_rights[64] = {
// clang-format off
@@ -38,8 +40,8 @@ bool Move::make(Board &board, bool attack_only) const {
if (is_capture()) return make(board, false);
return 0;
} else {
- const piece::Piece &piece = this->piece();
const Color color = board.get_side();
+ Color colorOther = color == Color::BLACK ? Color::WHITE : Color::BLACK;
const Square source = this->source();
const Square target = this->target();
@@ -48,34 +50,32 @@ bool Move::make(Board &board, bool attack_only) const {
if (!is_capture()) {
if (is_promote()) {
- piece_remove(board, piece, source);
- piece_set(board, piece_promote(), target);
+ piece_remove(board, piece(), color, source);
+ piece_set(board, promoted(), color, target);
} else {
- piece_move(board, piece, source, target);
+ piece_move(board, piece(), color, source, target);
}
} else {
if (is_enpassant()) {
- piece_move(board, piece, source, target);
- piece_remove(board, piece_capture(), ntarget);
+ piece_move(board, piece(), color, source, target);
+ piece_remove(board, captured(), colorOther, ntarget);
} else if (is_promote()) {
- piece_remove(board, piece, source);
- piece_remove(board, piece_capture(), target);
- piece_set(board, piece_promote(), target);
+ piece_remove(board, piece(), color, source);
+ piece_remove(board, captured(), colorOther, target);
+ piece_set(board, promoted(), color, target);
} else {
- piece_remove(board, piece_capture(), target);
- piece_move(board, piece, source, target);
+ piece_remove(board, captured(), colorOther, target);
+ piece_move(board, piece(), color, source, target);
}
}
board.set_enpassant(is_double() ? ntarget : Square::no_sq);
if (is_castle()) {
- static constexpr const piece::Piece &rook_white = piece::get(piece::Type::ROOK, Color::WHITE);
- static constexpr const piece::Piece &rook_black = piece::get(piece::Type::ROOK, Color::BLACK);
- if (target == Square::g1) piece_move(board, rook_white, Square::h1, Square::f1);
- if (target == Square::c1) piece_move(board, rook_white, Square::a1, Square::d1);
- if (target == Square::g8) piece_move(board, rook_black, Square::h8, Square::f8);
- if (target == Square::c8) piece_move(board, rook_black, Square::a8, Square::d8);
+ if (target == Square::g1) piece_move(board, ROOK, Color::WHITE, Square::h1, Square::f1);
+ if (target == Square::c1) piece_move(board, ROOK, Color::WHITE, Square::a1, Square::d1);
+ if (target == Square::g8) piece_move(board, ROOK, Color::BLACK, Square::h8, Square::f8);
+ if (target == Square::c8) piece_move(board, ROOK, Color::BLACK, Square::a8, Square::d8);
}
board.xor_hash(Zobrist::key_castle(board.get_castle()));
@@ -94,9 +94,9 @@ bool Move::make(Board &board, bool attack_only) const {
std::ostream &operator<<(std::ostream &os, Move move) {
os << square_to_coordinates(move.source()) << " ";
os << square_to_coordinates(move.target()) << " ";
- os << move.piece().code << " ";
- os << (move.is_capture() ? move.piece_capture().code : '.') << " ";
- os << (move.is_promote() ? move.piece_promote().code : '.') << " ";
+ os << piece::get_code(move.piece()) << " ";
+ os << (move.is_capture() ? piece::get_code(move.captured()) : '.') << " ";
+ os << (move.is_promote() ? piece::get_code(move.promoted()) : '.') << " ";
os << move.is_double() << " ";
os << move.is_enpassant() << " ";
os << move.is_castle();
diff --git a/src/move/movelist.cpp b/src/move/movelist.cpp
@@ -1,4 +1,5 @@
#include "movelist.hpp"
+#include "piece.hpp"
#include <iomanip>
#define pawn_canPromote(color, source) \
@@ -9,6 +10,14 @@
((color == Color::BLACK && source >= Square::a7 && source <= Square::h7) || \
(color == Color::WHITE && source >= Square::a2 && source <= Square::h2))
+using piece::Type::BISHOP;
+using piece::Type::KING;
+using piece::Type::KNIGHT;
+using piece::Type::NONE;
+using piece::Type::PAWN;
+using piece::Type::QUEEN;
+using piece::Type::ROOK;
+
void MoveList::generate(const Board &board) {
this->clear();
@@ -18,104 +27,92 @@ void MoveList::generate(const Board &board) {
Color colorOther = color == Color::BLACK ? Color::WHITE : Color::BLACK;
// pawn moves
- const piece::Piece &pawn = piece::get(piece::Type::PAWN, color);
const int add = (color == Color::WHITE) ? +8 : -8;
- U64 bitboard = board.get_bitboard_piece(pawn);
+ U64 bitboard = board.get_bitboard_piece(PAWN, color);
bitboard_for_each_bit(src_i, bitboard) {
const Square src = static_cast<Square>(src_i);
const Square tgt = static_cast<Square>(tgt_i = src_i + add);
if (!board.is_square_occupied(tgt)) {
if (pawn_canPromote(color, src)) {
- list.push_back(
- Move(src, tgt, &pawn, nullptr, &piece::get(piece::Type::KNIGHT, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, nullptr, &piece::get(piece::Type::BISHOP, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, nullptr, &piece::get(piece::Type::ROOK, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, nullptr, &piece::get(piece::Type::QUEEN, color), 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, KNIGHT, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, BISHOP, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, ROOK, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, QUEEN, 0, 0, 0));
} else {
- list.push_back(Move(src, tgt, &pawn, 0, 0, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, NONE, 0, 0, 0));
// two ahead
const Square tgt = static_cast<Square>(tgt_i + add);
if (pawn_onStart(color, src) && !board.is_square_occupied(tgt))
- list.push_back(Move(src, tgt, &pawn, 0, 0, 1, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, NONE, NONE, 1, 0, 0));
}
}
// capture
- U64 attack = board.get_bitboard_piece_attacks(pawn, src) & board.get_bitboard_color(colorOther);
+ U64 attack =
+ board.get_bitboard_piece_attacks(PAWN, color, src) & board.get_bitboard_color(colorOther);
bitboard_for_each_bit(tgt_i, attack) {
const Square tgt = static_cast<Square>(tgt_i);
- const piece::Piece *capture = board.get_square_piece(tgt);
+ const piece::Type capture = board.get_square_piece_type(tgt);
if (pawn_canPromote(color, src)) {
- list.push_back(
- Move(src, tgt, &pawn, capture, &piece::get(piece::Type::KNIGHT, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, capture, &piece::get(piece::Type::BISHOP, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, capture, &piece::get(piece::Type::ROOK, color), 0, 0, 0));
- list.push_back(
- Move(src, tgt, &pawn, capture, &piece::get(piece::Type::QUEEN, color), 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, capture, KNIGHT, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, capture, BISHOP, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, capture, ROOK, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, capture, QUEEN, 0, 0, 0));
} else {
- list.push_back(Move(src, tgt, &pawn, capture, 0, 0, 0, 0));
+ list.push_back(Move(src, tgt, PAWN, capture, NONE, 0, 0, 0));
}
}
// en passant
const Square enpassant = board.get_enpassant();
- if (enpassant != Square::no_sq && board.is_piece_attack_square(pawn, src, enpassant))
- list.push_back(
- Move(src, enpassant, &pawn, &piece::get(piece::Type::PAWN, colorOther), 0, 0, 1, 0));
+ if (enpassant != Square::no_sq && board.is_piece_attack_square(PAWN, color, src, enpassant))
+ list.push_back(Move(src, enpassant, PAWN, PAWN, NONE, 0, 1, 0));
}
// All piece move
for (const piece::Type type : ++piece::TypeIter()) {
- const piece::Piece &piece = piece::get(type, color);
- U64 bitboard = board.get_bitboard_piece(piece);
+ U64 bitboard = board.get_bitboard_piece(type, color);
bitboard_for_each_bit(src_i, bitboard) {
const Square src = static_cast<Square>(src_i);
- U64 attack = board.get_bitboard_piece_moves(piece, src);
+ U64 attack = board.get_bitboard_piece_moves(type, color, src);
bitboard_for_each_bit(tgt_i, attack) {
const Square tgt = static_cast<Square>(tgt_i);
- list.push_back(Move(src, tgt, &piece, board.get_square_piece(tgt), 0, 0, 0, 0));
+ list.push_back(Move(src, tgt, type, board.get_square_piece_type(tgt), NONE, 0, 0, 0));
}
}
}
// Castling
if (color == Color::WHITE) {
- static const piece::Piece &piece = piece::get(piece::Type::KING, Color::WHITE);
if (!board.is_square_attacked(Square::e1, Color::BLACK)) {
if (board.get_castle() & to_underlying(Board::Castle::WK)) {
if (!board.is_square_occupied(Square::f1) && !board.is_square_occupied(Square::g1) &&
!board.is_square_attacked(Square::f1, Color::BLACK))
- list.push_back(Move(Square::e1, Square::g1, &piece, 0, 0, 0, 0, 1));
+ list.push_back(Move(Square::e1, Square::g1, KING, NONE, NONE, 0, 0, 1));
}
if (board.get_castle() & to_underlying(Board::Castle::WQ)) {
if (!board.is_square_occupied(Square::d1) && !board.is_square_occupied(Square::c1) &&
!board.is_square_occupied(Square::b1) &&
!board.is_square_attacked(Square::d1, Color::BLACK) &&
!board.is_square_attacked(Square::c1, Color::BLACK))
- list.push_back(Move(Square::e1, Square::c1, &piece, 0, 0, 0, 0, 1));
+ list.push_back(Move(Square::e1, Square::c1, KING, NONE, NONE, 0, 0, 1));
}
}
} else {
- static const piece::Piece &piece = piece::get(piece::Type::KING, Color::BLACK);
if (!board.is_square_attacked(Square::e8, Color::WHITE)) {
if (board.get_castle() & to_underlying(Board::Castle::BK)) {
if (!board.is_square_occupied(Square::f8) && !board.is_square_occupied(Square::g8) &&
!board.is_square_attacked(Square::f8, Color::WHITE))
- list.push_back(Move(Square::e8, Square::g8, &piece, 0, 0, 0, 0, 1));
+ list.push_back(Move(Square::e8, Square::g8, KING, NONE, NONE, 0, 0, 1));
}
if (board.get_castle() & to_underlying(Board::Castle::BQ)) {
if (!board.is_square_occupied(Square::d8) && !board.is_square_occupied(Square::c8) &&
!board.is_square_occupied(Square::b8) &&
!board.is_square_attacked(Square::d8, Color::WHITE) &&
!board.is_square_attacked(Square::c8, Color::WHITE))
- list.push_back(Move(Square::e8, Square::c8, &piece, 0, 0, 0, 0, 1));
+ list.push_back(Move(Square::e8, Square::c8, KING, NONE, NONE, 0, 0, 1));
}
}
}
diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp
@@ -17,14 +17,16 @@ class Perft {
typedef std::counting_semaphore<THREAD_MAX> semaphore_t;
Perft(semaphore_t &sem) : sem(sem) {}
void operator()(const Board &board_start, Move move, int depth) {
- sem.acquire();
Board board = board_start;
- if (move.make(board, 0)) {
- if (depth > 1)
- test(board, depth - 1);
- else
- score(board, move);
+ if (!move.make(board, 0)) return;
+ sem.acquire();
+
+ if (depth > 1) {
+ test(board, depth - 1);
+ } else {
+ score(board, move);
}
+
mutex.acquire();
result += local;
mutex.release();
@@ -67,6 +69,13 @@ class Perft {
score(copy, list[i]);
}
}
+
+ void debug(const Board &before, Move move, const Board &after) {
+ std::cout << std::setw(16) << std::hex << before.get_hash() << " ";
+ std::cout << move << " ";
+ std::cout << std::setw(16) << std::hex << after.get_hash() << "\n";
+ }
+
void score(const Board &board, Move move) {
local.node++;
#ifdef USE_FULL_COUNT
@@ -77,7 +86,6 @@ class Perft {
if (move.is_promote()) local.promote++;
#endif
}
-
result_t local;
semaphore_t &sem;
static std::binary_semaphore mutex;
@@ -100,6 +108,7 @@ void perft_test(const char *fen, int depth, int thread_num) {
for (auto &thread : threads)
thread.join();
+ std::cout << std::dec;
std::cout << " Nodes: " << Perft::result.node << "\n";
#ifdef USE_FULL_COUNT
std::cout << " Captures: " << Perft::result.capture << "\n";