diff --git a/Makefile b/Makefile index 9eb16ae..501c030 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ CPPFLAGS += -DWARN_ON CPPFLAGS += -DDEBUG_DEBUG # enable log() functions #CPPFLAGS += -DDEBUG_DEBUG_C # enable verbose log() settings CPPFLAGS += -DDEBUG_POOL # memory pools management -CPPFLAGS += -DDEBUG_FEN # FEN decoding +#CPPFLAGS += -DDEBUG_FEN # FEN decoding CPPFLAGS += -DDEBUG_MOVE # move generation CPPFLAGS += -DDEBUG_EVAL # eval functions CPPFLAGS += -DDEBUG_PIECE # piece list management @@ -233,7 +233,7 @@ $(CCLSROOT): # maybe run cleanobj cleanlibobj in commands ? $(CCLSFILE): cleanobj cleanbrlib $(SRC) $(LIBSRC) | $(CCLSROOT) @echo "Generating ccls compile commands file ($@)." - @$(BEAR) -- make compile + @$(BEAR) -- $(MAKE) compile #.PHONY: bear #bear: cleanobj cleanlibobj Makefile | $(CCLSROOT) diff --git a/README.org b/README.org index 199f4df..7b5905e 100644 --- a/README.org +++ b/README.org @@ -13,6 +13,9 @@ the GNU General Public License v3.0 or later. Some rights reserved. See COPYING. ** Installation (don't do it until version 0.9) +*** dependencire +- GCC 10 or newer +- libreadline *** clone repository *user...** #+BEGIN_EXAMPLE diff --git a/src/bitboard.c b/src/bitboard.c index 7034183..9277397 100644 --- a/src/bitboard.c +++ b/src/bitboard.c @@ -11,7 +11,7 @@ * */ -#include "br.h" +#include "brlib.h" #include "bitboard.h" /* maps are clockwise from N */ diff --git a/src/chessdefs.h b/src/chessdefs.h index e605841..e0617df 100644 --- a/src/chessdefs.h +++ b/src/chessdefs.h @@ -20,45 +20,9 @@ #define C64(const_u64) const_u64##ULL #define U64(const_s64) const_s64##LL -/* piece_t bits structure - * piece is on bits 1-3, color on bit 4: - * .... CPPP - * C: 0 for white, 1: black - * PPP: pawn (1), knight, bishop, rook, queen, king (6) - */ -typedef enum { - WHITE, BLACK, - COLOR_MAX -} color_t; +typedef u64 bitboard; +typedef ushort board; -typedef enum { - ALL_PIECES = 0, /* 'all pieces' bitboard */ - PAWN = 1, KNIGHT, BISHOP, ROOK, QUEEN, KING, - PIECE_TYPE_MAX = 7 /* bit 4 */ -} piece_type_t; - -typedef enum { - EMPTY, - W_PAWN = PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING, - B_PAWN = PAWN | 8, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING, - PIECE_MAX -} piece_t; - -#define OPPONENT(p) !(p) - -#define MASK_PIECE 0x07 /* 00000111 */ -#define MASK_COLOR 0x08 /* 00001000 */ - -#define COLOR(p) ((p) >> 3) /* bitmask */ -#define PIECE(p) ((p) & MASK_PIECE) -#define MAKE_PIECE(p, c) ((p) | (c) << 3) - -#define IS_WHITE(p) (!COLOR(p)) -#define IS_BLACK(p) (COLOR(p)) - -#define SET_WHITE(p) ((p) &= ~MASK_COLOR) -#define SET_BLACK(p) ((p) |= MASK_COLOR) -#define SET_COLOR(p, c) (!(c)? SET_WHITE(p): SET_BLACK(p)) /* flip a 0-63 square: * Vertical: G8 (62) becomes G1 (6) @@ -67,8 +31,6 @@ typedef enum { #define FLIP_V(sq) ((sq) ^ 56) #define FLIP_H(sq) ((sq) ^ 7) -typedef u64 bitboard; -typedef ushort board; #define BOARDSIZE (8*8) /* from human to machine */ #define C2FILE(c) (tolower(c) - 'a') diff --git a/src/fen.c b/src/fen.c index 9fcd163..a2add0c 100644 --- a/src/fen.c +++ b/src/fen.c @@ -55,10 +55,6 @@ /* chess startup position FEN */ const char *startfen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; - -/* next must follow 'piece_type' enum values (pawn is 1, king is 6) */ -static const char *pieces_str = " PNBRQK"; -/* And this one must follow 'castle' enum order (also same as usual FEN) */ static const char *castle_str = "KQkq"; #define SKIP_BLANK(p) for(;isspace(*(p)); (p)++) @@ -81,7 +77,7 @@ pos_t *startpos(pos_t *pos) * @pos: a position pointer or NULL * @fen: a valid fen string * - * If @pos is NULL, a position will be allocated with malloc(1), + * If @pos is NULL, a position will be allocated with @pos_new(), * that should be freed by caller. * * @return: the pos position, or NULL if error. @@ -90,7 +86,8 @@ pos_t *fen2pos(pos_t *pos, const char *fen) { const char *cur = fen; char *p; - short rank, file, color, tmp; + short rank, file, tmp; + piece_t piece; int consumed, err_line = 0, err_pos, err_char; pos_t tmppos; @@ -108,13 +105,12 @@ pos_t *fen2pos(pos_t *pos, const char *fen) file += *cur - '0'; continue; } - color = isupper(*cur)? WHITE: BLACK; - if ((p = strchr(pieces_str, toupper(*cur)))) { /* valid piece letter */ + if ((piece = char_color_to_piece(*cur)) != EMPTY) { # ifdef DEBUG_FEN - log_i(5, "f=%d r=%d *p=%c piece=%c color=%d ppos=%ld\n", - file, rank, *cur, *p, color, p - pieces_str); + log_i(5, "f=%d r=%d *p=%c piece=%#04x t=%d c=%d\n", file, rank, *cur, + piece, PIECE(piece), COLOR(piece)); # endif - pos_set_sq(&tmppos, p - pieces_str, color, file, rank); + pos_set_sq(&tmppos, BB(file, rank), piece); file++; } else { /* error */ err_line = __LINE__, err_char = *cur, err_pos = cur - fen; @@ -163,37 +159,24 @@ pos_t *fen2pos(pos_t *pos, const char *fen) /* 6) current full move number, starting with 1 */ - printf ("remain=[%s]\n", cur); sscanf(cur, "%hd", &tmp); - printf ("tmp=[%d]\n", tmp); if (tmp <= 0) /* fix faulty numbers*/ tmp = 1; - printf ("tmp2=[%d]\n", tmp); tmp = 2 * (tmp - 1) + (tmppos.turn == BLACK); /* plies, +1 if black turn */ - printf ("tmp3=[%d]\n", tmp); tmppos.plycount = tmp; # ifdef DEBUG_FEN - for (rank = 7; rank >= 0; --rank) { - for (file = 0; file < 8; ++file) { - log(5, "%02x ", tmppos.board[BB(file, rank)]); - } - log(5, "\n"); - } - log(5, "turn=%d 50_rule=%d curply=%d\n", - tmppos.turn, tmppos.clock_50, tmppos.plycount); + raw_board_print(&tmppos); # endif end: - if (warn(err_line, "FEN error line %d: pos=%d char=%#x(%c)\n", + if (warn(err_line, "FEN error line %d: charpos=%d char=%#x(%c)\n", err_line, err_pos, err_char, err_char)) { return NULL; } if (!pos) pos = pos_new(); - else - pos_clear(pos); *pos = tmppos; return pos; } @@ -223,24 +206,18 @@ char *pos2fen(const pos_t *pos, char *fen) /* 1) position */ for (rank_t rank = RANK_8; rank >= RANK_1; --rank) { - printf("r=%d 1=%d\n", rank, RANK_1); for (file_t file = FILE_A; file <= FILE_H;) { - printf(" f=%d H=%d\n", file, FILE_H); square_t sq = BB(file, rank); - printf(" sq=%d\n", sq); - piece_t piece = PIECE(pos->board[sq]); - color_t color = COLOR(pos->board[sq]); + piece_t piece =pos->board[sq]; if (pos->board[sq] == EMPTY) { int len = 0; for (; file <= FILE_H && pos->board[BB(file,rank)] == EMPTY; file++) len++; fen[cur++] = '0' + len; } else { - char c = pieces_str[piece]; - fen[cur++] = color == WHITE? c: tolower(c); + fen[cur++] = piece_to_char_color(piece); file++; } - fen[cur]=0; puts(fen); } fen[cur++] = rank == RANK_1? ' ': '/'; } diff --git a/src/piece.c b/src/piece.c index 78c5113..8873d3f 100644 --- a/src/piece.c +++ b/src/piece.c @@ -16,39 +16,79 @@ #include #include -//#include -//#include -//#include +#include "bug.h" #include "chessdefs.h" #include "piece.h" -//#include "board.h" -//#include "bitboard.h" -//#include "position.h" /** * piece_details */ -const struct piece_details piece_details[] = { - /* Abb Sym Name start value */ - [EMPTY] = { ' ', " ", " ", 0, 0, 0 }, - [W_PAWN] = { 'P', "♙", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, - [W_KNIGHT] = { 'N', "♘", "Knight", N_VAL_OPN, N_VAL_MID, N_VAL_END }, - [W_BISHOP] = { 'B', "♗", "Bishop", B_VAL_OPN, B_VAL_MID, B_VAL_END }, - [W_ROOK] = { 'R', "♖", "Rook", R_VAL_OPN, R_VAL_MID, R_VAL_END }, - [W_QUEEN] = { 'Q', "♕", "Queen", Q_VAL_OPN, Q_VAL_MID, Q_VAL_END }, - [W_KING] = { 'K', "♔", "King", K_VAL_OPN, K_VAL_MID, K_VAL_END }, - [7] = { '7', "�", "Inv 7", 0, 0, 0 }, - [8] = { '7', "�", "Inv 8", 0, 0, 0 }, - [B_PAWN] = { 'p', "♟", "Pawn", P_VAL_OPN, P_VAL_MID, P_VAL_END }, - [B_KNIGHT] = { 'n', "♞", "Knight", P_VAL_OPN, N_VAL_MID, N_VAL_END }, - [B_BISHOP] = { 'b', "♝", "Bishop", P_VAL_OPN, B_VAL_MID, B_VAL_END }, - [B_ROOK] = { 'r', "♜", "Rook", P_VAL_OPN, R_VAL_MID, R_VAL_END }, - [B_QUEEN] = { 'q', "♛", "Queen", P_VAL_OPN, Q_VAL_MID, Q_VAL_END }, - [B_KING] = { 'k', "♚", "King", P_VAL_OPN, K_VAL_MID, K_VAL_END }, +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 }, }; -const char *fenpieces_idx = " PNBRQ pnbrq"; +const char pieces_str[6+6+1] = "PNBRQKpnbrqk"; + +bool piece_ok(piece_t p) +{ + piece_type_t pt = PIECE(p); + return !(p & ~(MASK_COLOR | MASK_PIECE)) && pt && (pt <= KING); +} + +char piece_to_char(piece_t p) +{ + return piece_details[p].abbr; +} + +char piece_to_char_color(piece_t p) +{ + return piece_details[p].abbr_color; +} + +char *piece_to_sym(piece_t p) +{ + return piece_details[PIECE(p)].sym; +} + +char *piece_to_sym_color(piece_t p) +{ + return piece_details[p].sym_color; +} + +char *piece_to_name(piece_t p) +{ + return piece_details[p].name; +} + +piece_t char_to_piece(char c) +{ + char *p = strchr(pieces_str, c); + return p? (p - pieces_str) % 6 + 1: EMPTY; +} + +piece_t char_color_to_piece(char c) +{ + piece_t piece = char_to_piece(c); + return isupper(c)? piece: SET_BLACK(piece); +} + + /* * void piece_list_print(struct list_head *list) * { diff --git a/src/piece.h b/src/piece.h index 9b7a7f5..14ac6f3 100644 --- a/src/piece.h +++ b/src/piece.h @@ -14,12 +14,34 @@ #ifndef PIECE_H #define PIECE_H -#include +#include #include "chessdefs.h" -#include "list.h" -#include "pool.h" +/* piece_t bits structure + * piece is on bits 1-3, color on bit 4: + * .... CPPP + * C: 0 for white, 1: black + * PPP: pawn (1), knight, bishop, rook, queen, king (6) + */ +typedef enum { + WHITE, BLACK, + COLOR_MAX +} color_t; + +typedef enum { + ALL_PIECES = 0, /* 'all pieces' bitboard */ + PAWN = 1, KNIGHT, BISHOP, ROOK, QUEEN, KING, + PIECE_TYPE_MAX = 7 /* bit 4 */ +} piece_type_t; + +typedef enum { + EMPTY = 0, + NO_PIECE = 0, + W_PAWN = PAWN, W_KNIGHT, W_BISHOP, W_ROOK, W_QUEEN, W_KING, + B_PAWN = PAWN | 8, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING, + PIECE_MAX +} piece_t; /* default values for opening, midgame, endgame */ @@ -47,33 +69,51 @@ #define Q_VAL_END 900 #define K_VAL_END 20000 -/* -typedef struct piece_list_s { - piece_t piece; - square_t square; - short castle; - s64 value; - struct list_head list; -} piece_list_t; -*/ - /* some default values for pieces */ extern const struct piece_details { - char abbrev; /* used for game notation */ - //char abbrev_b; - char *symbol; - //char *symbol_b; /* used for game notation */ + char abbr; /* used for game notation */ + char abbr_color; /* lowercase = black */ + char *sym; /* used for game notation */ + char *sym_color; /* different W & B */ char *name; - s64 opn_value; - s64 mid_value; - s64 end_value; -} piece_details[]; + s64 opn_value; /* value opening */ + s64 mid_value; /* value midgame */ + s64 end_value; /* value endgame */ +} piece_details[PIECE_MAX]; -#define P_ABBR(p) piece_details[PIECE(p)].abbrev -#define P_SYM(p) piece_details[PIECE(p)].symbol -#define P_NAME(p) piece_details[PIECE(p)].name -#define P_VAL(p) piece_details[PIECE(p)].opn_value +extern const char pieces_str[6+6+1]; + +//#define P_SYM(p) piece_details[p].sym +//#define P_NAME(p) piece_details[p].name +//#define P_VAL(p) piece_details[p].opn_value + +#define OPPONENT(p) !(p) + +#define MASK_PIECE 0x07 /* 00000111 */ +#define MASK_COLOR 0x08 /* 00001000 */ + +#define COLOR(p) ((p) >> 3) /* bitmask */ +#define PIECE(p) ((p) & MASK_PIECE) +#define MAKE_PIECE(p, c) ((p) | (c) << 3) + +#define IS_WHITE(p) (!COLOR(p)) +#define IS_BLACK(p) (COLOR(p)) + +#define SET_WHITE(p) ((p) &= ~MASK_COLOR) +#define SET_BLACK(p) ((p) |= MASK_COLOR) +#define SET_COLOR(p, c) (!(c)? SET_WHITE(p): SET_BLACK(p)) + +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_sym(piece_t p); +extern char *piece_to_sym_color(piece_t p); +extern char *piece_to_name(piece_t p); + +extern piece_t char_to_piece(char c); +extern piece_t char_color_to_piece(char c); /* use short name or symbol - no effect */ diff --git a/src/position.c b/src/position.c index 8e48e89..910b518 100644 --- a/src/position.c +++ b/src/position.c @@ -28,44 +28,155 @@ #include "util.h" //#include "eval.h" -static pool_t *pos_pool; +//static pool_t *pos_pool; -const char *rankstr = "12345678"; -const char *filestr = "ABCDEFGH"; +//const char *rankstr = "12345678"; +//const char *filestr = "ABCDEFGH"; -#define BYTE_PRINT "%c%c%c%c%c%c%c%c" -#define BYTE2BIN(b) ((b) & 0x01 ? '1' : '0'), \ - ((b) & 0x02 ? '1' : '0'), \ - ((b) & 0x04 ? '1' : '0'), \ - ((b) & 0x08 ? '1' : '0'), \ - ((b) & 0x10 ? '1' : '0'), \ - ((b) & 0x20 ? '1' : '0'), \ - ((b) & 0x40 ? '1' : '0'), \ - ((b) & 0x80 ? '1' : '0') +/**************************************************** + * #define BYTE_PRINT "%c%c%c%c%c%c%c%c" * + * #define BYTE2BIN(b) ((b) & 0x01 ? '1' : '0'), \ * + * ((b) & 0x02 ? '1' : '0'), \ * + * ((b) & 0x04 ? '1' : '0'), \ * + * ((b) & 0x08 ? '1' : '0'), \ * + * ((b) & 0x10 ? '1' : '0'), \ * + * ((b) & 0x20 ? '1' : '0'), \ * + * ((b) & 0x40 ? '1' : '0'), \ * + * ((b) & 0x80 ? '1' : '0') * + ****************************************************/ -/* -inline void bitboard_print_raw(bitboard_t bb, char *title) +/** + * pos_new() - allocate a new position + * + * position is not initialized + */ +pos_t *pos_new(void) { - int i; - printf("%s%s %#018lx\n", title? title: "", title? " - ": "", bb); - for (i=56; i>=0; i-=8) - printf("\t"BYTE_PRINT"\n", - BYTE2BIN(bb>>i)); + return safe_malloc(sizeof(pos_t)); } -*/ -/* -inline void bitboard_print2_raw(bitboard_t bb1, bitboard_t bb2, char *title) -{ - int i; - printf("%s%s", title? title: "", title? ":\n": ""); - printf("\tW: %#018lx\tB: %#018lx\n", bb1, bb2); - for (i=56; i>=0; i-=8) - printf("\t"BYTE_PRINT"\t\t"BYTE_PRINT"\n", - BYTE2BIN(bb1>>i), - BYTE2BIN(bb2>>i)); +/** + * pos_dup() - duplicate a position. + * @pos: &position to duplicate. + * + * New position is the same as source one (with duplicated pieces list), + * except: + * - moves list is empty + * - bestmove is NULL + * - nodecount is set to zero + * - eval is set to EVAL_INVALID + * - moves_generated ans moves_counted are unset + * - check is set to zero + * + * @return: The new position. + * + * TODO: merge with pos_new - NULL for init, non null for duplicate + */ +pos_t *pos_dup(pos_t *pos) +{ + pos_t *newpos = safe_malloc(sizeof(pos_t)); + + //board = new->board; + *newpos = *pos; + //new->bestmove = NULL; + newpos->node_count = 0; + //new->eval = EVAL_INVALID; + //new->moves_generated = false; + //new->moves_counted = false; + //new->check[WHITE] = new->check[BLACK] = 0; + return newpos; } -*/ + +/** + * pos_del() - delete a position. + * @pos: &position. + */ +void pos_del(pos_t *pos) +{ + safe_free(pos); +} + +/** + * pos_clear() - clear a position. + * @pos: &position. + */ +pos_t *pos_clear(pos_t *pos) +{ + printf("size(pos_board=%lu elt=%lu\n", sizeof(pos->board), sizeof(int)); + //for (square square = A1; square <= H8; ++square) + // pos->board[square] = EMPTY; + + SET_WHITE(pos->turn); + pos->node_count = 0; + pos->turn = 0; + pos->clock_50 = 0; + pos->plycount = 0; + pos->en_passant = 0; + pos->castle = 0; + memset(pos->board, 0, sizeof(pos->board)); + //pos->curmove = 0; + //pos->eval = 0; + //pos->occupied[WHITE] = 0; + //pos->occupied[BLACK] = 0; + for (color_t color = WHITE; color <= BLACK; ++color) { + for (piece_type_t piece = 0; piece <= KING; ++piece) + pos->bb[color][piece] = 0; + pos->controlled[WHITE] = 0; + pos->controlled[BLACK] = 0; + } + //pos->mobility[WHITE] = 0; + //pos->mobility[BLACK] = 0; + //pos->moves_generated = false; + //pos->moves_counted = false; + /* remove pieces / moves */ + //pieces_del(pos, WHITE); + //pieces_del(pos, BLACK); + //moves_del(pos); + + return pos; +} + +/** + * pos_print() - Print position and fen on stdout. + * @pos: &position + */ +void pos_print(pos_t *pos) +{ + int rank, file; + piece_t pc, *board = pos->board; + char fen[92]; + + //piece_list_t *wk = list_first_entry(&pos->pieces[WHITE], piece_list_t, list), + // *bk = list_first_entry(&pos->pieces[BLACK], piece_list_t, list); + + + printf(" +---+---+---+---+---+---+---+---+\n"); + for (rank = 7; rank >= 0; --rank) { + printf("%c |", rank + '1'); + for (file = 0; file < 8; ++file) { + pc = board[BB(file, rank)]; + printf(" %s |", 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("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black"); + /* + * printf("Kings: W:%c%c B:%c%c\n", + * FILE2C(F88(wk->square)), + * RANK2C(R88(wk->square)), + * FILE2C(F88(bk->square)), + * RANK2C(R88(bk->square))); + */ + //printf("plies=%d clock50=%d\n", pos->plycount, pos->clock_50); + //printf("Current move = %d\n", pos->curmove); + //printf("Squares controlled: W:%d B:%d\n", popcount64(pos->controlled[WHITE]), + // popcount64(pos->controlled[BLACK])); + //printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE], + // pos->mobility[BLACK]); +} + /** * pos_pieces_print() - Print position pieces * @pos: &position @@ -81,7 +192,7 @@ void pos_pieces_print(pos_t *pos) p = pos->bb[color][piece]; count = popcount64(p); cur = 0; - pname = P_LETTER(piece); + pname = piece_to_char(piece); printf("%c(0)%s", pname, count? ":": ""); if (count) { bit_for_each64(bit, tmp, p) { @@ -101,12 +212,42 @@ void pos_pieces_print(pos_t *pos) } } + +/* +inline void bitboard_print2_raw(bitboard_t bb1, bitboard_t bb2, char *title) +{ + int i; + printf("%s%s", title? title: "", title? ":\n": ""); + + printf("\tW: %#018lx\tB: %#018lx\n", bb1, bb2); + for (i=56; i>=0; i-=8) + printf("\t"BYTE_PRINT"\t\t"BYTE_PRINT"\n", + BYTE2BIN(bb1>>i), + BYTE2BIN(bb2>>i)); +} +*/ + +/** + * raw_board_print - print simple board (hex values) + * @bb: the bitboard + */ +void raw_board_print(const pos_t *pos) +{ + + for (rank_t r = RANK_8; r >= RANK_1; --r) { + for (file_t f = FILE_A; f <= FILE_H; ++f) + printf("%02x ", pos->board[BB(f, r)]); + printf(" \n"); + } + return; +} + /** * raw_bitboard_print - print simple bitboard representation * @bb: the bitboard * @tit: a string or NULL */ -void raw_bitboard_printc(const bitboard bb, const char *tit, piece_t p) +void raw_bitboard_print(const bitboard bb, const char *tit, const piece_t p) { if (tit) printf("%s\n", tit); @@ -133,64 +274,6 @@ void raw_bitboard_printc(const bitboard bb, const char *tit, piece_t p) // //} -/** - * pos_print() - Print position on stdout. - * @pos: &position - */ -void pos_print(pos_t *pos) -{ - int rank, file; - piece_t pc, *board = pos->board; - - //piece_list_t *wk = list_first_entry(&pos->pieces[WHITE], piece_list_t, list), - // *bk = list_first_entry(&pos->pieces[BLACK], piece_list_t, list); - - - printf(" +---+---+---+---+---+---+---+---+\n"); - for (rank = 7; rank >= 0; --rank) { - printf("%c |", rank + '1'); - for (file = 0; file < 8; ++file) { - pc = board[BB(file, rank)]; - printf(" %s |", P_CSYM(pc)); - } - printf("\n +---+---+---+---+---+---+---+---+\n"); - } - printf(" A B C D E F G H\n\n"); - printf("Turn: %s.\n", IS_WHITE(pos->turn) ? "white" : "black"); - /* - * printf("Kings: W:%c%c B:%c%c\n", - * FILE2C(F88(wk->square)), - * RANK2C(R88(wk->square)), - * FILE2C(F88(bk->square)), - * RANK2C(R88(bk->square))); - */ - printf("Possible en-passant: [%#x] ", pos->en_passant); - if (pos->en_passant == 0) - printf("None.\n"); - else - printf("%c%c.\n", - FILE2C(BBfile(pos->en_passant)), - RANK2C(BBrank(pos->en_passant))); - - printf("castle [%#x] : ", pos->castle); - - if (pos->castle & CASTLE_WK) - printf("K"); - if (pos->castle & CASTLE_WQ) - printf("Q"); - if (pos->castle & CASTLE_BK) - printf("k"); - if (pos->castle & CASTLE_BQ) - printf("q"); - - printf("\nplies=%d clock50=%d\n", pos->plycount, pos->clock_50); - //printf("Current move = %d\n", pos->curmove); - //printf("Squares controlled: W:%d B:%d\n", popcount64(pos->controlled[WHITE]), - // popcount64(pos->controlled[BLACK])); - //printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE], - // pos->mobility[BLACK]); -} - /** * pos_check() - extensive position consistenci check. * @pos: &position @@ -239,46 +322,6 @@ void pos_print(pos_t *pos) * } */ -pos_t *pos_clear(pos_t *pos) -{ - printf("size(pos_board=%lu elt=%lu\n", sizeof(pos->board), sizeof(int)); - //for (square square = A1; square <= H8; ++square) - // pos->board[square] = EMPTY; - - SET_WHITE(pos->turn); - pos->node_count = 0; - pos->turn = 0; - pos->clock_50 = 0; - pos->plycount = 0; - pos->en_passant = 0; - pos->castle = 0; - memset(pos->board, 0, sizeof(pos->board)); - //pos->curmove = 0; - //pos->eval = 0; - //pos->occupied[WHITE] = 0; - //pos->occupied[BLACK] = 0; - for (color_t color = WHITE; color <= BLACK; ++color) { - for (piece_type_t piece = 0; piece <= KING; ++piece) - pos->bb[color][piece] = 0; - pos->controlled[WHITE] = 0; - pos->controlled[BLACK] = 0; - } - //pos->mobility[WHITE] = 0; - //pos->mobility[BLACK] = 0; - //pos->moves_generated = false; - //pos->moves_counted = false; - /* remove pieces / moves */ - //pieces_del(pos, WHITE); - //pieces_del(pos, BLACK); - //moves_del(pos); - - return pos; -} - -/** - * pos_del() - delete a position. - * @pos: &position. - */ /* * void pos_del(pos_t *pos) * { @@ -290,56 +333,17 @@ pos_t *pos_clear(pos_t *pos) */ -pos_t *pos_new(void) -{ - pos_t *pos = safe_malloc(sizeof(pos_t)); - //assert(pos); - return pos_clear(pos); -} - -/** - * pos_dup() - duplicate a position. - * @pos: &position to duplicate. - * - * New position is the same as source one (with duplicated pieces list), - * except: - * - moves list is empty - * - bestmove is NULL - * - nodecount is set to zero - * - eval is set to EVAL_INVALID - * - moves_generated ans moves_counted are unset - * - check is set to zero - * - * @return: The new position. - * - * TODO: merge with pos_new - NULL for init, non null for duplicate - */ -pos_t *pos_dup(pos_t *pos) -{ - pos_t *newpos= pool_get(pos_pool); - - if (newpos) { - //board = new->board; - *newpos = *pos; - //new->bestmove = NULL; - newpos->node_count = 0; - //new->eval = EVAL_INVALID; - //new->moves_generated = false; - //new->moves_counted = false; - //new->check[WHITE] = new->check[BLACK] = 0; - } - return newpos; -} - -pool_t *pos_pool_init() -{ - if (!pos_pool) - pos_pool = pool_create("positions", 128, sizeof(pos_t)); - return pos_pool; -} - -void pos_pool_stats() -{ - if (pos_pool) - pool_stats(pos_pool); -} +/******************************************************************** + * pool_t *pos_pool_init() * + * { * + * if (!pos_pool) * + * pos_pool = pool_create("positions", 128, sizeof(pos_t)); * + * return pos_pool; * + * } * + * * + * void pos_pool_stats() * + * { * + * if (pos_pool) * + * pool_stats(pos_pool); * + * } * + ********************************************************************/ diff --git a/src/position.h b/src/position.h index 4090575..3f3f6c7 100644 --- a/src/position.h +++ b/src/position.h @@ -52,52 +52,53 @@ typedef struct { /** * pos_set_sq - unconditionally set a piece on a square * @pos: position - * @p, @c: type and color of piece to add - * @f, @r: destination file and rank + * @square: square_t to set + * @piece: piece_t to add * - * Both position bords and bitboards are modified. + * Both position board and bitboards are modified. */ -static inline void pos_set_sq(pos_t *pos, piece_type_t p, color_t c, file_t f, rank_t r) +static inline void pos_set_sq(pos_t *pos, square_t square, piece_t piece) { - piece_t piece = MAKE_PIECE(p, c); - square_t square = BB(f, r); + color_t color = COLOR(piece); + piece_type_t type = PIECE(piece); pos->board[square] = piece; - pos->bb[c][ALL_PIECES] |= 1 << square; - pos->bb[c][p] |= 1 << square; + pos->bb[color][type] |= 1 << square; + pos->bb[color][ALL_PIECES] |= 1 << square; } /** * pos_clr_sq - unconditionally remove a piece from square * @pos: position - * @f, @r: destination file and rank + * @square: square_t to clear * - * Both position bords and bitboards are modified. + * Both position board and bitboards are modified. */ -static inline void pos_clr_sq(pos_t *pos, file_t f, rank_t r) +static inline void pos_clr_sq(pos_t *pos, square_t square) { - square_t square = BB(f, r); - piece_type_t piece = PIECE(pos->board[square]); - color_t color = COLOR(pos->board[square]); + piece_t piece = pos->board[square]; + piece_type_t type = PIECE(piece); + color_t color = COLOR(piece); pos->board[square] = EMPTY; - pos->bb[color][piece] &= ~(1 << square); + pos->bb[color][type] &= ~(1 << square); pos->bb[color][ALL_PIECES] &= ~(1 << square); } //void bitboard_print(bitboard_t bb, char *title); //void bitboard_print2(bitboard_t bb1, bitboard_t bb2, char *title); -void raw_bitboard_print(const bitboard bitboard, const char *title); -void pos_pieces_print(pos_t *pos); +extern pos_t *pos_new(); +extern pos_t *pos_dup(pos_t *pos); +extern void pos_del(pos_t *pos); +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 raw_bitboard_print(const bitboard bitboard, const char *title, const piece_t piece); + +//extern pos_t *pos_startpos(pos_t *pos); -//void pos_bitboards_print(pos_t *pos); -void pos_print(pos_t *pos); -pos_t *pos_clear(pos_t *pos); -//void pos_del(position *pos); -pos_t *pos_startpos(pos_t *pos); -pos_t *pos_new(); -pool_t *pos_pool_init(); -void pos_pool_stats(); -pos_t *pos_dup(pos_t *pos); //void pos_check(position *pos); #endif /* POSITION_H */ diff --git a/src/util.c b/src/util.c index 6eb3ea4..6751b28 100644 --- a/src/util.c +++ b/src/util.c @@ -16,10 +16,3 @@ #include "util.h" #include "bitboard.h" - -/*int main() -{ - char *foo = safe_malloc(1000); - exit(0); -} -*/ diff --git a/src/util.h b/src/util.h index 2ba7edb..2036366 100644 --- a/src/util.h +++ b/src/util.h @@ -24,7 +24,6 @@ #undef safe_malloc #undef safe_free - #define safe_malloc(size) ({ \ void *_ret = malloc(size); \ bug_on(_ret == NULL); \ @@ -33,7 +32,7 @@ #define safe_free(ptr) do { \ bug_on(ptr == NULL); \ - free(_ret); \ + free(ptr); \ } while (0) #endif /* UTIL_H */ diff --git a/test/fen-test.c b/test/fen-test.c index c6f85b0..0e868dd 100644 --- a/test/fen-test.c +++ b/test/fen-test.c @@ -8,15 +8,23 @@ int main(int ac, char**av) { pos_t *pos; + const char *fen; + char revfen[128]; + int comp; debug_init(5, stderr, true); - pos_pool_init(); + //pos_pool_init(); pos = pos_new(); if (ac == 1) { + fen = startfen; startpos(pos); } else { - fen2pos(pos, av[1]); + fen = av[1]; + fen2pos(pos, fen); } pos_print(pos); - printf("fen=[%s]\n", pos2fen(pos, NULL)); + pos2fen(pos, revfen); + //printf("reverse fen=[%s]\n", pos2fen(pos, NULL)); + comp = strcmp(fen, revfen); + printf("compare=%d - %s\n", comp, comp? "NOK": "OK"); }