stellar

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

commit 227d847754d734b8d663443e463161e4857fac6d
parent 85399aeb3071503a5c6706969eef8c56793be513
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Sat, 29 Jul 2023 19:59:08 +0200

Rename custom types and functions

Diffstat:
Dinclude/CBoard.h | 63---------------------------------------------------------------
Ainclude/board.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/moves.h | 56++++++++++++++++++++++++++++----------------------------
Minclude/perft.h | 6+++---
Minclude/score.h | 2+-
Minclude/utils.h | 19++++++++++++++-----
Dsrc/CBoard.c | 281-------------------------------------------------------------------------------
Asrc/board.c | 280+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/engine.c | 142++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/moves.c | 239++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/perft.c | 68++++++++++++++++++++++++++++++++++----------------------------------
11 files changed, 619 insertions(+), 605 deletions(-)

diff --git a/include/CBoard.h b/include/CBoard.h @@ -1,63 +0,0 @@ -#ifndef CBOARD_H -#define CBOARD_H - -#include "utils.h" - -enum enumCastle { WK = 1, WQ = 2, BK = 4, BQ = 8 }; -typedef enum enumCastle eCastle; - -typedef struct Piece_T *Piece_T; - -char Piece_asci(Piece_T self); -char Piece_code(Piece_T self); -char *Piece_unicode(Piece_T self); -eColor Piece_color(Piece_T self); -ePiece Piece_piece(Piece_T self); -int Piece_index(Piece_T self); - -Piece_T Piece_get(ePiece piece, eColor color); -Piece_T Piece_fromCode(char code); -Piece_T Piece_fromIndex(int index); -ePiece Piece_piece_fromCode(int index); - -typedef struct CBoard_T *CBoard_T; - -CBoard_T CBoard_new(void); -void CBoard_free(CBoard_T *p); -void CBoard_copy(CBoard_T self, CBoard_T dest); - -U64 CBoard_colorBB(CBoard_T self, eColor color); -U64 CBoard_occupancy(CBoard_T self); -U64 CBoard_pieceBB(CBoard_T self, ePiece piece); -eCastle CBoard_castle(CBoard_T self); -eColor CBoard_side(CBoard_T self); - -Square CBoard_enpassant(CBoard_T self); -void CBoard_enpassant_set(CBoard_T self, Square target); - -U64 CBoard_pieceSet(CBoard_T self, Piece_T piece); -U64 CBoard_piece_attacks(CBoard_T self, Piece_T Piece, Square src); -void CBoard_piece_capture(CBoard_T self, Piece_T Piece, Piece_T Taken, Square source, Square target); -void CBoard_piece_move(CBoard_T self, Piece_T Piece, Square square, - Square target); -void CBoard_piece_pop(CBoard_T self, Piece_T Piece, Square square); -void CBoard_piece_set(CBoard_T self, Piece_T Piece, Square square); -int CBoard_piece_get(CBoard_T self, Square square); - -U64 CBoard_colorBB_get(CBoard_T self, eColor color, Square target); -void CBoard_colorBB_pop(CBoard_T self, eColor color, Square target); -void CBoard_colorBB_set(CBoard_T self, eColor color, Square target); - -void CBoard_castle_and(CBoard_T self, int exp); -void CBoard_castle_pop(CBoard_T self, eCastle castle); - -Piece_T CBoard_square_piece(CBoard_T self, Square square, eColor side); -int CBoard_square_isAttack(CBoard_T self, Square square, eColor side); -int CBoard_square_isOccupied(CBoard_T self, Square square); - -CBoard_T CBoard_fromFEN(CBoard_T board, char *fen); -int CBoard_isCheck(CBoard_T self); -void CBoard_print(CBoard_T self); -void CBoard_side_switch(CBoard_T self); - -#endif diff --git a/include/board.h b/include/board.h @@ -0,0 +1,68 @@ +#ifndef CBOARD_H +#define CBOARD_H + +#include "utils.h" + +enum enumCastle { + WK = 1, + WQ = 2, + BK = 4, + BQ = 8 +}; +typedef enum enumCastle eCastle; + +typedef struct Piece *Piece; + +char Piece_asci(Piece self); +char Piece_code(Piece self); +char *Piece_unicode(Piece self); +eColor Piece_color(Piece self); +ePiece Piece_piece(Piece self); +int Piece_index(Piece self); + +Piece Piece_get(ePiece piece, eColor color); +Piece Piece_fromCode(char code); +Piece Piece_fromIndex(int index); +ePiece Piece_piece_fromCode(int index); + +typedef struct Board *Board; + +Board board_new(void); +void board_free(Board *p); +void board_copy(Board self, Board dest); + +U64 board_colorBB(Board self, eColor color); +U64 board_occupancy(Board self); +U64 board_pieceBB(Board self, ePiece piece); +eCastle board_castle(Board self); +eColor board_side(Board self); + +Square board_enpassant(Board self); +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, + 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); + +U64 board_colorBB_get(Board self, eColor color, Square target); +void board_colorBB_pop(Board self, eColor color, Square target); +void board_colorBB_set(Board self, eColor color, Square target); + +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); + +Board board_fromFEN(Board board, char *fen); +int board_isCheck(Board self); +void board_print(Board self); +void board_side_switch(Board self); + +#endif diff --git a/include/moves.h b/include/moves.h @@ -3,7 +3,7 @@ #include <stdint.h> -#include "CBoard.h" +#include "board.h" typedef struct Move Move; struct Move { @@ -19,36 +19,36 @@ struct Move { unsigned promote : 1; }; -typedef struct MoveList_T *MoveList_T; -struct MoveList_T { +typedef struct MoveList *MoveList; +struct MoveList { Move moves[256]; int count; }; -int Move_cmp(Move a, Move b); -Move Move_encode(Square src, Square tgt, Piece_T Piece, Piece_T Capture, - Piece_T Promote, int dbl, int enpassant, int castle); -void Move_print(Move move); -MoveList_T MoveList_new(void); -void MoveList_free(MoveList_T *p); -Move MoveList_move(MoveList_T self, int index); -int MoveList_size(MoveList_T self); -void MoveList_reset(MoveList_T self); -void MoveList_add(MoveList_T self, Move move); -void MoveList_print(MoveList_T self); -MoveList_T MoveList_generate(MoveList_T moves, CBoard_T board); -int Move_make(Move move, CBoard_T board, int flag); - -#define Move_source(move) (move.source) -#define Move_target(move) (move.target) -#define Move_double(move) (move.dbl) -#define Move_enpassant(move) (move.enpassant) -#define Move_castle(move) (move.castle) -#define Move_capture(move) (move.capture) -#define Move_promote(move) (move.promote) - -#define Move_piece(move) (Piece_fromIndex(move.piece)) -#define Move_piece_capture(move) (Piece_fromIndex(move.piece_capture)) -#define Move_piece_promote(move) (Piece_fromIndex(move.piece_promote)) +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); + +#define move_source(move) (move.source) +#define move_target(move) (move.target) +#define move_double(move) (move.dbl) +#define move_enpassant(move) (move.enpassant) +#define move_castle(move) (move.castle) +#define move_capture(move) (move.capture) +#define move_promote(move) (move.promote) + +#define move_piece(move) (Piece_fromIndex(move.piece)) +#define move_piece_capture(move) (Piece_fromIndex(move.piece_capture)) +#define move_piece_promote(move) (Piece_fromIndex(move.piece_promote)) #endif diff --git a/include/perft.h b/include/perft.h @@ -1,9 +1,9 @@ #ifndef PERFT_H #define PERFT_H -#include "CBoard.h" +#include "board.h" -void perft_test_threaded(CBoard_T board, int depth); -void perft_test(CBoard_T board, int depth); +void perft_test_threaded(Board board, int depth); +void perft_test(Board board, int depth); #endif diff --git a/include/score.h b/include/score.h @@ -1,7 +1,7 @@ #ifndef SCORE_H #define SCORE_H -#include "CBoard.h" +#include "board.h" int Score_capture(ePiece src, ePiece tgt); int Score_position(ePiece piece, eColor color, Square square); diff --git a/include/utils.h b/include/utils.h @@ -25,7 +25,7 @@ int bit_count(U64 bitboard); int bit_lsb_index(U64 bitboard); #define bitboard_for_each_bit(var, bb) \ - for (var = bit_lsb_index(bb); bb; bit_pop(bb, var), var = bit_lsb_index(bb)) + for (var = bit_lsb_index(bb); bb; bit_pop(bb, var), var = bit_lsb_index(bb)) void bitboard_print(U64 bitboard); @@ -45,7 +45,7 @@ enum enumSquare { typedef enum enumSquare Square; extern const char *square_to_coordinates[]; -Square coordinates_to_square(char * cord); +Square coordinates_to_square(char *cord); // board moving typedef U64 (*direction_f)(U64); @@ -63,8 +63,18 @@ U64 rotateLeft(U64 x, int s); U64 rotateRight(U64 x, int s); // enum types for color and piece type -enum enumColor { WHITE = 0, BLACK }; -enum enumPiece { PAWN = 0, KNIGHT, BISHOP, ROOK, QUEEN, KING }; +enum enumColor { + WHITE = 0, + BLACK +}; +enum enumPiece { + PAWN = 0, + KNIGHT, + BISHOP, + ROOK, + QUEEN, + KING +}; typedef enum enumColor eColor; typedef enum enumPiece ePiece; @@ -73,5 +83,4 @@ int get_time_ms(void); typedef U64 (*attack_f)(Square square, U64 occupancy); - #endif diff --git a/src/CBoard.c b/src/CBoard.c @@ -1,281 +0,0 @@ -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -#include <cul/assert.h> -#include <cul/mem.h> - -#include "CBoard.h" -#include "attack.h" -#include "utils.h" - -U64 CBoard_pieceBB_get(CBoard_T self, ePiece piece, Square target); - -// PIECE -struct Piece_T { - ePiece piece; - eColor color; - char code; - char asci; - char *unicode; - attack_f attacks; -}; - -// clang-format off -struct Piece_T Pieces[2][6] = { - { - [PAWN] = {.color = WHITE, .code = 'P', .asci = 'P', .unicode = "♙ ", .piece = PAWN, .attacks = get_wpawn_attacks}, -[KNIGHT] = {.color = WHITE, .code = 'N', .asci = 'N', .unicode = "♘ ", .piece = KNIGHT, .attacks = get_knight_attacks}, -[BISHOP] = {.color = WHITE, .code = 'B', .asci = 'B', .unicode = "♗ ", .piece = BISHOP, .attacks = get_bishop_attacks}, - [ROOK] = {.color = WHITE, .code = 'R', .asci = 'R', .unicode = "♖ ", .piece = ROOK, .attacks = get_rook_attacks}, - [QUEEN] = {.color = WHITE, .code = 'Q', .asci = 'Q', .unicode = "♕ ", .piece = QUEEN, .attacks = get_queen_attacks}, - [KING] = {.color = WHITE, .code = 'K', .asci = 'K', .unicode = "♔ ", .piece = KING, .attacks = get_king_attacks}, - }, - { - [PAWN] = {.color = BLACK, .code = 'p', .asci = 'p', .unicode = "♟ ", .piece = PAWN, .attacks = get_bpawn_attacks}, -[KNIGHT] = {.color = BLACK, .code = 'n', .asci = 'n', .unicode = "♞ ", .piece = KNIGHT, .attacks = get_knight_attacks}, -[BISHOP] = {.color = BLACK, .code = 'b', .asci = 'b', .unicode = "♝ ", .piece = BISHOP, .attacks = get_bishop_attacks}, - [ROOK] = {.color = BLACK, .code = 'r', .asci = 'r', .unicode = "♜ ", .piece = ROOK, .attacks = get_rook_attacks}, - [QUEEN] = {.color = BLACK, .code = 'q', .asci = 'q', .unicode = "♛ ", .piece = QUEEN, .attacks = get_queen_attacks}, - [KING] = {.color = BLACK, .code = 'k', .asci = 'k', .unicode = "♚ ", .piece = KING, .attacks = get_king_attacks}, - }, -}; -// clang-format on - -attack_f Piece_attacks(Piece_T self) { return self->attacks; } -char Piece_asci(Piece_T self) { return self->asci; } -char Piece_code(Piece_T self) { return self->code; } -char *Piece_unicode(Piece_T self) { return self->unicode; } -eColor Piece_color(Piece_T self) { return self->color; } -ePiece Piece_piece(Piece_T self) { return self->piece; } -int Piece_index(Piece_T self) { return self->color * 8 + self->piece; } - -Piece_T Piece_fromCode(char code) { - int color = (isupper(code)) ? WHITE : BLACK; - for (int i = 0; i < 6; i++) - if (Pieces[color][i].code == code) return &Pieces[color][i]; - return NULL; -} - -ePiece Piece_piece_fromCode(int index) { - return Pieces[WHITE][index % 8].piece; -} - -Piece_T Piece_fromIndex(int index) { return &Pieces[index / 8][index % 8]; } -Piece_T Piece_get(ePiece piece, eColor color) { return &Pieces[color][piece]; } - -// CBOARD -struct CBoard_T { - U64 colorBB[2]; - U64 pieceBB[6]; - eColor side; - Square enpassant; - eCastle castle; -}; - -CBoard_T CBoard_new(void) { - CBoard_T p; - NEW0(p); - return p; -} - -void CBoard_free(CBoard_T *p) { FREE(*p); } - -void CBoard_copy(CBoard_T self, CBoard_T dest) { *dest = *self; } - -Square CBoard_enpassant(CBoard_T self) { return self->enpassant; } -eCastle CBoard_castle(CBoard_T self) { return self->castle; } -eColor CBoard_side(CBoard_T self) { return self->side; } -U64 CBoard_colorBB(CBoard_T self, eColor color) { return self->colorBB[color]; } -U64 CBoard_pieceBB(CBoard_T self, ePiece piece) { return self->pieceBB[piece]; } -U64 CBoard_occupancy(CBoard_T self) { - return self->colorBB[WHITE] | self->colorBB[BLACK]; -} - -U64 CBoard_pieceBB_get(CBoard_T self, ePiece piece, Square target) { - return bit_get(self->pieceBB[piece], target); -} - -U64 CBoard_pieceSet(CBoard_T self, Piece_T piece) { - return self->pieceBB[Piece_piece(piece)] & - self->colorBB[Piece_color(piece)]; -} - -void CBoard_enpassant_set(CBoard_T self, Square target) { - self->enpassant = target; -} - -void CBoard_colorBB_pop(CBoard_T self, eColor color, Square target) { - bit_pop(self->colorBB[color], target); -} -void CBoard_colorBB_set(CBoard_T self, eColor color, Square target) { - bit_set(self->colorBB[color], target); -} -U64 CBoard_colorBB_get(CBoard_T self, eColor color, Square target) { - return bit_get(self->colorBB[color], target); -} - -int CBoard_piece_get(CBoard_T self, Square square) { - for (int i = 0; i < 6; i++) - if (bit_get(self->pieceBB[i], square)) return i; - return -1; -} - -void CBoard_piece_pop(CBoard_T self, Piece_T Piece, Square square) { - bit_pop(self->pieceBB[Piece->piece], square); - bit_pop(self->colorBB[Piece->color], square); -} - -void CBoard_piece_set(CBoard_T self, Piece_T Piece, Square square) { - bit_set(self->pieceBB[Piece->piece], square); - bit_set(self->colorBB[Piece->color], square); -} - -void CBoard_piece_move(CBoard_T self, Piece_T Piece, Square source, - Square target) { - CBoard_piece_pop(self, Piece, source); - CBoard_piece_set(self, Piece, target); -} - -U64 CBoard_piece_attacks(CBoard_T self, Piece_T Piece, Square src) { - return Piece_attacks(Piece)(src, CBoard_occupancy(self)); -} - -void CBoard_piece_capture(CBoard_T self, Piece_T Piece, Piece_T Taken, - Square source, Square target) { - CBoard_piece_pop(self, Piece, source); - if (Taken) CBoard_piece_pop(self, Taken, target); - CBoard_piece_set(self, Piece, target); -} - -void CBoard_castle_pop(CBoard_T self, eCastle castle) { - bit_pop(self->castle, bit_lsb_index(castle)); -} - -void CBoard_castle_and(CBoard_T self, int exp) { self->castle &= exp; } -void CBoard_side_switch(CBoard_T self) { self->side = !self->side; } - -int CBoard_isCheck(CBoard_T self) { - U64 king = self->pieceBB[KING] & self->colorBB[self->side]; - return CBoard_square_isAttack(self, bit_lsb_index(king), !self->side); -} -int CBoard_square_isOccupied(CBoard_T self, Square square) { - return bit_get(CBoard_occupancy(self), square); -} - -int CBoard_square_isAttack(CBoard_T self, Square square, eColor side) { - U64 occupancy = self->colorBB[WHITE] | self->colorBB[BLACK]; - - for (int i = 0; i < 6; i++) { - if (Pieces[!side][i].attacks(square, occupancy) & self->pieceBB[i] & - self->colorBB[side]) - return 1; - } - - return 0; -} - -Piece_T CBoard_square_piece(CBoard_T self, Square square, eColor color) { - for (ePiece i = 0; i < 6; i++) - if (CBoard_pieceBB_get(self, i, square)) return Piece_get(i, color); - return NULL; -} - -void CBoard_print(CBoard_T self) { - for (int rank = 0; rank < 8; rank++) { - for (int file = 0; file < 8; file++) { - Square square = (7 - rank) * 8 + file; - Piece_T piece = NULL; - - int color = -1; - if (bit_get(self->colorBB[WHITE], square)) - color = WHITE; - else if (bit_get(self->colorBB[BLACK], square)) - color = BLACK; - - if (color != -1) { - for (int piece_index = 0; piece_index < 6; piece_index++) { - if (bit_get(self->pieceBB[piece_index], square)) { - piece = &Pieces[color][piece_index]; - break; - } - } - } - - if (!file) printf(" %d ", 8 - rank); - - printf("%s", (piece) ? Piece_unicode(piece) : ". "); - } - printf("\n"); - } - printf(" A B C D E F G H\n"); - printf(" Side: %s\n", (self->side == WHITE) ? "white" : "black"); - printf("Enpassant: %s\n", square_to_coordinates[self->enpassant]); - printf(" Castling: %c%c%c%c\n", (self->castle & WK) ? 'K' : '-', - (self->castle & WQ) ? 'Q' : '-', (self->castle & BK) ? 'k' : '-', - (self->castle & BQ) ? 'q' : '-'); - printf("\n"); -} - -CBoard_T CBoard_fromFEN(CBoard_T board, char *fen) { - if (!board) NEW(board); - - memset(board, 0, sizeof(*board)); - - board->side = -1; - board->enpassant = no_sq; - board->castle = 0; - - int file = 0, rank = 7; - for (Piece_T piece; *fen != ' '; fen++) { - Square square = rank * 8 + file; - if (isalpha(*fen)) { - if (!(piece = Piece_fromCode(*fen))) assert(0); - bit_set(board->colorBB[piece->color], square); - bit_set(board->pieceBB[piece->piece], square); - file++; - } else if (isdigit(*fen)) { - file += *fen - '0'; - } else if (*fen == '/') { - file = 0; - rank--; - } else - assert(0); - } - - fen++; - if (*fen == 'w') - board->side = WHITE; - else if (*fen == 'b') - board->side = BLACK; - else - assert(0); - - for (fen += 2; *fen != ' '; fen++) { - switch (*fen) { - case 'K': - board->castle |= WK; - break; - case 'Q': - board->castle |= WQ; - break; - case 'k': - board->castle |= BK; - break; - case 'q': - board->castle |= BQ; - break; - case '-': - break; - default: - assert(0); - } - } - - fen++; - if (*fen != '-') { - board->enpassant = coordinates_to_square(fen); - } - - return board; -} diff --git a/src/board.c b/src/board.c @@ -0,0 +1,280 @@ +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include <cul/assert.h> +#include <cul/mem.h> + +#include "attack.h" +#include "board.h" +#include "utils.h" + +U64 board_pieceBB_get(Board self, ePiece piece, Square target); + +// PIECE +struct Piece { + ePiece piece; + eColor color; + char code; + char asci; + char *unicode; + attack_f attacks; +}; + +// clang-format off +struct Piece Pieces[2][6] = { + { + [PAWN] = {.color = WHITE, .code = 'P', .asci = 'P', .unicode = "♙ ", .piece = PAWN, .attacks = get_wpawn_attacks}, +[KNIGHT] = {.color = WHITE, .code = 'N', .asci = 'N', .unicode = "♘ ", .piece = KNIGHT, .attacks = get_knight_attacks}, +[BISHOP] = {.color = WHITE, .code = 'B', .asci = 'B', .unicode = "♗ ", .piece = BISHOP, .attacks = get_bishop_attacks}, + [ROOK] = {.color = WHITE, .code = 'R', .asci = 'R', .unicode = "♖ ", .piece = ROOK, .attacks = get_rook_attacks}, + [QUEEN] = {.color = WHITE, .code = 'Q', .asci = 'Q', .unicode = "♕ ", .piece = QUEEN, .attacks = get_queen_attacks}, + [KING] = {.color = WHITE, .code = 'K', .asci = 'K', .unicode = "♔ ", .piece = KING, .attacks = get_king_attacks}, + }, + { + [PAWN] = {.color = BLACK, .code = 'p', .asci = 'p', .unicode = "♟ ", .piece = PAWN, .attacks = get_bpawn_attacks}, +[KNIGHT] = {.color = BLACK, .code = 'n', .asci = 'n', .unicode = "♞ ", .piece = KNIGHT, .attacks = get_knight_attacks}, +[BISHOP] = {.color = BLACK, .code = 'b', .asci = 'b', .unicode = "♝ ", .piece = BISHOP, .attacks = get_bishop_attacks}, + [ROOK] = {.color = BLACK, .code = 'r', .asci = 'r', .unicode = "♜ ", .piece = ROOK, .attacks = get_rook_attacks}, + [QUEEN] = {.color = BLACK, .code = 'q', .asci = 'q', .unicode = "♛ ", .piece = QUEEN, .attacks = get_queen_attacks}, + [KING] = {.color = BLACK, .code = 'k', .asci = 'k', .unicode = "♚ ", .piece = KING, .attacks = get_king_attacks}, + }, +}; +// clang-format on + +attack_f Piece_attacks(Piece self) { return self->attacks; } +char Piece_asci(Piece self) { return self->asci; } +char Piece_code(Piece self) { return self->code; } +char *Piece_unicode(Piece self) { return self->unicode; } +eColor Piece_color(Piece self) { return self->color; } +ePiece Piece_piece(Piece self) { return self->piece; } +int Piece_index(Piece self) { return self->color * 8 + self->piece; } + +Piece Piece_fromCode(char code) { + int color = (isupper(code)) ? WHITE : BLACK; + for (int i = 0; i < 6; i++) + if (Pieces[color][i].code == code) return &Pieces[color][i]; + return NULL; +} + +ePiece Piece_piece_fromCode(int index) { + return Pieces[WHITE][index % 8].piece; +} + +Piece Piece_fromIndex(int index) { return &Pieces[index / 8][index % 8]; } +Piece Piece_get(ePiece piece, eColor color) { return &Pieces[color][piece]; } + +// CBOARD +struct Board { + U64 colorBB[2]; + U64 pieceBB[6]; + eColor side; + Square enpassant; + eCastle castle; +}; + +Board board_new(void) { + Board p; + NEW0(p); + return p; +} + +void board_free(Board *p) { FREE(*p); } + +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_colorBB(Board self, eColor color) { return self->colorBB[color]; } +U64 board_pieceBB(Board self, ePiece piece) { return self->pieceBB[piece]; } +U64 board_occupancy(Board self) { + return self->colorBB[WHITE] | self->colorBB[BLACK]; +} + +U64 board_pieceBB_get(Board self, ePiece piece, Square target) { + return bit_get(self->pieceBB[piece], target); +} + +U64 board_pieceSet(Board self, Piece piece) { + return self->pieceBB[Piece_piece(piece)] & + self->colorBB[Piece_color(piece)]; +} + +void board_enpassant_set(Board self, Square target) { + self->enpassant = target; +} + +void board_colorBB_pop(Board self, eColor color, Square target) { + bit_pop(self->colorBB[color], target); +} +void board_colorBB_set(Board self, eColor color, Square target) { + bit_set(self->colorBB[color], target); +} +U64 board_colorBB_get(Board self, eColor color, Square target) { + return bit_get(self->colorBB[color], target); +} + +int board_piece_get(Board self, Square square) { + for (int i = 0; i < 6; i++) + if (bit_get(self->pieceBB[i], square)) return i; + return -1; +} + +void board_piece_pop(Board self, Piece Piece, Square square) { + bit_pop(self->pieceBB[Piece->piece], square); + bit_pop(self->colorBB[Piece->color], square); +} + +void board_piece_set(Board self, Piece Piece, Square square) { + bit_set(self->pieceBB[Piece->piece], square); + bit_set(self->colorBB[Piece->color], square); +} + +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) { + return Piece_attacks(Piece)(src, board_occupancy(self)); +} + +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) { + 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; } + +int board_isCheck(Board self) { + U64 king = self->pieceBB[KING] & self->colorBB[self->side]; + return board_square_isAttack(self, bit_lsb_index(king), !self->side); +} +int board_square_isOccupied(Board self, Square square) { + return bit_get(board_occupancy(self), square); +} + +int board_square_isAttack(Board self, Square square, eColor side) { + U64 occupancy = self->colorBB[WHITE] | self->colorBB[BLACK]; + + for (int i = 0; i < 6; i++) { + if (Pieces[!side][i].attacks(square, occupancy) & self->pieceBB[i] & + self->colorBB[side]) + return 1; + } + + return 0; +} + +Piece board_square_piece(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); + return NULL; +} + +void board_print(Board self) { + for (int rank = 0; rank < 8; rank++) { + for (int file = 0; file < 8; file++) { + Square square = (7 - rank) * 8 + file; + Piece piece = NULL; + + int color = -1; + if (bit_get(self->colorBB[WHITE], square)) + color = WHITE; + else if (bit_get(self->colorBB[BLACK], square)) + color = BLACK; + + if (color != -1) { + for (int piece_index = 0; piece_index < 6; piece_index++) { + if (bit_get(self->pieceBB[piece_index], square)) { + piece = &Pieces[color][piece_index]; + break; + } + } + } + + if (!file) printf(" %d ", 8 - rank); + + printf("%s", (piece) ? Piece_unicode(piece) : ". "); + } + printf("\n"); + } + printf(" A B C D E F G H\n"); + printf(" Side: %s\n", (self->side == WHITE) ? "white" : "black"); + printf("Enpassant: %s\n", square_to_coordinates[self->enpassant]); + printf(" Castling: %c%c%c%c\n", (self->castle & WK) ? 'K' : '-', + (self->castle & WQ) ? 'Q' : '-', (self->castle & BK) ? 'k' : '-', + (self->castle & BQ) ? 'q' : '-'); + printf("\n"); +} + +Board board_fromFEN(Board board, char *fen) { + if (!board) NEW(board); + + memset(board, 0, sizeof(*board)); + + board->side = -1; + board->enpassant = no_sq; + board->castle = 0; + + int file = 0, rank = 7; + for (Piece piece; *fen != ' '; fen++) { + Square square = rank * 8 + file; + if (isalpha(*fen)) { + if (!(piece = Piece_fromCode(*fen))) assert(0); + bit_set(board->colorBB[piece->color], square); + bit_set(board->pieceBB[piece->piece], square); + file++; + } else if (isdigit(*fen)) { + file += *fen - '0'; + } else if (*fen == '/') { + file = 0; + rank--; + } else + assert(0); + } + + fen++; + if (*fen == 'w') + board->side = WHITE; + else if (*fen == 'b') + board->side = BLACK; + else + assert(0); + + for (fen += 2; *fen != ' '; fen++) { + switch (*fen) { + case 'K': + board->castle |= WK; + break; + case 'Q': + board->castle |= WQ; + break; + case 'k': + board->castle |= BK; + break; + case 'q': + board->castle |= BQ; + break; + case '-': + break; + default: + assert(0); + } + } + + fen++; + if (*fen != '-') { + board->enpassant = coordinates_to_square(fen); + } + + return board; +} diff --git a/src/engine.c b/src/engine.c @@ -3,7 +3,7 @@ #include <stdlib.h> #include <string.h> -#include "CBoard.h" +#include "board.h" #include "attack.h" #include "moves.h" #include "perft.h" @@ -46,27 +46,27 @@ Stats_T Stats_new(void) { void Stats_free(Stats_T *p) { FREE(*p); } -int Move_score(Stats_T stats, Move move) { - if (Move_capture(move)) { - return Score_capture(Piece_piece(Move_piece(move)), - Piece_piece(Move_piece_capture(move))); +int move_score(Stats_T stats, Move move) { + if (move_capture(move)) { + return Score_capture(Piece_piece(move_piece(move)), + Piece_piece(move_piece_capture(move))); } else { - if (!Move_cmp(stats->killer_moves[0][stats->ply], move)) + if (!move_cmp(stats->killer_moves[0][stats->ply], move)) return 9000; - else if (!Move_cmp(stats->killer_moves[1][stats->ply], move)) + else if (!move_cmp(stats->killer_moves[1][stats->ply], move)) return 8000; else - return stats->history_moves[Piece_index(Move_piece(move))] - [Move_target(move)]; + return stats->history_moves[Piece_index(move_piece(move))] + [move_target(move)]; } return 0; } -void MoveList_sort(Stats_T stats, MoveList_T list) { +void move_list_sort(Stats_T stats, MoveList list) { int score[list->count]; for (int i = 0; i < list->count; i++) - score[i] = Move_score(stats, list->moves[i]); + score[i] = move_score(stats, list->moves[i]); for (int i = 0; i < list->count; i++) for (int j = i + 1; j < list->count; j++) @@ -83,14 +83,14 @@ void MoveList_sort(Stats_T stats, MoveList_T list) { /* SEARCHING */ -int evaluate(CBoard_T board) { +int evaluate(Board board) { Square square; - eColor side = CBoard_side(board); - U64 occupancy = CBoard_colorBB(board, side); + eColor side = board_side(board); + U64 occupancy = board_colorBB(board, side); int score = 0; for (int i = 0; i < 6; i++) { - U64 bitboard = CBoard_pieceBB(board, i); + U64 bitboard = board_pieceBB(board, i); bitboard_for_each_bit(square, bitboard) { if (bit_get(occupancy, square)) { score += Score_value(i); @@ -105,9 +105,9 @@ int evaluate(CBoard_T board) { return score; } -int quiescence(Stats_T stats, CBoard_T board, int alpha, int beta) { - MoveList_T moves; - CBoard_T copy; +int quiescence(Stats_T stats, Board board, int alpha, int beta) { + MoveList moves; + Board copy; int eval = evaluate(board); stats->nodes++; @@ -120,22 +120,22 @@ int quiescence(Stats_T stats, CBoard_T board, int alpha, int beta) { alpha = eval; } - copy = CBoard_new(); - moves = MoveList_generate(NULL, board); - MoveList_sort(stats, moves); + copy = board_new(); + moves = move_list_generate(NULL, board); + move_list_sort(stats, moves); - for (int i = 0; i < MoveList_size(moves); i++) { - CBoard_copy(board, copy); + for (int i = 0; i < move_list_size(moves); i++) { + board_copy(board, copy); - if (Move_make(MoveList_move(moves, i), copy, 1) == 0) continue; + if (move_make(move_list_move(moves, i), copy, 1) == 0) continue; stats->ply++; int score = -quiescence(stats, copy, -beta, -alpha); stats->ply--; if (score >= beta) { - MoveList_free(&moves); - CBoard_free(&copy); + move_list_free(&moves); + board_free(&copy); return beta; } @@ -144,14 +144,14 @@ int quiescence(Stats_T stats, CBoard_T board, int alpha, int beta) { } } - MoveList_free(&moves); - CBoard_free(&copy); + move_list_free(&moves); + board_free(&copy); return alpha; } -int negamax(Stats_T stats, CBoard_T board, int alpha, int beta, int depth) { - MoveList_T list; - CBoard_T copy; +int negamax(Stats_T stats, Board board, int alpha, int beta, int depth) { + MoveList list; + Board copy; int isCheck = 0; int ply = stats->ply; @@ -163,19 +163,19 @@ int negamax(Stats_T stats, CBoard_T board, int alpha, int beta, int depth) { stats->nodes++; - copy = CBoard_new(); - list = MoveList_generate(NULL, board); - isCheck = CBoard_isCheck(board); + copy = board_new(); + list = move_list_generate(NULL, board); + isCheck = board_isCheck(board); if (isCheck) depth++; int legal_moves = 0; - MoveList_sort(stats, list); - for (int i = 0; i < MoveList_size(list); i++) { - Move move = MoveList_move(list, i); + move_list_sort(stats, list); + for (int i = 0; i < move_list_size(list); i++) { + Move move = move_list_move(list, i); - CBoard_copy(board, copy); - if (Move_make(move, copy, 0) == 0) { + board_copy(board, copy); + if (move_make(move, copy, 0) == 0) { continue; } @@ -185,19 +185,19 @@ int negamax(Stats_T stats, CBoard_T board, int alpha, int beta, int depth) { legal_moves++; if (score >= beta) { - if (!Move_capture(move)) { + if (!move_capture(move)) { stats->killer_moves[1][ply] = stats->killer_moves[0][ply]; stats->killer_moves[0][ply] = move; } - MoveList_free(&list); - CBoard_free(&copy); + move_list_free(&list); + board_free(&copy); return beta; } if (score > alpha) { - if (!Move_capture(move)) - stats->history_moves[Piece_index(Move_piece(move))] - [Move_target(move)] += depth; + if (!move_capture(move)) + stats->history_moves[Piece_index(move_piece(move))] + [move_target(move)] += depth; alpha = score; stats->pv_table[ply][ply] = move; @@ -214,18 +214,18 @@ int negamax(Stats_T stats, CBoard_T board, int alpha, int beta, int depth) { return 0; } - MoveList_free(&list); - CBoard_free(&copy); + move_list_free(&list); + board_free(&copy); return alpha; } -void Move_print_UCI(Move move) { - printf("%s%s", square_to_coordinates[Move_source(move)], - square_to_coordinates[Move_target(move)]); - if (Move_promote(move)) printf(" %c", Piece_asci(Move_piece_promote(move))); +void move_print_UCI(Move move) { + printf("%s%s", square_to_coordinates[move_source(move)], + square_to_coordinates[move_target(move)]); + if (move_promote(move)) printf(" %c", Piece_asci(move_piece_promote(move))); } -void search_position(CBoard_T board, int depth) { +void search_position(Board board, int depth) { Stats_T stats = Stats_new(); for (int crnt = 1; crnt <= depth; crnt++) { @@ -235,14 +235,14 @@ void search_position(CBoard_T board, int depth) { stats->nodes); for (int i = 0; i < stats->pv_length[0]; i++) { - Move_print_UCI(stats->pv_table[0][i]); + move_print_UCI(stats->pv_table[0][i]); printf(" "); } printf("\n"); } printf("bestmove "); - Move_print_UCI(stats->pv_table[0][0]); + move_print_UCI(stats->pv_table[0][0]); printf("\n"); Stats_free(&stats); @@ -311,20 +311,20 @@ char *Instruction_token_next(Instruction_T self) { return Instruction_token_n(self, 1); } -Move parse_move(CBoard_T board, char *move_string) { +Move parse_move(Board board, char *move_string) { Move result = {0}; - MoveList_T moves; + MoveList moves; Square source, target; source = coordinates_to_square(move_string); target = coordinates_to_square(move_string + 2); - moves = MoveList_generate(NULL, board); + moves = move_list_generate(NULL, board); for (int i = 0; i < moves->count; i++) { Move move = moves->moves[i]; - if (Move_source(move) == source && Move_target(move) == target) { + if (move_source(move) == source && move_target(move) == target) { if (move_string[4]) { - if (tolower(Piece_code(Move_piece_promote(move))) != + if (tolower(Piece_code(move_piece_promote(move))) != move_string[4]) continue; } @@ -333,18 +333,18 @@ Move parse_move(CBoard_T board, char *move_string) { } } - MoveList_free(&moves); + move_list_free(&moves); return result; } -CBoard_T Instruction_parse(Instruction_T self, CBoard_T board) { +Board Instruction_parse(Instruction_T self, Board board) { char *token = Instruction_token(self); - if (!board) board = CBoard_new(); + if (!board) board = board_new(); do { if (strcmp(token, "ucinewgame") == 0) { - board = CBoard_fromFEN(board, start_position); + board = board_fromFEN(board, start_position); continue; } @@ -353,27 +353,27 @@ CBoard_T Instruction_parse(Instruction_T self, CBoard_T board) { if (strcmp(token, "position") == 0) { token = Instruction_token_next(self); if (token && strcmp(token, "startpos") == 0) { - board = CBoard_fromFEN(board, start_position); + board = board_fromFEN(board, start_position); } else if (token && strcmp(token, "fen") == 0) { token = Instruction_token_n(self, 6); - board = CBoard_fromFEN(board, token); + board = board_fromFEN(board, token); } else { printf("Unknown argument after position\n"); } - // CBoard_print(board); + // board_print(board); continue; } if (strcmp(token, "moves") == 0) { while ((token = Instruction_token_next(self))) { Move move = parse_move(board, token); - if (!Move_cmp(move, (Move){0})) { - Move_make(move, board, 0); + if (!move_cmp(move, (Move){0})) { + move_make(move, board, 0); } else { printf("Invalid move %s!\n", token); } } - // CBoard_print(board); + // board_print(board); return board; } @@ -406,7 +406,7 @@ CBoard_T Instruction_parse(Instruction_T self, CBoard_T board) { } void uci_loop(void) { - CBoard_T board = NULL; + Board board = NULL; Instruction_T instruction; char input[200000]; @@ -425,7 +425,7 @@ void uci_loop(void) { } Instruction_free(&instruction); - CBoard_free(&board); + board_free(&board); } /* MAIN */ diff --git a/src/moves.c b/src/moves.c @@ -5,56 +5,56 @@ #include "moves.h" -int Move_cmp(Move a, Move b) { return *(uint32_t *)&a == *(uint32_t *)&b; } +int move_cmp(Move a, Move b) { return *(uint32_t *)&a == *(uint32_t *)&b; } -Move Move_encode(Square src, Square tgt, Piece_T Piece, Piece_T Capture, - Piece_T Promote, int dbl, int enpassant, int castle) { +Move move_encode(Square src, Square tgt, Piece piece, Piece capture, + Piece promote, int dbl, int enpassant, int castle) { return (Move){ .source = src, .target = tgt, .dbl = dbl, .enpassant = enpassant, .castle = castle, - .capture = Capture != NULL, - .promote = Promote != NULL, - .piece = Piece_index(Piece), - .piece_capture = Capture ? Piece_index(Capture) : 0, - .piece_promote = Promote ? Piece_index(Promote) : 0, + .capture = capture != NULL, + .promote = promote != NULL, + .piece = Piece_index(piece), + .piece_capture = capture ? Piece_index(capture) : 0, + .piece_promote = promote ? Piece_index(promote) : 0, }; } -void Move_print(Move move) { +void move_print(Move move) { printf("%5s %5s %2s %2s %2s %4d %4d %4d %4d %4d\n", - square_to_coordinates[Move_source(move)], - square_to_coordinates[Move_target(move)], - Piece_unicode(Move_piece(move)), - Move_capture(move) ? Piece_unicode(Move_piece_capture(move)) : "X ", - Move_promote(move) ? Piece_unicode(Move_piece_promote(move)) : "X ", - Move_double(move) ? 1 : 0, Move_enpassant(move) ? 1 : 0, - Move_castle(move) ? 1 : 0, Move_capture(move) ? 1 : 0, - Move_promote(move) ? 1 : 0); + square_to_coordinates[move_source(move)], + square_to_coordinates[move_target(move)], + Piece_unicode(move_piece(move)), + move_capture(move) ? Piece_unicode(move_piece_capture(move)) : "X ", + move_promote(move) ? Piece_unicode(move_piece_promote(move)) : "X ", + move_double(move) ? 1 : 0, move_enpassant(move) ? 1 : 0, + move_castle(move) ? 1 : 0, move_capture(move) ? 1 : 0, + move_promote(move) ? 1 : 0); } -MoveList_T MoveList_new(void) { - MoveList_T p; +MoveList move_list_new(void) { + MoveList p; NEW0(p); return p; } -void MoveList_free(MoveList_T *p) { FREE(*p); } +void move_list_free(MoveList *p) { FREE(*p); } -Move MoveList_move(MoveList_T self, int index) { return self->moves[index]; } -int MoveList_size(MoveList_T self) { return self->count; } -void MoveList_reset(MoveList_T self) { self->count = 0; } +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; } -void MoveList_add(MoveList_T self, Move move) { +void move_list_add(MoveList self, Move move) { self->moves[self->count++] = move; } -void MoveList_print(MoveList_T self) { +void move_list_print(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]); + move_print(self->moves[i]); printf("Total: %d\n", self->count); } @@ -68,65 +68,66 @@ void MoveList_print(MoveList_T self) { #define pawn_promote(source, target, Piece, Capture) \ for (int i = 1; i < 5; i++) { \ - move = Move_encode(source, target, Piece, Capture, \ + move = move_encode(source, target, Piece, Capture, \ Piece_get(i, color), 0, 0, 0); \ - MoveList_add(moves, move); \ + move_list_add(moves, move); \ } -MoveList_T MoveList_generate(MoveList_T moves, CBoard_T board) { +MoveList move_list_generate(MoveList moves, Board board) { Move move; Square src, tgt; - eColor color = CBoard_side(board); + eColor color = board_side(board); - if (!moves) moves = MoveList_new(); + if (!moves) moves = move_list_new(); { // pawn moves - Piece_T Piece = Piece_get(PAWN, color); - U64 bitboard = CBoard_pieceSet(board, Piece); + 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 (tgt > a1 && tgt < h8 && - !CBoard_square_isOccupied(board, tgt)) { + !board_square_isOccupied(board, tgt)) { if (pawn_canPromote(color, src)) { pawn_promote(src, tgt, Piece, 0); } else { - MoveList_add( - moves, Move_encode(src, tgt, Piece, 0, 0, 0, 0, 0)); + move_list_add( + moves, move_encode(src, tgt, Piece, 0, 0, 0, 0, 0)); // two ahead if (pawn_onStart(color, src) && - !CBoard_square_isOccupied(board, tgt += add)) - MoveList_add(moves, Move_encode(src, tgt, Piece, 0, - 0, 1, 0, 0)); + !board_square_isOccupied(board, tgt += add)) + move_list_add(moves, move_encode(src, tgt, Piece, 0, + 0, 1, 0, 0)); } } } { // capture - U64 attack = CBoard_piece_attacks(board, Piece, src) & - CBoard_colorBB(board, !color); + U64 attack = board_piece_attacks(board, Piece, src) & + board_colorBB(board, !color); bitboard_for_each_bit(tgt, attack) { if (pawn_canPromote(color, src)) { pawn_promote(src, tgt, Piece, - CBoard_square_piece(board, tgt, !color)); + board_square_piece(board, tgt, !color)); } else { - MoveList_add(moves, Move_encode(src, tgt, Piece, - CBoard_square_piece( - board, tgt, !color), - 0, 0, 0, 0)); + move_list_add( + moves, + move_encode(src, tgt, Piece, + board_square_piece(board, tgt, !color), + 0, 0, 0, 0)); } } } { // en passant - if (CBoard_enpassant(board) != no_sq && - CBoard_piece_attacks(board, Piece, src) & - (C64(1) << CBoard_enpassant(board))) - MoveList_add( + if (board_enpassant(board) != no_sq && + board_piece_attacks(board, Piece, src) & + (C64(1) << board_enpassant(board))) + move_list_add( moves, - Move_encode(src, CBoard_enpassant(board), Piece, - CBoard_square_piece(board, tgt, !color), 0, + move_encode(src, board_enpassant(board), Piece, + board_square_piece(board, tgt, !color), 0, 0, 1, 0)); } } @@ -134,16 +135,16 @@ MoveList_T MoveList_generate(MoveList_T moves, CBoard_T board) { // All piece move for (int piece = 1; piece < 6; piece++) { - Piece_T Piece = Piece_get(piece, color); - U64 bitboard = CBoard_pieceSet(board, Piece); + Piece Piece = Piece_get(piece, color); + U64 bitboard = board_pieceSet(board, Piece); bitboard_for_each_bit(src, bitboard) { - U64 attack = CBoard_piece_attacks(board, Piece, src) & - ~CBoard_colorBB(board, color); + U64 attack = board_piece_attacks(board, Piece, src) & + ~board_colorBB(board, color); bitboard_for_each_bit(tgt, attack) { - /* int take = bit_get(CBoard_colorBB(board, !color), tgt); */ - MoveList_add( - moves, Move_encode(src, tgt, Piece, - CBoard_square_piece(board, tgt, !color), + /* int take = bit_get(board_colorBB(board, !color), tgt); */ + move_list_add( + moves, move_encode(src, tgt, Piece, + board_square_piece(board, tgt, !color), 0, 0, 0, 0)); } } @@ -152,42 +153,42 @@ MoveList_T MoveList_generate(MoveList_T moves, CBoard_T board) { // Castling { if (color == WHITE) { - Piece_T Piece = Piece_get(KING, WHITE); - if (CBoard_castle(board) & WK) { - if (!CBoard_square_isOccupied(board, f1) && - !CBoard_square_isOccupied(board, g1) && - !CBoard_square_isAttack(board, e1, BLACK) && - !CBoard_square_isAttack(board, f1, BLACK)) - MoveList_add(moves, - Move_encode(e1, g1, Piece, 0, 0, 0, 0, 1)); + 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 (CBoard_castle(board) & WQ) { - if (!CBoard_square_isOccupied(board, d1) && - !CBoard_square_isOccupied(board, c1) && - !CBoard_square_isOccupied(board, b1) && - !CBoard_square_isAttack(board, e1, BLACK) && - !CBoard_square_isAttack(board, d1, BLACK)) - MoveList_add(moves, - Move_encode(e1, c1, 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_T Piece = Piece_get(KING, BLACK); - if (CBoard_castle(board) & BK) { - if (!CBoard_square_isOccupied(board, f8) && - !CBoard_square_isOccupied(board, g8) && - !CBoard_square_isAttack(board, e8, WHITE) && - !CBoard_square_isAttack(board, f8, WHITE)) - MoveList_add(moves, - Move_encode(e8, g8, Piece, 0, 0, 0, 0, 1)); + 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 (CBoard_castle(board) & BQ) { - if (!CBoard_square_isOccupied(board, d8) && - !CBoard_square_isOccupied(board, c8) && - !CBoard_square_isOccupied(board, b8) && - !CBoard_square_isAttack(board, e8, WHITE) && - !CBoard_square_isAttack(board, d8, WHITE)) - MoveList_add(moves, - Move_encode(e8, c8, 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)); } } } @@ -208,64 +209,64 @@ const int castling_rights[64] = { }; // clang-format on -int Move_make(Move move, CBoard_T board, int flag) { +int move_make(Move move, Board board, int flag) { if (flag == 0) { - Square source = Move_source(move); - Square target = Move_target(move); - Piece_T Piece = Move_piece(move); - eColor color = CBoard_side(board); + Square source = move_source(move); + Square target = move_target(move); + Piece piece = move_piece(move); + eColor color = board_side(board); - if (!Move_capture(move)) - CBoard_piece_move(board, Piece, source, target); + if (!move_capture(move)) + board_piece_move(board, piece, source, target); else - CBoard_piece_capture(board, Piece, Move_piece_capture(move), source, - target); + board_piece_capture(board, piece, move_piece_capture(move), source, + target); - if (Move_promote(move)) { - CBoard_piece_pop(board, Piece, target); - CBoard_piece_set(board, Move_piece_promote(move), target); + if (move_promote(move)) { + board_piece_pop(board, piece, target); + board_piece_set(board, move_piece_promote(move), target); } { int ntarget = target + (color == WHITE ? -8 : +8); - if (Move_enpassant(move)) - CBoard_piece_pop(board, Piece_get(PAWN, !color), ntarget); + if (move_enpassant(move)) + board_piece_pop(board, Piece_get(PAWN, !color), ntarget); - CBoard_enpassant_set(board, Move_double(move) ? ntarget : no_sq); + board_enpassant_set(board, move_double(move) ? ntarget : no_sq); } - if (Move_castle(move)) { - Piece_T Rook = Piece_get(ROOK, CBoard_side(board)); + if (move_castle(move)) { + Piece Rook = Piece_get(ROOK, board_side(board)); switch (target) { case g1: - CBoard_piece_move(board, Rook, h1, f1); + board_piece_move(board, Rook, h1, f1); break; case c1: - CBoard_piece_move(board, Rook, a1, d1); + board_piece_move(board, Rook, a1, d1); break; case g8: - CBoard_piece_move(board, Rook, h8, f8); + board_piece_move(board, Rook, h8, f8); break; case c8: - CBoard_piece_move(board, Rook, a8, d8); + board_piece_move(board, Rook, a8, d8); break; default: break; } } - CBoard_castle_and(board, castling_rights[source]); - CBoard_castle_and(board, castling_rights[target]); + board_castle_and(board, castling_rights[source]); + board_castle_and(board, castling_rights[target]); - if (!CBoard_isCheck(board)) { - CBoard_side_switch(board); + if (!board_isCheck(board)) { + board_side_switch(board); return 1; } else return 0; } else { - if (Move_capture(move)) - return Move_make(move, board, 0); + if (move_capture(move)) + return move_make(move, board, 0); else return 0; } diff --git a/src/perft.c b/src/perft.c @@ -5,49 +5,49 @@ #include "moves.h" #include "perft.h" -struct MoveList_T moveList[10]; +struct MoveList moveList[10]; long nodes; -void perft_driver(CBoard_T board, struct MoveList_T *moveList, int depth, +void perft_driver(Board board, struct MoveList *moveList, int depth, unsigned long long *nodes) { if (depth == 0) { (*nodes)++; return; } - MoveList_T list = MoveList_generate(&moveList[depth], board); - CBoard_T copy = CBoard_new(); + MoveList list = move_list_generate(&moveList[depth], board); + Board copy = board_new(); - for (int i = 0; i < MoveList_size(list); i++) { - CBoard_copy(board, copy); - if (!Move_make(MoveList_move(list, i), copy, 0)) continue; + for (int i = 0; i < move_list_size(list); i++) { + board_copy(board, copy); + if (!move_make(move_list_move(list, i), copy, 0)) continue; perft_driver(copy, moveList, depth - 1, nodes); } - MoveList_reset(list); - CBoard_free(&copy); + move_list_reset(list); + board_free(&copy); } -void perft_test(CBoard_T board, int depth) { - MoveList_T list = MoveList_generate(&moveList[depth], board); - CBoard_T copy = CBoard_new(); +void perft_test(Board board, int depth) { + MoveList list = move_list_generate(&moveList[depth], board); + Board copy = board_new(); long start = get_time_ms(); printf("\n Performance test\n\n"); nodes = 0; - for (int i = 0; i < MoveList_size(list); i++) { - CBoard_copy(board, copy); - Move move = MoveList_move(list, i); - if (!Move_make(MoveList_move(list, i), copy, 0)) continue; + for (int i = 0; i < move_list_size(list); i++) { + board_copy(board, copy); + Move move = move_list_move(list, i); + if (!move_make(move_list_move(list, i), copy, 0)) continue; unsigned long long node = 0; perft_driver(copy, moveList, depth - 1, &node); - printf("%s%s: %llu\n", square_to_coordinates[Move_source(move)], - square_to_coordinates[Move_target(move)], node); + printf("%s%s: %llu\n", square_to_coordinates[move_source(move)], + square_to_coordinates[move_target(move)], node); nodes += node; } - MoveList_reset(list); - CBoard_free(&copy); + move_list_reset(list); + board_free(&copy); printf("\nNodes searched: %ld\n\n", nodes); printf("\n Depth: %d\n", depth); @@ -57,8 +57,8 @@ void perft_test(CBoard_T board, int depth) { typedef struct perf_shared perf_shared; struct perf_shared { - CBoard_T board; - MoveList_T list; + Board board; + MoveList list; int depth; sem_t *mutex; int *index; @@ -68,36 +68,36 @@ struct perf_shared { void *perft_thread(void *arg) { perf_shared *shared = (perf_shared *)arg; - CBoard_T board = CBoard_new(); + Board board = board_new(); unsigned long long node_count = 0; - struct MoveList_T moveList[10]; + struct MoveList moveList[10]; while (1) { sem_wait(shared->mutex); *shared->total += node_count; - if (*shared->index >= MoveList_size(shared->list)) { + if (*shared->index >= move_list_size(shared->list)) { sem_post(shared->mutex); break; } - Move move = MoveList_move(shared->list, (*shared->index)++); + Move move = move_list_move(shared->list, (*shared->index)++); sem_post(shared->mutex); - CBoard_copy(shared->board, board); - if (!Move_make(move, board, 0)) continue; + board_copy(shared->board, board); + if (!move_make(move, board, 0)) continue; node_count = 0; perft_driver(board, moveList, shared->depth, &node_count); - printf("%s%s: %llu\n", square_to_coordinates[Move_source(move)], - square_to_coordinates[Move_target(move)], node_count); + printf("%s%s: %llu\n", square_to_coordinates[move_source(move)], + square_to_coordinates[move_target(move)], node_count); } - CBoard_free(&board); + board_free(&board); sem_post(shared->finish); return NULL; } -void perft_test_threaded(CBoard_T board, int depth) { - MoveList_T list = MoveList_generate(NULL, board); +void perft_test_threaded(Board board, int depth) { + MoveList list = move_list_generate(NULL, board); int size = 8; unsigned long long total = 0; @@ -121,7 +121,7 @@ void perft_test_threaded(CBoard_T board, int depth) { for (int i = 0; i < size; i++) sem_wait(&finish); - MoveList_free(&list); + move_list_free(&list); printf("Nodes processed: %llu\n", total); }