stellar

UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE

commit 230f52919827bd8671fd340e5cbcbb753e37140a
parent 60dd166598e91141690a89aebb8af8cdbb6ae8ba
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Tue, 1 Aug 2023 19:50:44 +0200

No more hiding pointers behind typedefs!

Diffstat:
M src/board/board.c | +++++++++++++++++++++++++++++++++ --------------------------------
M src/engine/engine.c | ++++++++++++++++++++++++++++++ ------------------------------
M src/include/board.h | ++++++++++++++++++++++++++++++ ------------------------------
M src/include/moves.h | ++++++++++ ----------
M src/moves/moves.c | +++++++++++++++++++++++++++++++++++++++ -------------------------------------------
M src/perft/perft.c | ++++++ ------

6 files changed, 203 insertions(+), 212 deletions(-)


diff --git a/ src/board/board.c b/ src/board/board.c

@@ -15,97 +15,97 @@ struct Board { eCastle castle; };
Board board_new(void) {
Board p;
Board *board_new(void) {
Board *p;
NEW0(p); return p; }
void board_free(Board *p) { FREE(*p); }
void board_free(Board **p) { FREE(*p); }
void board_copy(Board self, Board dest) { *dest = *self; }
void board_copy(Board *self, Board *dest) { *dest = *self; }
Square board_enpassant(Board self) { return self->enpassant; }
eCastle board_castle(Board self) { return self->castle; }
eColor board_side(Board self) { return self->side; }
U64 board_color(Board self, eColor color) { return self->color[color]; }
U64 board_piece(Board self, ePiece piece) { return self->piece[piece]; }
U64 board_occupancy(Board self) {
Square board_enpassant(const Board *self) { return self->enpassant; }
eCastle board_castle(const Board *self) { return self->castle; }
eColor board_side(const Board *self) { return self->side; }
U64 board_color(const Board *self, eColor color) { return self->color[color]; }
U64 board_piece(const Board *self, ePiece piece) { return self->piece[piece]; }
U64 board_occupancy(const Board *self) {
return self->color[WHITE] | self->color[BLACK]; }
U64 board_pieceBB_get(Board self, ePiece piece, Square target) {
U64 board_piece_get_internal(const Board *self, ePiece piece, Square target) {
return bit_get(self->piece[piece], target); }
U64 board_pieceSet(Board self, Piece piece) {
U64 board_pieceSet(Board *self, Piece piece) {
return self->piece[piece_piece(piece)] & self->color[piece_color(piece)]; }
void board_enpassant_set(Board self, Square target) {
void board_enpassant_set(Board *self, Square target) {
self->enpassant = target; }
void board_color_pop(Board self, eColor color, Square target) {
void board_color_pop(Board *self, eColor color, Square target) {
bit_pop(self->color[color], target); }
void board_color_set(Board self, eColor color, Square target) {
void board_color_set(Board *self, eColor color, Square target) {
bit_set(self->color[color], target); }
U64 board_color_get(Board self, eColor color, Square target) {
U64 board_color_get(const Board *self, eColor color, Square target) {
return bit_get(self->color[color], target); }
int board_piece_get(Board self, Square square) {
int board_piece_get(const Board *self, Square square) {
for (int i = 0; i < 6; i++) if (bit_get(self->piece[i], square)) return i; return -1; }
void board_piece_pop(Board self, Piece piece, Square square) {
void board_piece_pop(Board *self, Piece piece, Square square) {
bit_pop(self->piece[piece_piece(piece)], square); bit_pop(self->color[piece_color(piece)], square); }
void board_piece_set(Board self, Piece piece, Square square) {
void board_piece_set(Board *self, Piece piece, Square square) {
bit_set(self->piece[piece_piece(piece)], square); bit_set(self->color[piece_color(piece)], square); }
void board_piece_move(Board self, Piece Piece, Square source, Square target) {
void board_piece_move(Board *self, Piece Piece, Square source, Square target) {
board_piece_pop(self, Piece, source); board_piece_set(self, Piece, target); }
U64 board_piece_attacks(Board self, Piece piece, Square src) {
U64 board_piece_attacks(Board *self, Piece piece, Square src) {
return piece_attacks(piece)(src, board_occupancy(self)); }
void board_piece_capture(Board self, Piece piece, Piece taken, Square source,
void board_piece_capture(Board *self, Piece piece, Piece taken, Square source,
Square target) { board_piece_pop(self, piece, source); if (taken) board_piece_pop(self, taken, target); board_piece_set(self, piece, target); }
void board_castle_pop(Board self, eCastle castle) {
void board_castle_pop(Board *self, eCastle castle) {
bit_pop(self->castle, bit_lsb_index(castle)); }
void board_castle_and(Board self, int exp) { self->castle &= exp; }
void board_side_switch(Board self) { self->side = !self->side; }
void board_castle_and(Board *self, int exp) { self->castle &= exp; }
void board_side_switch(Board *self) { self->side = !self->side; }
int board_isCheck(Board self) {
int board_isCheck(const Board *self) {
U64 king = self->piece[KING] & self->color[self->side]; return board_square_isAttack(self, bit_lsb_index(king), !self->side); }
int board_square_isOccupied(Board self, Square square) {
int board_square_isOccupied(const Board *self, Square square) {
return bit_get(board_occupancy(self), square); }
int board_square_isAttack(Board self, Square square, eColor side) {
int board_square_isAttack(const Board *self, Square square, eColor side) {
U64 occupancy = self->color[WHITE] | self->color[BLACK]; for (int i = 0; i < 6; i++) {

@@ -117,13 +117,14 @@ int board_square_isAttack(Board self, Square square, eColor side) { return 0; }
Piece board_square_piece(Board self, Square square, eColor color) {
Piece board_square_piece(const Board *self, Square square, eColor color) {
for (ePiece i = 0; i < 6; i++)
if (board_pieceBB_get(self, i, square)) return piece_get(i, color);
if (board_piece_get_internal(self, i, square))
return piece_get(i, color);
return NULL; }
Board board_from_FEN(Board board, const char *fen) {
Board *board_from_FEN(Board *board, const char *fen) {
if (!board) NEW(board); memset(board, 0, sizeof(*board));

@@ -187,7 +188,7 @@ Board board_from_FEN(Board board, const char *fen) { return board; }
void board_print(Board self) {
void board_print(const Board *self) {
for (int rank = 0; rank < 8; rank++) { for (int file = 0; file < 8; file++) { Square square = (7 - rank) * 8 + file;

diff --git a/ src/engine/engine.c b/ src/engine/engine.c

@@ -15,8 +15,8 @@ #define MAX_PLY 64
typedef struct Stats_T *Stats_T;
struct Stats_T {
typedef struct Stats Stats;
struct Stats {
long nodes; int ply; int pv_length[MAX_PLY];

@@ -25,15 +25,15 @@ struct Stats_T { U32 history_moves[16][64]; };
Stats_T Stats_new(void) {
Stats_T p;
Stats *Stats_new(void) {
Stats *p;
NEW0(p); return p; }
void Stats_free(Stats_T *p) { FREE(*p); }
void Stats_free(Stats **p) { FREE(*p); }
int move_score(Stats_T stats, Move move) {
int move_score(Stats *stats, Move move) {
if (move_capture(move)) { return Score_capture(piece_piece(move_piece(move)), piece_piece(move_piece_capture(move)));

@@ -50,7 +50,7 @@ int move_score(Stats_T stats, Move move) { return 0; }
void move_list_sort(Stats_T stats, MoveList list) {
void move_list_sort(Stats *stats, MoveList *list) {
int score[list->count]; for (int i = 0; i < list->count; i++) score[i] = move_score(stats, list->moves[i]);

@@ -70,7 +70,7 @@ void move_list_sort(Stats_T stats, MoveList list) { /* SEARCHING */
int evaluate(Board board) {
int evaluate(Board *board) {
Square square; eColor side = board_side(board); U64 occupancy = board_color(board, side);

@@ -92,9 +92,9 @@ int evaluate(Board board) { return score; }
int quiescence(Stats_T stats, Board board, int alpha, int beta) {
MoveList moves;
Board copy;
int quiescence(Stats *stats, Board *board, int alpha, int beta) {
MoveList *moves;
Board *copy;
int eval = evaluate(board); stats->nodes++;

@@ -136,9 +136,9 @@ int quiescence(Stats_T stats, Board board, int alpha, int beta) { return alpha; }
int negamax(Stats_T stats, Board board, int alpha, int beta, int depth) {
MoveList list;
Board copy;
int negamax(Stats *stats, Board *board, int alpha, int beta, int depth) {
MoveList *list;
Board *copy;
int isCheck = 0; int ply = stats->ply;

@@ -212,8 +212,8 @@ void move_print_UCI(Move move) { if (move_promote(move)) printf(" %c", piece_asci(move_piece_promote(move))); }
void search_position(Board board, int depth) {
Stats_T stats = Stats_new();
void search_position(Board *board, int depth) {
Stats *stats = Stats_new();
for (int crnt = 1; crnt <= depth; crnt++) { int score = negamax(stats, board, -50000, 50000, crnt);

@@ -241,17 +241,17 @@ void print_info(void) { printf("uciok\n"); }
typedef struct Instruction_T *Instruction_T;
struct Instruction_T {
typedef struct Instruction Instruction;
struct Instruction {
char *command; char *token; char *crnt; };
char *Instruction_token_next(Instruction_T self);
char *Instruction_token_next(Instruction *self);
Instruction_T Instruction_new(char *command) {
Instruction_T p;
Instruction *Instruction_new(char *command) {
Instruction *p;
NEW0(p); p->command = ALLOC(strlen(command) + 1); p->token = ALLOC(strlen(command) + 1);

@@ -261,14 +261,14 @@ Instruction_T Instruction_new(char *command) { return p; }
void Instruction_free(Instruction_T *p) {
void Instruction_free(Instruction **p) {
FREE((*p)->command); FREE((*p)->token); FREE(*p); }
char *Instruction_token(Instruction_T self) { return self->token; }
char *Instruction_token_n(Instruction_T self, int n) {
char *Instruction_token(Instruction *self) { return self->token; }
char *Instruction_token_n(Instruction *self, int n) {
while (isspace(*self->crnt) && *self->crnt != '\0') self->crnt++;

@@ -294,13 +294,13 @@ char *Instruction_token_n(Instruction_T self, int n) { return self->token; }
char *Instruction_token_next(Instruction_T self) {
char *Instruction_token_next(Instruction *self) {
return Instruction_token_n(self, 1); }
Move parse_move(Board board, char *move_string) {
Move parse_move(Board *board, char *move_string) {
Move result = {0};
MoveList moves;
MoveList *moves;
Square source, target; source = coordinates_to_square(move_string);

@@ -324,7 +324,7 @@ Move parse_move(Board board, char *move_string) { return result; }
Board Instruction_parse(Instruction_T self, Board board) {
Board *Instruction_parse(Instruction *self, Board *board) {
char *token = Instruction_token(self); if (!board) board = board_new();

@@ -393,8 +393,8 @@ Board Instruction_parse(Instruction_T self, Board board) { } void uci_loop(void) {
Board board = NULL;
Instruction_T instruction;
Board *board = NULL;
Instruction *instruction;
char input[200000]; setbuf(stdin, NULL);

diff --git a/ src/include/board.h b/ src/include/board.h

@@ -11,45 +11,45 @@ enum enumCastle { }; typedef enum enumCastle eCastle;
typedef struct Board *Board;
typedef struct Board Board;
Board board_new(void);
void board_free(Board *p);
void board_copy(Board self, Board dest);
Board *board_new(void);
void board_free(Board **p);
void board_copy(Board *self, Board *dest);
U64 board_color(Board self, eColor color);
U64 board_occupancy(Board self);
U64 board_piece(Board self, ePiece piece);
eCastle board_castle(Board self);
eColor board_side(Board self);
U64 board_color(const Board *self, eColor color);
U64 board_occupancy(const Board *self);
U64 board_piece(const Board *self, ePiece piece);
eCastle board_castle(const Board *self);
eColor board_side(const Board *self);
Square board_enpassant(const Board *self);
Square board_enpassant(Board self);
void board_enpassant_set(Board self, Square target);
void board_enpassant_set(Board *self, Square target);
U64 board_pieceSet(Board self, Piece piece);
U64 board_piece_attacks(Board self, Piece piece, Square src);
void board_piece_capture(Board self, Piece piece, Piece taken, Square source,
U64 board_pieceSet(Board *self, Piece piece);
U64 board_piece_attacks(Board *self, Piece piece, Square src);
void board_piece_capture(Board *self, Piece piece, Piece taken, Square source,
Square target);
void board_piece_move(Board self, Piece Piece, Square square, Square target);
void board_piece_pop(Board self, Piece Piece, Square square);
void board_piece_set(Board self, Piece Piece, Square square);
int board_piece_get(Board self, Square square);
void board_piece_move(Board *self, Piece Piece, Square square, Square target);
void board_piece_pop(Board *self, Piece Piece, Square square);
void board_piece_set(Board *self, Piece Piece, Square square);
int board_piece_get(const Board *self, Square square);
U64 board_color_get(Board self, eColor color, Square target);
void board_color_pop(Board self, eColor color, Square target);
void board_color_set(Board self, eColor color, Square target);
U64 board_color_get(const Board *self, eColor color, Square target);
void board_color_pop(Board *self, eColor color, Square target);
void board_color_set(Board *self, eColor color, Square target);
void board_castle_and(Board self, int exp);
void board_castle_pop(Board self, eCastle castle);
void board_castle_and(Board *self, int exp);
void board_castle_pop(Board *self, eCastle castle);
Piece board_square_piece(Board self, Square square, eColor side);
int board_square_isAttack(Board self, Square square, eColor side);
int board_square_isOccupied(Board self, Square square);
Piece board_square_piece(const Board *self, Square square, eColor side);
int board_square_isAttack(const Board *self, Square square, eColor side);
int board_square_isOccupied(const Board *self, Square square);
Board board_from_FEN(Board board, const char *fen);
int board_isCheck(Board self);
void board_print(Board self);
void board_side_switch(Board self);
Board *board_from_FEN(Board *board, const char *fen);
int board_isCheck(const Board *self);
void board_print(const Board *self);
void board_side_switch(Board *self);
#endif

diff --git a/ src/include/moves.h b/ src/include/moves.h

@@ -20,7 +20,7 @@ struct Move { bool promote : 1; };
typedef struct MoveList *MoveList;
typedef struct MoveList MoveList;
struct MoveList { Move moves[256]; int count;

@@ -30,15 +30,15 @@ int move_cmp(Move a, Move b); Move move_encode(Square src, Square tgt, Piece piece, Piece capture, Piece promote, int dbl, int enpassant, int castle); void move_print(Move move);
MoveList move_list_new(void);
void move_list_free(MoveList *p);
Move move_list_move(MoveList self, int index);
int move_list_size(MoveList self);
void move_list_reset(MoveList self);
void move_list_add(MoveList self, Move move);
void move_list_print(MoveList self);
MoveList move_list_generate(MoveList moves, Board board);
int move_make(Move move, Board board, int flag);
MoveList *move_list_new(void);
void move_list_free(MoveList **p);
Move move_list_move(const MoveList *self, int index);
int move_list_size(const MoveList *self);
void move_list_reset(MoveList *self);
void move_list_add(MoveList *self, Move move);
void move_list_print(const MoveList *self);
MoveList *move_list_generate(MoveList *moves, Board *board);
int move_make(Move move, Board *board, int flag);
#define move_source(move) (move.source) #define move_target(move) (move.target)

diff --git a/ src/moves/moves.c b/ src/moves/moves.c

@@ -36,23 +36,25 @@ void move_print(Move move) { move_promote(move) ? 1 : 0); }
MoveList move_list_new(void) {
MoveList p;
MoveList *move_list_new(void) {
MoveList *p;
NEW0(p); return p; }
void move_list_free(MoveList *p) { FREE(*p); }
void move_list_free(MoveList **p) { FREE(*p); }
Move move_list_move(MoveList self, int index) { return self->moves[index]; }
int move_list_size(MoveList self) { return self->count; }
void move_list_reset(MoveList self) { self->count = 0; }
Move move_list_move(const MoveList *self, int index) {
return self->moves[index];
}
int move_list_size(const MoveList *self) { return self->count; }
void move_list_reset(MoveList *self) { self->count = 0; }
void move_list_add(MoveList self, Move move) {
void move_list_add(MoveList *self, Move move) {
self->moves[self->count++] = move; }
void move_list_print(MoveList self) {
void move_list_print(const MoveList *self) {
printf(" From To Pi Cap Prmt Dbl Enp Cst C P\n"); for (int i = 0; i < self->count; i++) move_print(self->moves[i]);

@@ -74,76 +76,72 @@ void move_list_print(MoveList self) { move_list_add(moves, move); \ }
MoveList move_list_generate(MoveList moves, Board board) {
MoveList *move_list_generate(MoveList *moves, Board *board) {
Move move; Square src, tgt; eColor color = board_side(board); if (!moves) moves = move_list_new();
{ // pawn moves
Piece Piece = piece_get(PAWN, color);
U64 bitboard = board_pieceSet(board, Piece);
bitboard_for_each_bit(src, bitboard) {
{ // quiet
int add = (color == WHITE) ? +8 : -8;
tgt = src + add;
if (!board_square_isOccupied(board, tgt)) {
if (pawn_canPromote(color, src)) {
pawn_promote(src, tgt, Piece, 0);
} else {
move_list_add(
moves, move_encode(src, tgt, Piece, 0, 0, 0, 0, 0));
// pawn moves
Piece piece = piece_get(PAWN, color);
U64 bitboard = board_pieceSet(board, piece);
bitboard_for_each_bit(src, bitboard) {
{ // quiet
int add = (color == WHITE) ? +8 : -8;
tgt = src + add;
if (!board_square_isOccupied(board, tgt)) {
if (pawn_canPromote(color, src)) {
pawn_promote(src, tgt, piece, 0);
} else {
move_list_add(moves,
move_encode(src, tgt, piece, 0, 0, 0, 0, 0));
// two ahead
if (pawn_onStart(color, src) &&
!board_square_isOccupied(board, tgt += add))
move_list_add(moves, move_encode(src, tgt, Piece, 0,
0, 1, 0, 0));
}
// two ahead
if (pawn_onStart(color, src) &&
!board_square_isOccupied(board, tgt += add))
move_list_add(
moves, move_encode(src, tgt, piece, 0, 0, 1, 0, 0));
} }
{ // capture
U64 attack = board_piece_attacks(board, Piece, src) &
board_color(board, !color);
bitboard_for_each_bit(tgt, attack) {
if (pawn_canPromote(color, src)) {
pawn_promote(src, tgt, Piece,
board_square_piece(board, tgt, !color));
} else {
move_list_add(
moves,
move_encode(src, tgt, Piece,
board_square_piece(board, tgt, !color),
0, 0, 0, 0));
}
}
{ // capture
U64 attack = board_piece_attacks(board, piece, src) &
board_color(board, !color);
bitboard_for_each_bit(tgt, attack) {
if (pawn_canPromote(color, src)) {
pawn_promote(src, tgt, piece,
board_square_piece(board, tgt, !color));
} else {
move_list_add(moves, move_encode(src, tgt, piece,
board_square_piece(
board, tgt, !color),
0, 0, 0, 0));
} }
}
{ // en passant
if (board_enpassant(board) != no_sq &&
board_piece_attacks(board, Piece, src) &
(C64(1) << board_enpassant(board)))
move_list_add(
moves,
move_encode(src, board_enpassant(board), Piece,
board_square_piece(board, tgt, !color), 0,
0, 1, 0));
}
{ // en passant
if (board_enpassant(board) != no_sq &&
board_piece_attacks(board, piece, src) &
(C64(1) << board_enpassant(board)))
move_list_add(
moves, move_encode(src, board_enpassant(board), piece,
board_square_piece(board, tgt, !color),
0, 0, 1, 0));
} } // All piece move
for (int piece = 1; piece < 6; piece++) {
Piece Piece = piece_get(piece, color);
U64 bitboard = board_pieceSet(board, Piece);
for (int piece_idx = 1; piece_idx < 6; piece_idx++) {
Piece piece = piece_get(piece_idx, color);
U64 bitboard = board_pieceSet(board, piece);
bitboard_for_each_bit(src, bitboard) {
U64 attack = board_piece_attacks(board, Piece, src) &
U64 attack = board_piece_attacks(board, piece, src) &
~board_color(board, color); bitboard_for_each_bit(tgt, attack) {
/* int take = bit_get(board_colorBB(board, !color), tgt); */
move_list_add(
moves, move_encode(src, tgt, Piece,
moves, move_encode(src, tgt, piece,
board_square_piece(board, tgt, !color), 0, 0, 0, 0)); }

@@ -151,45 +149,39 @@ MoveList move_list_generate(MoveList moves, Board board) { } // Castling
{
if (color == WHITE) {
Piece Piece = piece_get(KING, WHITE);
if (board_castle(board) & WK) {
if (!board_square_isOccupied(board, f1) &&
!board_square_isOccupied(board, g1) &&
!board_square_isAttack(board, e1, BLACK) &&
!board_square_isAttack(board, f1, BLACK))
move_list_add(moves,
move_encode(e1, g1, Piece, 0, 0, 0, 0, 1));
}
if (board_castle(board) & WQ) {
if (!board_square_isOccupied(board, d1) &&
!board_square_isOccupied(board, c1) &&
!board_square_isOccupied(board, b1) &&
!board_square_isAttack(board, e1, BLACK) &&
!board_square_isAttack(board, d1, BLACK))
move_list_add(moves,
move_encode(e1, c1, Piece, 0, 0, 0, 0, 1));
}
} else {
Piece Piece = piece_get(KING, BLACK);
if (board_castle(board) & BK) {
if (!board_square_isOccupied(board, f8) &&
!board_square_isOccupied(board, g8) &&
!board_square_isAttack(board, e8, WHITE) &&
!board_square_isAttack(board, f8, WHITE))
move_list_add(moves,
move_encode(e8, g8, Piece, 0, 0, 0, 0, 1));
}
if (board_castle(board) & BQ) {
if (!board_square_isOccupied(board, d8) &&
!board_square_isOccupied(board, c8) &&
!board_square_isOccupied(board, b8) &&
!board_square_isAttack(board, e8, WHITE) &&
!board_square_isAttack(board, d8, WHITE))
move_list_add(moves,
move_encode(e8, c8, Piece, 0, 0, 0, 0, 1));
}
if (color == WHITE) {
Piece piece = piece_get(KING, WHITE);
if (board_castle(board) & WK) {
if (!board_square_isOccupied(board, f1) &&
!board_square_isOccupied(board, g1) &&
!board_square_isAttack(board, e1, BLACK) &&
!board_square_isAttack(board, f1, BLACK))
move_list_add(moves, move_encode(e1, g1, piece, 0, 0, 0, 0, 1));
}
if (board_castle(board) & WQ) {
if (!board_square_isOccupied(board, d1) &&
!board_square_isOccupied(board, c1) &&
!board_square_isOccupied(board, b1) &&
!board_square_isAttack(board, e1, BLACK) &&
!board_square_isAttack(board, d1, BLACK))
move_list_add(moves, move_encode(e1, c1, piece, 0, 0, 0, 0, 1));
}
} else {
Piece piece = piece_get(KING, BLACK);
if (board_castle(board) & BK) {
if (!board_square_isOccupied(board, f8) &&
!board_square_isOccupied(board, g8) &&
!board_square_isAttack(board, e8, WHITE) &&
!board_square_isAttack(board, f8, WHITE))
move_list_add(moves, move_encode(e8, g8, piece, 0, 0, 0, 0, 1));
}
if (board_castle(board) & BQ) {
if (!board_square_isOccupied(board, d8) &&
!board_square_isOccupied(board, c8) &&
!board_square_isOccupied(board, b8) &&
!board_square_isAttack(board, e8, WHITE) &&
!board_square_isAttack(board, d8, WHITE))
move_list_add(moves, move_encode(e8, c8, piece, 0, 0, 0, 0, 1));
} }

@@ -209,7 +201,7 @@ const int castling_rights[64] = { }; // clang-format on
int move_make(Move move, Board board, int flag) {
int move_make(Move move, Board *board, int flag) {
if (flag == 0) { Square source = move_source(move);

@@ -228,13 +220,11 @@ int move_make(Move move, Board board, int flag) { board_piece_set(board, move_piece_promote(move), target); }
{
int ntarget = target + (color == WHITE ? -8 : +8);
if (move_enpassant(move))
board_piece_pop(board, piece_get(PAWN, !color), ntarget);
int ntarget = target + (color == WHITE ? -8 : +8);
if (move_enpassant(move))
board_piece_pop(board, piece_get(PAWN, !color), ntarget);
board_enpassant_set(board, move_double(move) ? ntarget : no_sq);
}
board_enpassant_set(board, move_double(move) ? ntarget : no_sq);
if (move_castle(move)) { Piece Rook = piece_get(ROOK, board_side(board));

diff --git a/ src/perft/perft.c b/ src/perft/perft.c

@@ -51,10 +51,10 @@ void perft_result_add(PerftResult *base, PerftResult *add) { #endif }
void perft_driver(Board board, struct MoveList *moveList, int depth,
void perft_driver(Board *board, struct MoveList *moveList, int depth,
PerftResult *result) {
MoveList list = move_list_generate(&moveList[depth], board);
Board copy = board_new();
MoveList *list = move_list_generate(&moveList[depth], board);
Board *copy = board_new();
for (int i = 0; i < move_list_size(list); i++) { Move move = move_list_move(list, i);

@@ -82,7 +82,7 @@ void perft_driver(Board board, struct MoveList *moveList, int depth, typedef struct perf_shared perf_shared; struct perf_shared { const char *fen;
MoveList list;
MoveList *list;
int depth; pthread_mutex_t mutex; unsigned int index;

@@ -94,8 +94,8 @@ void *perft_thread(void *arg) { perf_shared *shared = (perf_shared *)arg; struct MoveList moveList[shared->depth + 1];
Board board = board_from_FEN(NULL, shared->fen);
Board copy = board_new();
Board *board = board_from_FEN(NULL, shared->fen);
Board *copy = board_new();
while (1) { pthread_mutex_lock(&shared->mutex);