5 Commits

13 changed files with 195 additions and 66 deletions

View File

@@ -25,20 +25,24 @@
#ifdef DEBUG_DEBUG #ifdef DEBUG_DEBUG
void debug_init(u32 level, FILE *stream); void debug_init(uint level, FILE *stream, bool flush);
void debug_level_set(u32 level); void debug_level_set(uint level);
void debug_stream_set(FILE *stream); void debug_stream_set(FILE *stream);
void _printf debug(u32 level, bool timestamp, void debug_flush_set(bool flush);
u32 indent, const char *src, void _printf debug(uint level, bool timestamp,
u32 line, const char *fmt, ...); uint indent, const char *src,
uint line, const char *fmt, ...);
#else /* DEBUG_DEBUG */ #else /* DEBUG_DEBUG */
static inline void debug_init(__unused u32 level, __unused FILE *stream) {} static inline void debug_init(__unused uint level,
static inline void debug_level_set(__unused u32 level) {} __unused FILE *stream,
_unused bool flush) {}
static inline void debug_level_set(__unused uint level) {}
static inline void debug_stream_set(__unused FILE *stream) {} static inline void debug_stream_set(__unused FILE *stream) {}
static inline void _printf debug(__unused u32 level, __unused bool timestamp, static inline void debug_flush_set(__unused bool level) {}
__unused u32 indent, __unused const char *src, static inline void _printf debug(__unused uint level, __unused bool timestamp,
__unused u32 line, __unused const char *fmt, ...) {} __unused uint indent, __unused const char *src,
__unused uint line, __unused const char *fmt, ...) {}
#endif /* DEBUG_DEBUG */ #endif /* DEBUG_DEBUG */

View File

@@ -26,10 +26,15 @@
#define MILLISEC 1000000 /* milli sec in sec */ #define MILLISEC 1000000 /* milli sec in sec */
static long long timer_start; /* in nanosecond */ static long long timer_start; /* in nanosecond */
static u32 debug_level = 0; static uint debug_level = 0;
static bool debug_flush = false;
static FILE *stream = NULL; static FILE *stream = NULL;
void debug_level_set(u32 level) /**
* debug_level_set() - set debug level.
* @level: unsigned debug level.
*/
void debug_level_set(uint level)
{ {
debug_level = level; debug_level = level;
log(0, "debug level set to %u\n", level); log(0, "debug level set to %u\n", level);
@@ -41,12 +46,19 @@ void debug_stream_set(FILE *_stream)
log(0, "stream set to %d\n", stream? fileno(stream): -1); log(0, "stream set to %d\n", stream? fileno(stream): -1);
} }
void debug_init(u32 level, FILE *_stream) void debug_flush_set(bool flush)
{
debug_flush = flush;
log(0, "debug flush set to %d\n", flush);
}
void debug_init(uint level, FILE *_stream, bool flush)
{ {
struct timespec timer; struct timespec timer;
debug_stream_set(_stream); debug_stream_set(_stream);
debug_level_set(level); debug_level_set(level);
debug_flush_set(flush);
if (!clock_gettime(CLOCK_MONOTONIC, &timer)) { if (!clock_gettime(CLOCK_MONOTONIC, &timer)) {
timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec; timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec;
} }
@@ -64,14 +76,16 @@ inline static long long timer_elapsed()
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start; return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
} }
/* void debug - log function /**
* @timestamp : boolean * debug() - log function
* @indent : indent level (2 spaces each) * @level: log level
* @src : source file/func name (or NULL) * @timestamp: boolean, print timestamp if true
* @line : line number * @indent: indent level (2 spaces each)
* @src: source file/func name (or NULL)
* @line: line number
*/ */
void debug(u32 level, bool timestamp, u32 indent, const char *src, void debug(uint level, bool timestamp, uint indent, const char *src,
u32 line, const char *fmt, ...) uint line, const char *fmt, ...)
{ {
if (!stream || level > debug_level) if (!stream || level > debug_level)
return; return;
@@ -96,6 +110,8 @@ void debug(u32 level, bool timestamp, u32 indent, const char *src,
va_start(ap, fmt); va_start(ap, fmt);
vfprintf(stream, fmt, ap); vfprintf(stream, fmt, ap);
va_end(ap); va_end(ap);
if (debug_flush)
fflush(stream);
} }
#ifdef BIN_debug #ifdef BIN_debug

View File

@@ -29,6 +29,7 @@
#include "move.h" #include "move.h"
#include "fen.h" #include "fen.h"
#include "eval.h" #include "eval.h"
#include "search.h"
struct command { struct command {
char *name; /* User printable name */ char *name; /* User printable name */
@@ -62,6 +63,8 @@ int do_eval(pos_t *, char*);
int do_move(pos_t *, char*); int do_move(pos_t *, char*);
int do_quit(pos_t *, char*); int do_quit(pos_t *, char*);
int do_debug(pos_t *, char*); int do_debug(pos_t *, char*);
int do_depth(pos_t *, char*);
int do_search(pos_t *, char*);
struct command commands[] = { struct command commands[] = {
{ "help", do_help, "Display this text" }, { "help", do_help, "Display this text" },
@@ -78,10 +81,13 @@ struct command commands[] = {
{ "eval", do_eval, "Eval current position" }, { "eval", do_eval, "Eval current position" },
{ "do_move", do_move, "execute nth move on current position" }, { "do_move", do_move, "execute nth move on current position" },
{ "debug", do_debug, "Set log level to LEVEL" }, { "debug", do_debug, "Set log level to LEVEL" },
{ "depth", do_depth, "Set search depth to N" },
{ "search", do_search, "Search best move" },
{ NULL, (int(*)()) NULL, NULL } { NULL, (int(*)()) NULL, NULL }
}; };
static int done=0; static int done=0;
static int depth=1;
int brchess(pos_t *pos) int brchess(pos_t *pos)
{ {
@@ -377,7 +383,7 @@ int do_debug(__unused pos_t *pos, __unused char *arg)
not present. */ not present. */
int do_help(__unused pos_t *pos, __unused char *arg) int do_help(__unused pos_t *pos, __unused char *arg)
{ {
register int i; int i;
int printed = 0; int printed = 0;
for (i = 0; commands[i].name; i++) { for (i = 0; commands[i].name; i++) {
@@ -407,6 +413,23 @@ int do_help(__unused pos_t *pos, __unused char *arg)
return 0; return 0;
} }
int do_depth(__unused pos_t *pos, char *arg)
{
depth = atoi(arg);
printf("depth = %d\n", depth);
return 1;
}
int do_search(pos_t *pos, __unused char *arg)
{
printf("++++++++\nnegamax=%d\n", negamax(pos, depth, pos->turn==WHITE? 1:-1));
printf("best=");
move_print(0, pos->bestmove, 0);
printf("score=%d\n", pos->bestmove->negamax);
return 1;
}
#ifdef BIN_brchess #ifdef BIN_brchess
/** main() /** main()
* options: * options:
@@ -430,7 +453,7 @@ int main(int ac, char **av)
moves_pool_init(); moves_pool_init();
pos_pool_init(); pos_pool_init();
pos = pos_get(); pos = pos_get();
debug_init(1, stderr); debug_init(1, stderr, true);
while ((opt = getopt(ac, av, "d:f:")) != -1) { while ((opt = getopt(ac, av, "d:f:")) != -1) {
switch (opt) { switch (opt) {

View File

@@ -112,5 +112,6 @@ typedef s32 eval_t;
typedef struct piece_list_s piece_list_t; typedef struct piece_list_s piece_list_t;
typedef struct board_s board_t; typedef struct board_s board_t;
typedef struct pos_s pos_t; typedef struct pos_s pos_t;
typedef struct move_s move_t;
#endif #endif

View File

@@ -98,7 +98,7 @@ int main(int ac, char**av)
pos_t *pos; pos_t *pos;
eval_t res; eval_t res;
debug_init(5, stderr); debug_init(5, stderr, true);
piece_pool_init(); piece_pool_init();
moves_pool_init(); moves_pool_init();

View File

@@ -179,7 +179,7 @@ int main(int ac, char**av)
{ {
pos_t *pos; pos_t *pos;
debug_init(5, stderr); debug_init(5, stderr, true);
piece_pool_init(); piece_pool_init();
pos_pool_init(); pos_pool_init();
pos = pos_get(); pos = pos_get();

View File

@@ -73,18 +73,19 @@ void moves_pool_stats()
* M_PR_NCAPT: print move if non capture * M_PR_NCAPT: print move if non capture
* M_PR_NUM: print also move number * M_PR_NUM: print also move number
* M_PR_LONG: print long notation * M_PR_LONG: print long notation
* M_PR_NL: print a newline after move
* *
* @return: 0 if nothing printed, 1 otherwise * @return: 0 if nothing printed, 1 otherwise
*/ */
int move_print(int movenum, move_t *move, move_flags_t flags) int move_print(int movenum, move_t *move, move_flags_t flags)
{ {
if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) { if ((flags & M_PR_CAPT) && !(move->flags & M_CAPTURE)) {
# ifdef DEBUG_MOVE # ifdef DEBUG_MOVE
log_i(9, "skipping capture & %#04x\n", move->flags); log_i(9, "skipping capture & %#04x\n", move->flags);
# endif # endif
return 0; return 0;
} }
if (flags & M_PR_NCAPT && move->flags & M_CAPTURE) { if ((flags & M_PR_NCAPT) && (move->flags & M_CAPTURE)) {
# ifdef DEBUG_MOVE # ifdef DEBUG_MOVE
log_i(9, "skipping !capture & %#04x\n", move->flags); log_i(9, "skipping !capture & %#04x\n", move->flags);
# endif # endif
@@ -119,6 +120,8 @@ int move_print(int movenum, move_t *move, move_flags_t flags)
end: end:
printf(" "); printf(" ");
} }
if (flags & M_PR_NL)
printf("\n");
return 1; return 1;
} }
@@ -660,9 +663,10 @@ void moves_gen_all(pos_t *pos)
{ {
moves_gen(pos, OPPONENT(pos->turn), false, false); moves_gen(pos, OPPONENT(pos->turn), false, false);
moves_gen(pos, pos->turn, true, true); moves_gen(pos, pos->turn, true, true);
moves_gen_king_moves(pos, OPPONENT(pos->turn), true); moves_gen_king_moves(pos, OPPONENT(pos->turn), false);
} }
/** /**
* move_do() - execute move in a duplicated position. * move_do() - execute move in a duplicated position.
* @pos: &pos_t struct on which move will be applied * @pos: &pos_t struct on which move will be applied
@@ -672,13 +676,12 @@ void moves_gen_all(pos_t *pos)
pos_t *move_do(pos_t *pos, move_t *move) pos_t *move_do(pos_t *pos, move_t *move)
{ {
# ifdef DEBUG_MOVE # ifdef DEBUG_MOVE
log_f(3, "++++++++++"); printf("++++++++++ ");
move_print(0, move, 0); move_print(0, move, M_PR_NL | M_PR_LONG | M_PR_NUM);
log(3, "\n");
# endif # endif
pos_t *new = pos_dup(pos); pos_t *new = pos_dup(pos);
piece_t piece = move->piece; piece_t piece = PIECE(move->piece), newpiece = piece, captured = move->capture;
int color = COLOR(piece); int color = COLOR(piece);
square_t from = move->from, to = move->to; square_t from = move->from, to = move->to;
@@ -692,7 +695,7 @@ pos_t *move_do(pos_t *pos, move_t *move)
piece_del(&new->board[to].s_piece->list); piece_del(&new->board[to].s_piece->list);
new->board[to].piece = 0; new->board[to].piece = 0;
new->occupied[OPPONENT(color)] ^= SQ88_2_BB(to); new->occupied[OPPONENT(color)] ^= SQ88_2_BB(to);
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(to); new->bb[OPPONENT(color)][PIECETOBB(captured)] ^= SQ88_2_BB(to);
} else { } else {
uchar ep_file = F88(pos->en_passant); uchar ep_file = F88(pos->en_passant);
square_t ep_grab = color == WHITE ? SQ88(ep_file, 4): SQ88(ep_file, 3); square_t ep_grab = color == WHITE ? SQ88(ep_file, 4): SQ88(ep_file, 3);
@@ -700,7 +703,7 @@ pos_t *move_do(pos_t *pos, move_t *move)
piece_del(&new->board[ep_grab].s_piece->list); piece_del(&new->board[ep_grab].s_piece->list);
new->board[ep_grab].piece = 0; new->board[ep_grab].piece = 0;
new->occupied[OPPONENT(color)] ^= SQ88_2_BB(ep_grab); new->occupied[OPPONENT(color)] ^= SQ88_2_BB(ep_grab);
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(ep_grab); new->bb[OPPONENT(color)][BB_PAWN] ^= SQ88_2_BB(ep_grab);
} }
} else if (move->flags & M_CASTLE_Q) { } else if (move->flags & M_CASTLE_Q) {
@@ -729,21 +732,25 @@ pos_t *move_do(pos_t *pos, move_t *move)
new->board[rook_from].s_piece = NULL; new->board[rook_from].s_piece = NULL;
} }
new->board[to] = new->board[from];
/* fix dest square */
new->board[to].s_piece->square = to;
if (move->flags & M_PROMOTION) { if (move->flags & M_PROMOTION) {
log(2, "promotion to %s\n", P_SYM(move->piece)); log(2, "promotion to %s\n", P_SYM(move->promotion));
printf("newpiece=%#x p=%#x\n", move->promotion, PIECE(move->promotion));
newpiece = PIECE(move->promotion);
new->board[to].piece = move->promotion; new->board[to].piece = move->promotion;
new->board[to].s_piece->square = to;
new->board[to].s_piece->piece = move->promotion; new->board[to].s_piece->piece = move->promotion;
} else {
new->board[to] = new->board[from];
/* fix dest square */
new->board[to].s_piece->square = to;
} }
/* replace old occupied bitboard by new one */ /* replace old occupied bitboard by new one */
new->occupied[color] ^= SQ88_2_BB(from); new->occupied[color] ^= SQ88_2_BB(from);
new->occupied[color] |= SQ88_2_BB(to); new->occupied[color] |= SQ88_2_BB(to);
new->bb[color][PIECETOBB(piece)] ^= SQ88_2_BB(from); new->bb[color][PIECETOBB(piece)] ^= SQ88_2_BB(from);
new->bb[color][PIECETOBB(piece)] |= SQ88_2_BB(to); new->bb[color][PIECETOBB(newpiece)] |= SQ88_2_BB(to);
if (move->flags & M_PROMOTION) {
printf("color=%d bbpiece=%d\n", color, PIECETOBB(newpiece));
bitboard_print(new->bb[color][PIECETOBB(newpiece)]);
}
/* always make "from" square empty */ /* always make "from" square empty */
new->board[from].piece = 0; new->board[from].piece = 0;
@@ -765,7 +772,7 @@ int main(int ac, char**av)
{ {
pos_t *pos; pos_t *pos;
debug_init(5, stderr); debug_init(5, stderr, true);
piece_pool_init(); piece_pool_init();
moves_pool_init(); moves_pool_init();
pos_pool_init(); pos_pool_init();

View File

@@ -35,6 +35,7 @@ typedef unsigned char move_flags_t;
#define M_PR_CAPT 0x01 #define M_PR_CAPT 0x01
#define M_PR_NCAPT 0x02 #define M_PR_NCAPT 0x02
#define M_PR_NUM 0x04 #define M_PR_NUM 0x04
#define M_PR_NL 0x08
#define M_PR_SEPARATE 0x40 /* separate captures */ #define M_PR_SEPARATE 0x40 /* separate captures */
#define M_PR_LONG 0x80 #define M_PR_LONG 0x80
@@ -44,6 +45,7 @@ typedef struct move_s {
piece_t capture; /* captured piece */ piece_t capture; /* captured piece */
piece_t promotion; /* promoted piece */ piece_t promotion; /* promoted piece */
move_flags_t flags; move_flags_t flags;
eval_t negamax;
struct list_head list; /* next move */ struct list_head list; /* next move */
} move_t; } move_t;
@@ -65,4 +67,4 @@ void moves_gen_all(pos_t *pos);
pos_t *move_do(pos_t *pos, move_t *move); pos_t *move_do(pos_t *pos, move_t *move);
void move_undo(pos_t *pos, move_t *move); void move_undo(pos_t *pos, move_t *move);
#endif /* MODE_H */ #endif /* MOVE_H */

View File

@@ -122,7 +122,7 @@ int main(int ac, char**av)
{ {
pos_t *pos; pos_t *pos;
printf("zobi\n");fflush(stdout); printf("zobi\n");fflush(stdout);
debug_init(6, stderr); debug_init(6, stderr, true);
log_f(5, "kfsjdhg\n"); log_f(5, "kfsjdhg\n");
pos_pool_init(); pos_pool_init();
pos = pos_get(); pos = pos_get();

View File

@@ -54,6 +54,10 @@ inline void bitboard_print2(bitboard_t bb1, bitboard_t bb2)
BYTE2BIN(bb2>>i)); BYTE2BIN(bb2>>i));
} }
/**
* pos_pieces_print() - Print position pieces
* @pos: &position
*/
void pos_pieces_print(pos_t *pos) void pos_pieces_print(pos_t *pos)
{ {
printf("White pieces (%d): \t", popcount64(pos->occupied[WHITE])); printf("White pieces (%d): \t", popcount64(pos->occupied[WHITE]));
@@ -62,10 +66,22 @@ void pos_pieces_print(pos_t *pos)
piece_list_print(&pos->pieces[BLACK]); piece_list_print(&pos->pieces[BLACK]);
} }
/* void pos_print - Print position on stdout. /**
* @pos: Position address (pos_t * ) * pos_bitboards_print() - Print position bitboards
* * @pos: &position
* Return: None. */
void pos_bitboards_print(pos_t *pos)
{
printf("Bitboards occupied :\n");
bitboard_print2(pos->occupied[WHITE], pos->occupied[BLACK]);
printf("Bitboards controlled :\n");
bitboard_print2(pos->controlled[WHITE], pos->controlled[BLACK]);
}
/**
* pos_print() - Print position on stdout.
* @pos: &position
*/ */
void pos_print(pos_t *pos) void pos_print(pos_t *pos)
{ {
@@ -119,10 +135,54 @@ void pos_print(pos_t *pos)
popcount64(pos->controlled[BLACK])); popcount64(pos->controlled[BLACK]));
printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE], printf("Mobility: W:%u B:%u\n", pos->mobility[WHITE],
pos->mobility[BLACK]); pos->mobility[BLACK]);
printf("Bitboards occupied :\n"); }
bitboard_print2(pos->occupied[WHITE], pos->occupied[BLACK]);
printf("Bitboards controlled :\n"); /**
bitboard_print2(pos->controlled[WHITE], pos->controlled[BLACK]); * pos_check() - extensive position consistenci check.
* @pos: &position
*/
void pos_check(pos_t *pos)
{
int rank, file;
piece_t piece;
board_t *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);
/* check that board and bitboard reflect same information */
for (rank = 7; rank >= 0; --rank) {
for (file = 0; file < 8; ++file) {
piece_list_t *ppiece;
printf("checking %c%c ", file+'a', rank+'1');
piece = board[SQ88(file, rank)].piece;
ppiece= board[SQ88(file, rank)].s_piece;
printf("piece=%s ", P_CSYM(piece));
if (ppiece)
printf("ppiece=%s/sq=%#x ", P_CSYM(ppiece->piece), ppiece->square);
switch(PIECE(piece)) {
case PAWN:
printf("pawn" );
break;
case KNIGHT:
printf("knight ");
break;
case BISHOP:
printf("bishop ");
break;
case ROOK:
printf("rook ");
break;
case QUEEN:
printf("queen ");
break;
case KING:
printf("king ");
break;
}
printf("\n");
}
}
} }
pos_t *pos_clear(pos_t *pos) pos_t *pos_clear(pos_t *pos)
@@ -203,7 +263,7 @@ pos_t *pos_get()
* @pos: &position to duplicate. * @pos: &position to duplicate.
* *
* New position is the same as source one, with duplicated pieces list * New position is the same as source one, with duplicated pieces list
* and empty moves list. * and empty moves list and NULL bestmove.
* *
* @return: The new position. * @return: The new position.
* *
@@ -219,10 +279,10 @@ pos_t *pos_dup(pos_t *pos)
if (new) { if (new) {
board = new->board; board = new->board;
*new = *pos; *new = *pos;
for (int color=0; color<2; ++color) { for (int color = 0; color < 2; ++color) {
INIT_LIST_HEAD(&new->pieces[color]); INIT_LIST_HEAD(&new->pieces[color]);
INIT_LIST_HEAD(&new->moves[color]); INIT_LIST_HEAD(&new->moves[color]);
new->bestmove = NULL;
/* duplicate piece list */ /* duplicate piece list */
piece_list = &pos->pieces[color]; /* white/black piece list */ piece_list = &pos->pieces[color]; /* white/black piece list */

View File

@@ -28,6 +28,7 @@ typedef struct pos_s {
u16 clock_50; u16 clock_50;
u16 curmove; u16 curmove;
eval_t eval; eval_t eval;
move_t *bestmove;
board_t board[BOARDSIZE]; board_t board[BOARDSIZE];
square_t en_passant; square_t en_passant;
@@ -43,6 +44,7 @@ typedef struct pos_s {
void bitboard_print(bitboard_t bb); void bitboard_print(bitboard_t bb);
void bitboard_print2(bitboard_t bb1, bitboard_t bb2); void bitboard_print2(bitboard_t bb1, bitboard_t bb2);
void pos_pieces_print(pos_t *pos); void pos_pieces_print(pos_t *pos);
void pos_bitboards_print(pos_t *pos);
void pos_print(pos_t *pos); void pos_print(pos_t *pos);
pos_t *pos_clear(pos_t *pos); pos_t *pos_clear(pos_t *pos);
void pos_del(pos_t *pos); void pos_del(pos_t *pos);
@@ -52,5 +54,6 @@ pool_t *pos_pool_init();
void pos_pool_stats(); void pos_pool_stats();
pos_t *pos_get(); pos_t *pos_get();
pos_t *pos_dup(pos_t *pos); pos_t *pos_dup(pos_t *pos);
void pos_check(pos_t *pos);
#endif /* POSITION_H */ #endif /* POSITION_H */

View File

@@ -24,28 +24,41 @@
* negamax() - the negamax tree. * negamax() - the negamax tree.
* *
*/ */
eval_t negamax(pos_t *pos, int depth) eval_t negamax(pos_t *pos, int depth, int color)
{ {
move_t *move, *bestmove; move_t *move, bestmove;
pos_t *newpos; pos_t *newpos;
eval_t best = EVAL_MIN, score; eval_t best = EVAL_MIN, score;
printf("depth=%d\n", depth);
moves_gen_all(pos); moves_gen_all(pos);
if (depth == 0) //pos_check(pos);
return eval(pos) * pos->turn == WHITE? 1: -1; if (depth == 0) {
score = eval(pos);
printf("evalnega=%d turn=%d color=%d", score, pos->turn, color);
score *= color;
printf(" --> evalnega=%d\n", score);
return score;
}
moves_print(pos, 0);
list_for_each_entry(move, &pos->moves[pos->turn], list) { list_for_each_entry(move, &pos->moves[pos->turn], list) {
newpos = move_do(pos, move); newpos = move_do(pos, move);
score = -negamax(newpos, depth - 1 ); score = -negamax(newpos, depth - 1, -color);
if(score > best) { move->negamax = score;
printf("move=");
move_print(0, move, 0);
printf("score=%d\n", score);
if (score > best) {
best = score; best = score;
bestmove = move; pos->bestmove = move;
# ifdef DEBUG_SEARCH # ifdef DEBUG_SEARCH
log_f(2, "depth=%d best move=", best); printf("depth=%d best move=", depth);
move_print(0, bestmove, M_PR_LONG); move_print(0, &bestmove, 0);
log_f(2, " eval=%d\n", best); printf(" eval=%d\n", best);
# endif # endif
} }
move_undo(newpos, move);
} }
return best; return best;
} }

View File

@@ -20,6 +20,6 @@
#define EVAL_MIN INT_MIN #define EVAL_MIN INT_MIN
#define EVAL_MAX INT_MAX #define EVAL_MAX INT_MAX
eval_t negamax(pos_t *pos, int depth); eval_t negamax(pos_t *pos, int depth, int color);
#endif /* SEARCH_H */ #endif /* SEARCH_H */