commit efb266c91585d3dcfe9ade481bc13199b9508418
parent d02e946f5b524acd6871c196d4ef505cfa0b5e0a
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Thu, 10 Aug 2023 15:30:42 +0200
Fix almost all of the bugs...
Diffstat:
9 files changed, 48 insertions(+), 88 deletions(-)
diff --git a/src/attacks/attacks.cpp b/src/attacks/attacks.cpp
@@ -48,7 +48,7 @@ U64 attacks_queen_get(Square square, U64 occupancy) {
void attacks_init_leapers(void) {
for (Square square : SquareIter()) {
- uint8_t square_i;
+ uint8_t square_i = to_underlying(square);
pawn_attacks[to_underlying(Color::WHITE)][square_i] =
pawn_mask(Color::WHITE, square);
pawn_attacks[to_underlying(Color::BLACK)][square_i] =
@@ -60,7 +60,7 @@ void attacks_init_leapers(void) {
void attacks_init_sliders(int bishop) {
for (Square square : SquareIter()) {
- uint8_t square_i;
+ uint8_t square_i = to_underlying(square);
U64 attack_mask;
if (bishop) {
diff --git a/src/attacks/internal.cpp b/src/attacks/internal.cpp
@@ -1,4 +1,4 @@
-#include "internal.h"
+#include "internal.hpp"
#include "utils_cpp.hpp"
#include <algorithm> // std::min
diff --git a/src/attacks/internal.h b/src/attacks/internal.h
@@ -1,30 +0,0 @@
-#ifndef STELLAR_ATTAKCS_INTERNAL_H
-#define STELLAR_ATTAKCS_INTERNAL_H
-
-#include "utils_cpp.hpp"
-
-extern U64 king_attacks[64]; // king attack table [square]
-extern U64 knight_attacks[64]; // knight attack table [square]
-extern U64 pawn_attacks[2][64]; // pawn attack table [side][square]
-extern U64 rook_attacks[64][4096]; // rook attack table [square][occupancies]
-extern U64 bishop_attacks[64][512]; // bishop attack table [square][occupancies]
-
-extern U64 rook_masks[64]; // rook attack mask
-extern U64 bishop_masks[64]; // bishop attack mask
-
-extern const int rook_relevant_bits[64];
-extern const int bishop_relevant_bits[64];
-
-int hash(U64 key, U64 magic, int relevant_bits);
-
-U64 set_occupancy(int index, int bits_in_mask, U64 attack_mask);
-
-U64 bishop_mask(Square square);
-U64 bishop_on_the_fly(Square square, U64 block);
-U64 king_mask(Square square);
-U64 knight_mask(Square square);
-U64 pawn_mask(Color side, Square square);
-U64 rook_mask(Square square);
-U64 rook_on_the_fly(Square square, U64 block);
-
-#endif
diff --git a/src/board/board.cpp b/src/board/board.cpp
@@ -121,13 +121,11 @@ bool Board::is_square_occupied(Square square) const {
}
bool Board::is_square_attacked(Square square, Color side) const {
- // side switch because of pawns
Color side_other = (side == Color::BLACK) ? Color::WHITE : Color::BLACK;
for (piece::Type type : piece::TypeIter()) {
- const piece::Piece &piece = piece::get(type, side_other);
- if (get_bitboard_piece_attacks(piece, square) &
- get_bitboard_piece(piece))
+ if (get_bitboard_piece_attacks(piece::get(type, side_other), square) &
+ get_bitboard_piece(piece::get(type, side)))
return 1;
}
@@ -137,19 +135,14 @@ bool Board::is_square_attacked(Square square, Color side) const {
bool Board::is_check(void) const {
U64 king =
pieces[to_underlying(piece::Type::KING)] & colors[to_underlying(side)];
+ Color side_other = (side == Color::BLACK) ? Color::WHITE : Color::BLACK;
Square square = static_cast<Square>(bit_lsb_index(king));
- return is_square_attacked(square, side);
+ return is_square_attacked(square, side_other);
}
Board::Board(const std::string &fen) {
- *this = {0};
-
- side = Color::WHITE;
- enpassant = Square::no_sq;
- castle = 0;
-
int file = 0, rank = 7, i;
- for (i = 0; i < fen.size(); 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));
@@ -181,6 +174,8 @@ Board::Board(const std::string &fen) {
castle |= to_underlying(Castle::BK);
else if (fen[i] == 'q')
castle |= to_underlying(Castle::BQ);
+ else if (fen[i] == '-')
+ break;
else
throw std::exception();
}
@@ -192,13 +187,14 @@ Board::Board(const std::string &fen) {
std::ostream &operator<<(std::ostream &os, const Board &board) {
for (int rank = 0; rank < 8; rank++) {
for (int file = 0; file < 8; file++) {
+ if (!file) os << 8 - rank << " ";
Square square = static_cast<Square>((7 - rank) * 8 + file);
const piece::Piece *piece = board.get_square_piece(square);
os << (piece ? piece->code : '.') << " ";
}
printf("\n");
}
- os << " A B C D E F G H\n";
+ os << " A B C D E F G H\n";
os << " Side: ";
os << ((board.side == Color::WHITE) ? "white" : "black") << "\n";
os << "Enpassant: " << square_to_coordinates(board.enpassant) << "\n";
diff --git a/src/include/board.hpp b/src/include/board.hpp
@@ -69,12 +69,12 @@ class Board {
bool is_check(void) const;
private:
- U64 colors[2];
- U64 pieces[6];
- U64 hash;
- Color side;
- Square enpassant;
- uint8_t castle;
+ U64 colors[2] = {0};
+ U64 pieces[6] = {0};
+ U64 hash = 0;
+ Color side = Color::WHITE;
+ Square enpassant = Square::no_sq;
+ uint8_t castle = 0;
};
const piece::Piece &board_square_piece(const Board *self, Square square,
diff --git a/src/include/piece.hpp b/src/include/piece.hpp
@@ -32,11 +32,10 @@ class Piece {
constexpr Piece(Type type, Color color, char code, const char *symbol,
attack_get_f attacks)
: type(type), color(color), code(code), symbol(symbol),
- attacks(attacks), index(index_calc()) {}
+ attacks(attacks), index(index_calc(color, type)) {}
- constexpr int index_calc() {
- return to_underlying(Type::TypeSIZE) * to_underlying(color) *
- to_underlying(type);
+ constexpr uint8_t index_calc(Color color, Type type) {
+ return to_underlying(color) * 6 + to_underlying(type);
}
};
diff --git a/src/moves/moves_generate.cpp b/src/moves/moves_generate.cpp
@@ -15,19 +15,19 @@
#define pawn_promote(source, target, piece, capture) \
res.push_back( \
- {move_encode(source, target, &piece, 0, \
+ {move_encode(source, target, &piece, capture, \
&piece::get(piece::Type::KNIGHT, color), 0, 0, 0), \
0}); \
res.push_back( \
- {move_encode(source, target, &piece, 0, \
+ {move_encode(source, target, &piece, capture, \
&piece::get(piece::Type::BISHOP, color), 0, 0, 0), \
0}); \
res.push_back( \
- {move_encode(source, target, &piece, 0, \
+ {move_encode(source, target, &piece, capture, \
&piece::get(piece::Type::ROOK, color), 0, 0, 0), \
0}); \
res.push_back( \
- {move_encode(source, target, &piece, 0, \
+ {move_encode(source, target, &piece, capture, \
&piece::get(piece::Type::QUEEN, color), 0, 0, 0), \
0});
@@ -53,22 +53,24 @@ std::vector<MoveE> move_list_generate(const Board &board) {
if (!board.is_square_occupied(tgt)) {
if (pawn_canPromote(color, src)) {
pawn_promote(src_i, tgt_i, piece, nullptr);
- continue;
- }
- res.push_back(
- {move_encode(src_i, tgt_i, &piece, 0, 0, 0, 0, 0), 0});
-
- // two ahead
- if (pawn_onStart(color, src) && !board.is_square_occupied(tgt))
+ } else {
res.push_back(
- {move_encode(src_i, tgt_i + add, &piece, 0, 0, 1, 0, 0),
- 0});
+ {move_encode(src_i, tgt_i, &piece, 0, 0, 0, 0, 0), 0});
+
+ // two ahead
+ Square tgt = static_cast<Square>(tgt_i + add);
+ if (pawn_onStart(color, src) && !board.is_square_occupied(tgt))
+ res.push_back(
+ {move_encode(src_i, tgt_i + add, &piece, 0, 0, 1, 0, 0),
+ 0});
+ }
}
// capture
U64 attack = board.get_bitboard_piece_attacks(piece, src) &
board.get_bitboard_color(colorOther);
bitboard_for_each_bit(tgt_i, attack) {
+ Square tgt = static_cast<Square>(tgt_i);
const piece::Piece *capture = board.get_square_piece(tgt);
if (pawn_canPromote(color, src)) {
pawn_promote(src_i, tgt_i, piece, capture);
@@ -92,11 +94,12 @@ std::vector<MoveE> move_list_generate(const Board &board) {
}
// All piece move
- for (piece::Type type : ++piece::TypeIter()) {
- const piece::Piece &piece = piece::get(type, color);
+ auto type_it = piece::TypeIter().begin();
+ for (++type_it; type_it != type_it.end(); ++type_it) {
+ const piece::Piece &piece = piece::get(*type_it, color);
U64 bitboard = board.get_bitboard_piece(piece);
- Square src = static_cast<Square>(src_i);
bitboard_for_each_bit(src_i, bitboard) {
+ Square src = static_cast<Square>(src_i);
U64 attack = board.get_bitboard_piece_attacks(piece, src) &
~board.get_bitboard_color(color);
bitboard_for_each_bit(tgt_i, attack) {
@@ -111,7 +114,8 @@ std::vector<MoveE> move_list_generate(const Board &board) {
// Castling
if (color == Color::WHITE) {
- const piece::Piece &piece = piece::get(piece::Type::KING, Color::WHITE);
+ static const piece::Piece &piece =
+ piece::get(piece::Type::KING, Color::WHITE);
if (board.get_castle() & to_underlying(Board::Castle::WK)) {
if (!board.is_square_occupied(Square::f1) &&
!board.is_square_occupied(Square::g1) &&
@@ -134,7 +138,8 @@ std::vector<MoveE> move_list_generate(const Board &board) {
0});
}
} else {
- const piece::Piece &piece = piece::get(piece::Type::KING, Color::BLACK);
+ static const piece::Piece &piece =
+ piece::get(piece::Type::KING, Color::BLACK);
if (board.get_castle() & to_underlying(Board::Castle::BK)) {
if (!board.is_square_occupied(Square::f8) &&
!board.is_square_occupied(Square::g8) &&
@@ -158,5 +163,6 @@ std::vector<MoveE> move_list_generate(const Board &board) {
}
}
+ res.resize(res.size());
return res;
}
diff --git a/src/perft/CMakeLists.txt b/src/perft/CMakeLists.txt
@@ -1,10 +1,3 @@
-project(
- perft
- VERSION 1.1.0
- DESCRIPTION "Performance Test"
- LANGUAGES C CXX
-)
-
add_executable(perft perft.cpp)
option(WITH_FULL_COUNT "Make count on types of moves" OFF)
diff --git a/src/perft/perft.cpp b/src/perft/perft.cpp
@@ -14,10 +14,6 @@
// FEN debug positions
#define tricky_position \
"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1 "
-#define killer_position \
- "rnbqkb1r/pp1p1pPp/8/2p1pP2/1P1P4/3P3P/P1P1P3/RNBQKBNR w KQkq e6 0 1"
-#define cmk_position \
- "r2q1rk1/ppp2ppp/2n1bn2/2b1p3/3pP3/3P1NPP/PPP1NPB1/R1BQ1RK1 b - - 0 9 "
void perft_result_print(PerftResult res) {
printf(" - Perft Results -\n\n");
@@ -66,7 +62,7 @@ void perft_driver(Board &board, MoveList *moveList, int depth,
} else {
result->node++;
#ifdef USE_FULL_COUNT
- if (board_isCheck(copy)) result->check++;
+ if (copy.is_check()) result->check++;
if (move_capture(move)) result->capture++;
if (move_enpassant(move)) result->enpassant++;
if (move_castle(move)) result->castle++;
@@ -113,7 +109,7 @@ void *perft_thread(void *arg) {
} else {
result.node++;
#ifdef USE_FULL_COUNT
- if (board_isCheck(copy)) result.check++;
+ if (copy.is_check()) result.check++;
if (move_capture(move)) result.capture++;
if (move_enpassant(move)) result.enpassant++;
if (move_castle(move)) result.castle++;
@@ -145,7 +141,7 @@ PerftResult perft_test(const char *fen, int depth, int thread_num) {
int main(int argc, char *argv[]) {
int c, depth = 1, thread_num = 1;
- std::string s(start_position);
+ std::string s(tricky_position);
const char *fen = s.data();
while ((c = getopt(argc, argv, "t:f:d:")) != -1) {
switch (c) {