Compare commits
5 Commits
120a459206
...
48319cf21a
| Author | SHA1 | Date | |
|---|---|---|---|
| 48319cf21a | |||
| 0b787c8a90 | |||
| 4bca805404 | |||
| 0df87ff41c | |||
| 892bdcd004 |
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
41
src/move.c
41
src/move.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (move->flags & M_PROMOTION) {
|
|
||||||
log(2, "promotion to %s\n", P_SYM(move->piece));
|
|
||||||
new->board[to].piece = move->promotion;
|
|
||||||
new->board[to].s_piece->square = to;
|
|
||||||
new->board[to].s_piece->piece = move->promotion;
|
|
||||||
} else {
|
|
||||||
new->board[to] = new->board[from];
|
new->board[to] = new->board[from];
|
||||||
/* fix dest square */
|
/* fix dest square */
|
||||||
new->board[to].s_piece->square = to;
|
new->board[to].s_piece->square = to;
|
||||||
|
if (move->flags & M_PROMOTION) {
|
||||||
|
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].s_piece->piece = move->promotion;
|
||||||
}
|
}
|
||||||
/* 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();
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
35
src/search.c
35
src/search.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user