From 8f0840fc2f983aaab3c85d57cae424298f290c7b Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Thu, 29 Feb 2024 09:31:00 +0100 Subject: [PATCH] add functions documentation - should be done earlier !! --- src/bitboard.c | 47 ++++++++++++++++++++++--------------------- src/bitboard.h | 54 +++++++++++++++++++++++++++++++------------------- src/board.c | 19 ++++++++++++++++-- src/board.h | 3 ++- src/piece.c | 40 ++++++++++++++++++------------------- src/piece.h | 22 +++++++++++++------- src/position.c | 41 +++++++++++++++++++++++++++----------- src/position.h | 11 +++++----- 8 files changed, 147 insertions(+), 90 deletions(-) diff --git a/src/bitboard.c b/src/bitboard.c index 222cd30..03e4eaf 100644 --- a/src/bitboard.c +++ b/src/bitboard.c @@ -20,7 +20,6 @@ #include "piece.h" #include "board.h" #include "bitboard.h" -#include "position.h" /* vectors are clockwise from N */ static int knight_vector[] = { @@ -141,26 +140,6 @@ void bitboard_init(void) bb_anti[sq] = tmpbb[sq][3]; } - /* - * for (int i = 0; i < 64; ++i) { - * for (int j = 0; j < 64; ++j) { - * if (bb_between[i][j] != bb_between_excl[i][j]) { - * bitboard_t diff = bb_between_excl[i][j] ^ bb_between[i][j]; - * int k = popcount64(bb_between[i][j]) - - * popcount64(bb_between_excl[i][j]); - * printf("%s-%s diff=%d excl=%s ", - * sq_string(i), sq_string(j), - * k, - * sq_string(ctz64(diff))); - * if (k == 1 && ctz64(diff) == j) - * printf("OK\n"); - * else - * printf("NOK\n"); - * } - * } - * } - */ - /* 3) knight and king moves */ for (square_t sq = A1; sq <= H8; ++sq) { //rank_t r1 = sq_rank(sq); @@ -182,10 +161,28 @@ void bitboard_init(void) } } + +/** + * bb_knight_moves() - get bitboard of knight pseudo-moves + * @notmine: bitboard_t of squares not occupied by own pieces + * @sq: knight square + * + * @Return: bitboard of available moves. + */ bitboard_t bb_knight_moves(bitboard_t notmine, square_t sq) { + //bitboard_print("bb_knight_move mask", bb_knight[sq]); + //bitboard_print("bb_knight_move res", bb_knight[sq] & notmine); return bb_knight[sq] & notmine; } + +/** + * bb_king_moves() - get bitboard of king pseudo-moves + * @notmine: bitboard_t of squares not occupied by own pieces + * @sq: king square + * + * @Return: bitboard of available moves. + */ bitboard_t bb_king_moves(bitboard_t notmine, square_t sq) { return bb_king[sq] & notmine; @@ -258,12 +255,16 @@ void bitboard_print_multi(const char *title, int n, ...) * bitboard_rank_sprint() - print an u8 rank binary representation * @str: the destination string * @bb8: the uchar to print + * + * @return: @str, filled with ascii representation */ char *bitboard_rank_sprint(char *str, const uchar bb8) { - for (file_t f = FILE_A; f <= FILE_H; ++f) { - *(str+f) = bb8 & mask(f) ? '1': '.'; + file_t f; + for (f = FILE_A; f <= FILE_H; ++f) { + *(str + f) = bb8 & mask(f) ? '1': '.'; } + *(str + f) = 0; //printf(" 0 1 2 3 4 5 6 7\n"); //printf("\n"); return str; diff --git a/src/bitboard.h b/src/bitboard.h index 10692b4..578f56c 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -40,25 +40,34 @@ extern bitboard_t bb_rank[64], bb_file[64], bb_diag[64], bb_anti[64]; extern bitboard_t bb_knight[64], bb_king[64]; enum { - FILE_Abb = 0x0101010101010101ULL, - FILE_Bbb = 0x0202020202020202ULL, - FILE_Cbb = 0x0404040404040404ULL, - FILE_Dbb = 0x0808080808080808ULL, - FILE_Ebb = 0x1010101010101010ULL, - FILE_Fbb = 0x2020202020202020ULL, - FILE_Gbb = 0x4040404040404040ULL, - FILE_Hbb = 0x8080808080808080ULL, + A1bb = mask(A1), A2bb = mask(A2), A3bb = mask(A3), A4bb = mask(A4), + A5bb = mask(A5), A6bb = mask(A6), A7bb = mask(A7), A8bb = mask(A8), + B1bb = mask(B1), B2bb = mask(B2), B3bb = mask(B3), B4bb = mask(B4), + B5bb = mask(B5), B6bb = mask(B6), B7bb = mask(B7), B8bb = mask(B8), + C1bb = mask(C1), C2bb = mask(C2), C3bb = mask(C3), C4bb = mask(C4), + C5bb = mask(C5), C6bb = mask(C6), C7bb = mask(C7), C8bb = mask(C8), + D1bb = mask(D1), D2bb = mask(D2), D3bb = mask(D3), D4bb = mask(D4), + D5bb = mask(D5), D6bb = mask(D6), D7bb = mask(D7), D8bb = mask(D8), + E1bb = mask(E1), E2bb = mask(E2), E3bb = mask(E3), E4bb = mask(E4), + E5bb = mask(E5), E6bb = mask(E6), E7bb = mask(E7), E8bb = mask(E8), + F1bb = mask(F1), F2bb = mask(F2), F3bb = mask(F3), F4bb = mask(F4), + F5bb = mask(F5), F6bb = mask(F6), F7bb = mask(F7), F8bb = mask(F8), + G1bb = mask(G1), G2bb = mask(G2), G3bb = mask(G3), G4bb = mask(G4), + G5bb = mask(G5), G6bb = mask(G6), G7bb = mask(G7), G8bb = mask(G8), + H1bb = mask(H1), H2bb = mask(H2), H3bb = mask(H3), H4bb = mask(H4), + H5bb = mask(H5), H6bb = mask(H6), H7bb = mask(H7), H8bb = mask(H8), }; enum { - RANK_1bb = 0x00000000000000ffULL, - RANK_2bb = 0x000000000000ff00ULL, - RANK_3bb = 0x0000000000ff0000ULL, - RANK_4bb = 0x00000000ff000000ULL, - RANK_5bb = 0x000000ff00000000ULL, - RANK_6bb = 0x0000ff0000000000ULL, - RANK_7bb = 0x00ff000000000000ULL, - RANK_8bb = 0xff00000000000000ULL + FILE_Abb = 0x0101010101010101ULL, FILE_Bbb = 0x0202020202020202ULL, + FILE_Cbb = 0x0404040404040404ULL, FILE_Dbb = 0x0808080808080808ULL, + FILE_Ebb = 0x1010101010101010ULL, FILE_Fbb = 0x2020202020202020ULL, + FILE_Gbb = 0x4040404040404040ULL, FILE_Hbb = 0x8080808080808080ULL, + + RANK_1bb = 0x00000000000000ffULL, RANK_2bb = 0x000000000000ff00ULL, + RANK_3bb = 0x0000000000ff0000ULL, RANK_4bb = 0x00000000ff000000ULL, + RANK_5bb = 0x000000ff00000000ULL, RANK_6bb = 0x0000ff0000000000ULL, + RANK_7bb = 0x00ff000000000000ULL, RANK_8bb = 0xff00000000000000ULL }; /* https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#Rotation @@ -102,10 +111,15 @@ static __always_inline bitboard_t shift_nw(const bitboard_t bb) return (bb & ~FILE_Abb) << NORTH_WEST; } -/* pawn moves/attacks */ -#define pawn_push(bb, c) ((c) == WHITE ? shift_n(bb): shift_s(bb)) -#define pawn_take_left(bb, c) ((c) == WHITE ? shift_nw(bb): shift_se(bb)) -#define pawn_take_right(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb)) +#define pawn_up_value(c) ((c) == WHITE ? 8: -8) +/* pawn moves/attacks (for bitboards) */ +#define pawn_shift_up(bb, c) ((c) == WHITE ? shift_n(bb): shift_s(bb)) +#define pawn_shift_upleft(bb, c) ((c) == WHITE ? shift_nw(bb): shift_se(bb)) +#define pawn_shift_upright(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb)) +/* pawn move (for single pawn) */ +#define pawn_push_up(sq, c) ((sq) + ((c) == WHITE ? NORTH: SOUTH)) +#define pawn_push_upleft(sq, c) ((sq) + ((c) == WHITE ? NORTH_WEST: SOUTH_EAST)) +#define pawn_push_upright(sq, c) ((sq) + ((c) == WHITE ? NORTH_EAST: SOUTH_WEST)) extern bitboard_t bitboard_between_excl(square_t sq1, square_t sq2); extern void bitboard_init(void); diff --git a/src/board.c b/src/board.c index 2464c9d..fae2f2e 100644 --- a/src/board.c +++ b/src/board.c @@ -11,6 +11,8 @@ * */ +#include + #include "brlib.h" #include "board.h" @@ -26,12 +28,25 @@ static const char *sq_strings[] = { }; /** - * sq_string() - return a square string + * sq_to_string() - return a square string * @square: square (0-64) * * @Return: Pointer to @square string representation ("a1"-"h8"). */ -const char *sq_string(const square_t square) +const char *sq_to_string(const square_t square) { return sq_strings[square]; } + +/** + * sq_from_string() - return a square from a string + * @sqstr: the square representation (a1-h8) + * + * @Return: square_t representation of str. + */ +square_t sq_from_string(const char *sqstr) +{ + file_t f = C2FILE(sqstr[0]); + rank_t r = C2RANK(sqstr[1]); + return sq_coord_ok(f) && sq_coord_ok(r) ? sq_make(f, r): SQUARE_NONE; +} diff --git a/src/board.h b/src/board.h index c7075e7..930d195 100644 --- a/src/board.h +++ b/src/board.h @@ -97,6 +97,7 @@ static __always_inline rank_t sq_rank(square_t square) #define sq_manh(sq1, sq2) (abs(sq_file(sq2) - sq_file(sq1)) + \ abs(sq_rank(sq2) - sq_rank(sq1))) -extern const char *sq_string(const square_t sq); +extern const char *sq_to_string(const square_t sq); +extern square_t sq_from_string(const char *sq_string); #endif /* BOARD_H */ diff --git a/src/piece.c b/src/piece.c index 8873d3f..953f527 100644 --- a/src/piece.c +++ b/src/piece.c @@ -25,22 +25,22 @@ * piece_details */ const struct piece_details piece_details[PIECE_MAX] = { - /* Abb AbbC Sym SymC Name start value */ - [EMPTY] = { ' ', ' ', " ", " ", " ", 0, 0, 0 }, - [W_PAWN] = { 'P', 'P', "♟", "♙", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, - [W_KNIGHT] = { 'N', 'N', "♞", "♘", "Knight", N_VAL_OPN, N_VAL_MID, N_VAL_END }, - [W_BISHOP] = { 'B', 'B', "♝", "♗", "Bishop", B_VAL_OPN, B_VAL_MID, B_VAL_END }, - [W_ROOK] = { 'R', 'R', "♜", "♖", "Rook", R_VAL_OPN, R_VAL_MID, R_VAL_END }, - [W_QUEEN] = { 'Q', 'Q', "♛", "♕", "Queen", Q_VAL_OPN, Q_VAL_MID, Q_VAL_END }, - [W_KING] = { 'K', 'K', "♚", "♔", "King", K_VAL_OPN, K_VAL_MID, K_VAL_END }, - [7] = { '7', '7', "�", "�", "Inv 7", 0, 0, 0 }, - [8] = { '8', '8', "�", "�", "Inv 8", 0, 0, 0 }, - [B_PAWN] = { 'P', 'p', "♟", "♟", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, - [B_KNIGHT] = { 'N', 'n', "♞", "♞", "Knight", P_VAL_OPN, N_VAL_MID, N_VAL_END }, - [B_BISHOP] = { 'B', 'b', "♝", "♝", "Bishop", P_VAL_OPN, B_VAL_MID, B_VAL_END }, - [B_ROOK] = { 'R', 'r', "♜", "♜", "Rook", P_VAL_OPN, R_VAL_MID, R_VAL_END }, - [B_QUEEN] = { 'Q', 'q', "♛", "♛", "Queen", P_VAL_OPN, Q_VAL_MID, Q_VAL_END }, - [B_KING] = { 'K', 'k', "♚", "♚", "King", P_VAL_OPN, K_VAL_MID, K_VAL_END }, + /* Abb Fen Sym SymC Name start value */ + [EMPTY] = { "", "", "", "", "", 0, 0, 0 }, + [W_PAWN] = { "", "P", "♟", "♙", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, + [W_KNIGHT] = { "N", "N", "♞", "♘", "Knight", N_VAL_OPN, N_VAL_MID, N_VAL_END }, + [W_BISHOP] = { "B", "B", "♝", "♗", "Bishop", B_VAL_OPN, B_VAL_MID, B_VAL_END }, + [W_ROOK] = { "R", "R", "♜", "♖", "Rook", R_VAL_OPN, R_VAL_MID, R_VAL_END }, + [W_QUEEN] = { "Q", "Q", "♛", "♕", "Queen", Q_VAL_OPN, Q_VAL_MID, Q_VAL_END }, + [W_KING] = { "K", "K", "♚", "♔", "King", K_VAL_OPN, K_VAL_MID, K_VAL_END }, + [7] = { "", "", "", "", "", 0, 0, 0 }, + [8] = { "", "", "", "", "", 0, 0, 0 }, + [B_PAWN] = { "", "p", "♟", "♟", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, + [B_KNIGHT] = { "N", "n", "♞", "♞", "Knight", P_VAL_OPN, N_VAL_MID, N_VAL_END }, + [B_BISHOP] = { "B", "b", "♝", "♝", "Bishop", P_VAL_OPN, B_VAL_MID, B_VAL_END }, + [B_ROOK] = { "R", "r", "♜", "♜", "Rook", P_VAL_OPN, R_VAL_MID, R_VAL_END }, + [B_QUEEN] = { "Q", "q", "♛", "♛", "Queen", P_VAL_OPN, Q_VAL_MID, Q_VAL_END }, + [B_KING] = { "K", "k", "♚", "♚", "King", P_VAL_OPN, K_VAL_MID, K_VAL_END }, }; const char pieces_str[6+6+1] = "PNBRQKpnbrqk"; @@ -51,14 +51,14 @@ bool piece_ok(piece_t p) return !(p & ~(MASK_COLOR | MASK_PIECE)) && pt && (pt <= KING); } -char piece_to_char(piece_t p) +char *piece_to_char(piece_t p) { return piece_details[p].abbr; } -char piece_to_char_color(piece_t p) +char *piece_to_char_color(piece_t p) { - return piece_details[p].abbr_color; + return piece_details[p].c_abbr; } char *piece_to_sym(piece_t p) @@ -68,7 +68,7 @@ char *piece_to_sym(piece_t p) char *piece_to_sym_color(piece_t p) { - return piece_details[p].sym_color; + return piece_details[p].c_sym; } char *piece_to_name(piece_t p) diff --git a/src/piece.h b/src/piece.h index 1f2b71c..0ba9bd5 100644 --- a/src/piece.h +++ b/src/piece.h @@ -70,13 +70,21 @@ typedef enum { #define K_VAL_END 20000 /* some default values for pieces + * @abbr: char, piece capital letter (used for game notation) + * @abbr_c: char, capital for white, lowercase for black + * char *sym; + * char *sym_c; + * char *name; + * s64 opn_value; + * s64 mid_value; + * s64 end_value; */ extern const struct piece_details { - char abbr; /* used for game notation */ - char abbr_color; /* lowercase = black */ + char *abbr; /* used for game notation */ + char *c_abbr; /* lowercase = black */ char *sym; /* used for game notation */ - char *sym_color; /* different W & B */ - char *name; + char *c_sym; /* different W & B */ + char *name; /* piece name */ s64 opn_value; /* value opening */ s64 mid_value; /* value midgame */ s64 end_value; /* value endgame */ @@ -84,7 +92,7 @@ extern const struct piece_details { extern const char pieces_str[6+6+1]; /* to search from fen/user input */ -#define OPPONENT(p) !(p) +#define OPPONENT(color) !(color) #define MASK_PIECE 0x07 /* 00000111 */ #define MASK_COLOR 0x08 /* 00001000 */ @@ -102,8 +110,8 @@ extern const char pieces_str[6+6+1]; /* to search from fen/user inp extern bool piece_ok(piece_t p); -extern char piece_to_char(piece_t p); -extern char piece_to_char_color(piece_t p); +extern char *piece_to_char(piece_t p); +extern char *piece_to_char_color(piece_t p); extern char *piece_to_sym(piece_t p); extern char *piece_to_sym_color(piece_t p); extern char *piece_to_name(piece_t p); diff --git a/src/position.c b/src/position.c index 75e0077..e13964d 100644 --- a/src/position.c +++ b/src/position.c @@ -103,7 +103,9 @@ void pos_del(pos_t *pos) */ pos_t *pos_clear(pos_t *pos) { +# ifdef DEBUG_POS printf("size(pos_board=%lu elt=%lu\n", sizeof(pos->board), sizeof(int)); +# endif //for (square square = A1; square <= H8; ++square) // pos->board[square] = EMPTY; @@ -114,7 +116,7 @@ pos_t *pos_clear(pos_t *pos) pos->plycount = 0; pos->en_passant = SQUARE_NONE; pos->castle = 0; - memset(pos->board, 0, sizeof(pos->board)); + memset(pos->board, EMPTY, sizeof(pos->board)); //pos->curmove = 0; //pos->eval = 0; //pos->occupied[WHITE] = 0; @@ -124,7 +126,9 @@ pos_t *pos_clear(pos_t *pos) pos->bb[color][piece] = 0; pos->controlled[WHITE] = 0; pos->controlled[BLACK] = 0; + pos->king[color] = SQUARE_NONE; } + pos->moves.curmove = pos->moves.nmoves = 0; //pos->mobility[WHITE] = 0; //pos->mobility[BLACK] = 0; //pos->moves_generated = false; @@ -156,12 +160,12 @@ void pos_print(pos_t *pos) printf("%c |", rank + '1'); for (file = 0; file < 8; ++file) { pc = board[sq_make(file, rank)]; - printf(" %s |", piece_to_sym_color(pc)); + printf(" %s |", pc? piece_to_sym_color(pc): " "); } printf("\n +---+---+---+---+---+---+---+---+\n"); } printf(" A B C D E F G H\n"); - printf("%s\n", pos2fen(pos, fen)); + printf("fen %s\n", pos2fen(pos, fen)); //printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black"); /* * printf("Kings: W:%c%c B:%c%c\n", @@ -185,7 +189,7 @@ void pos_print(pos_t *pos) void pos_pieces_print(pos_t *pos) { int bit, count, cur; - char pname; + char *pname; u64 tmp; bitboard_t p; for (int color = WHITE; color <= BLACK; ++color) { @@ -194,7 +198,7 @@ void pos_pieces_print(pos_t *pos) count = popcount64(p); cur = 0; pname = piece_to_char(piece); - printf("%c(0)%s", pname, count? ":": ""); + printf("%s(0)%s", pname, count? ":": ""); if (count) { bit_for_each64(bit, tmp, p) { char cf = sq_file(bit), cr = sq_rank(bit); @@ -229,16 +233,29 @@ inline void bitboard_print2_raw(bitboard_t bb1, bitboard_t bb2, char *title) */ /** - * raw_board_print - print simple board (hex values) + * pos_print_board_raw - print simple position board (octal/FEN symbol values) * @bb: the bitboard + * @type: int, 0 for octal, 1 for fen symbol */ -void raw_board_print(const pos_t *pos) +void pos_print_board_raw(const pos_t *pos, int type) { - - for (rank_t r = RANK_8; r >= RANK_1; --r) { - for (file_t f = FILE_A; f <= FILE_H; ++f) - printf("%02o ", pos->board[sq_make(f, r)]); - printf(" \n"); + if (type == 0) { + for (rank_t r = RANK_8; r >= RANK_1; --r) { + for (file_t f = FILE_A; f <= FILE_H; ++f) + printf("%02o ", pos->board[sq_make(f, r)]); + printf(" \n"); + } + } else { + for (rank_t r = RANK_8; r >= RANK_1; --r) { + for (file_t f = FILE_A; f <= FILE_H; ++f) { + square_t sq = sq_make(f, r); + if (pos->board[sq] == EMPTY) + printf(". "); + else + printf("%s ", piece_to_char_color(pos->board[sq])); + } + printf(" \n"); + } } return; } diff --git a/src/position.h b/src/position.h index efc4338..13145fe 100644 --- a/src/position.h +++ b/src/position.h @@ -19,16 +19,18 @@ #include "brlib.h" #include "bitops.h" -#include "bitboard.h" #include "chessdefs.h" +#include "bitboard.h" #include "piece.h" #include "move.h" -typedef struct _pos_s { +typedef struct __pos_s { u64 node_count; /* evaluated nodes */ int turn; /* WHITE or BLACK */ u16 clock_50; u16 plycount; /* plies so far, start is 0 */ + + square_t king[2]; /* dup with bb, faster retrieval */ square_t en_passant; castle_rights_t castle; @@ -41,14 +43,13 @@ typedef struct _pos_s { //bool moves_counted; bitboard_t bb[2][PIECE_TYPE_MAX]; /* bb[0][PAWN], bb[1][ALL_PIECES] */ - square_t king[2]; /* dup with bb, faster retrieval */ bitboard_t controlled[2]; //u16 mobility[2]; //struct list_head pieces[2]; /* pieces list, King is first */ //struct list_head moves[2]; piece_t board[BOARDSIZE]; movelist_t moves; - int nmoves; + //int nmoves; } pos_t; /** @@ -98,7 +99,7 @@ extern pos_t *pos_clear(pos_t *pos); extern void pos_print(pos_t *pos); extern void pos_pieces_print(pos_t *pos); -extern void raw_board_print(const pos_t *pos); +extern void pos_print_board_raw(const pos_t *pos, int type); //extern pos_t *pos_startpos(pos_t *pos);