diff --git a/src/eval-simple.c b/src/eval-simple.c index 3a1420f..115254e 100644 --- a/src/eval-simple.c +++ b/src/eval-simple.c @@ -48,19 +48,15 @@ eval_t eval_material(pos_t *pos) * eval_simple() - simple and fast position evaluation * @pos: &position to evaluate * - * This function is normally used only during initialization, - * or when changing phase (middlegame <--> endgame), as the eval - * will be done incrementally when doing moves. - * * @return: the @pos evaluation in centipawns */ eval_t eval_simple(pos_t *pos) { - eval_t eval[2] = { 0, 0 }; + eval_t eval[2] = { 0, 0 }, res; eval_t mg_eval[2], eg_eval[2]; - //struct pc_sq = sq_ int (*gg)[6 + 2][64] = eg? pc_sq_eg: pc_sq_mg; - //pos->eval_simple_phase = ENDGAME; + int eg_weight = clamp((int) pos->phase, ALL_PHASE, 0); + int mg_weight = ALL_PHASE - pos->phase; for (color_t color = WHITE; color < COLOR_NB; ++color) { mg_eval[color] = 0; @@ -80,10 +76,15 @@ eval_t eval_simple(pos_t *pos) } } + eval[WHITE] = mg_eval[WHITE] * mg_weight + eg_eval[WHITE] * eg_weight; + eval[BLACK] = mg_eval[BLACK] * mg_weight + eg_eval[BLACK] * eg_weight; + res = (eval[WHITE] - eval[BLACK]) / ALL_PHASE; # ifdef DEBUG_EVAL - printf("phase:%d mg[WHITE]:%d mg[BLACK]:%d eg[WHITE]:%d eg[BLACK]:%d\n", - pos->phase, mg_eval[WHITE], mg_eval[BLACK], eg_eval[WHITE], eg_eval[BLACK]); + printf("phase:%d mg:%d/%d eg:%d/%d ev:%d/%d RES=%d\n", + pos->phase, mg_eval[WHITE], mg_eval[BLACK], + eg_eval[WHITE], eg_eval[BLACK], + eval[WHITE], eval[BLACK], res + ); # endif - - return eval[WHITE] - eval[BLACK]; + return res; } diff --git a/src/hash.h b/src/hash.h index db56fc6..19ee21e 100644 --- a/src/hash.h +++ b/src/hash.h @@ -44,14 +44,16 @@ typedef u64 hkey_t; /* cannot use typedef for key_ * 16 bytes in future, it should be updated to be exactly 32 bytes. */ typedef struct { - hkey_t key; /* zobrist */ + hkey_t key; /* position key */ union { u64 data; struct { - u16 depth; /* ply in search */ - s16 eval; - move_t move; - //u8 flags; /* maybe for locking, etc... */ + s16 eval; /* 16: eval */ + move_t move; /* 16: best move */ + u8 depth; /* 8: search depth */ + u8 gen8; /* 8: search generation */ + + //flags; /* maybe for locking, etc... */ //u8 filler; }; }; diff --git a/src/search.c b/src/search.c index c0633e3..373cb8c 100644 --- a/src/search.c +++ b/src/search.c @@ -15,6 +15,8 @@ #include +#include "chessdefs.h" + #include "position.h" #include "move-gen.h" #include "move-do.h" @@ -22,6 +24,8 @@ #include "attack.h" #include "hist.h" +search_uci_t search_uci; + /** * is_draw() - check if position is draw by 50 or repetition rule. * @pos: &position to search @@ -55,20 +59,25 @@ eval_t negamax(pos_t *pos, int depth, int color) movelist_t movelist; pos->node_count++; + + if (pos_repcount(pos)) /* repetition */ + return EVAL_DRAW * color; + + pos_set_checkers_pinners_blockers(pos); + pos_gen_legal(pos, &movelist); + + if (!movelist.nmoves) /* no move: mate ot draw */ + return (pos->checkers? EVAL_MATE: EVAL_DRAW) * color; + if (depth == 0) { score = eval(pos) * color; return score; } - pos_set_checkers_pinners_blockers(pos); - pos_gen_legal(pos, &movelist); + last = movelist.move + movelist.nmoves; - //moves_gen_all(pos); for (move = movelist.move; move < last; ++move) { - //list_for_each_entry(move, &pos->moves[pos->turn], list) { move_do(pos, *move, &state); score = -negamax(pos, depth - 1, -color); - pos->node_count += pos->node_count; - //move->negamax = score; if (score > best) { best = score; pos->eval = best; @@ -78,6 +87,21 @@ eval_t negamax(pos_t *pos, int depth, int color) return best; } +/** + * search() - do (iterative) search. + * @pos: &position to search + * @depth: wanted depth. + * @alpha: alpha. + * @beta: beta. + * @color: 1 for white, -1 for black. + * + * + * @return: The @pos PVS evaluation. + */ +void search(__unused pos_t *pos) +{ + +} /** * pvs() - Principal Variation Search. diff --git a/src/search.h b/src/search.h index 3b73978..880527f 100644 --- a/src/search.h +++ b/src/search.h @@ -16,8 +16,21 @@ #include "position.h" +/** + * search_values_t - search values given by "go" command + * @depth: max depth "go depth X", MAX_DEPTH for no limit + * + * + */ +typedef struct { + u16 depth; /* go depth X */ +} search_uci_t; + +extern search_uci_t search_uci; + bool is_draw(pos_t *pos); -//eval_t negamax(pos_t *pos, int depth, int color); +eval_t negamax(pos_t *pos, int depth, int color); +void search(pos_t *pos); //eval_t pvs(pos_t *pos, int depth, int alpha, int beta, int color); #endif /* SEARCH_H */ diff --git a/src/uci.c b/src/uci.c index 6054d6a..8df42e7 100644 --- a/src/uci.c +++ b/src/uci.c @@ -17,6 +17,7 @@ #include #include +#include #include "chessdefs.h" #include "util.h" @@ -50,6 +51,7 @@ int do_quit(pos_t *, char *); int do_setoption(pos_t *, char *); int do_position(pos_t *, char *); +int do_go(pos_t *, char *); /* commands *NOT* in UCI standard */ int do_moves(pos_t *, char *); @@ -66,6 +68,8 @@ struct command commands[] = { { "isready", do_isready, "" }, { "setoption", do_setoption, ""}, { "position", do_position, "position startpos|fen [moves ...]" }, + { "go", do_go, "go" }, + { "perft", do_perft, "(not UCI) perft [divide] [alt] depth" }, { "moves", do_moves, "(not UCI) moves ..." }, @@ -334,13 +338,12 @@ int do_setoption(__unused pos_t *pos, __unused char *arg) int do_position(pos_t *pos, char *arg) { - char *saveptr, *token, *fen, *moves; + char *saveptr = NULL, *token, *fen, *moves; hist_init(); /* separate "moves" section */ moves = str_token(arg, "moves"); - saveptr = NULL; token = strtok_r(arg, " ", &saveptr); if (!strcmp(token, "startpos")) { startpos(pos); @@ -374,13 +377,56 @@ int do_position(pos_t *pos, char *arg) return 1; } + +int do_go(pos_t *pos, char *arg) +{ + char *ptr = NULL, *tok, *val; + + //token = strtok_r(arg, " ", &saveptr); + for (tok = strtok_r(arg, " ", &ptr); tok; tok = strtok_r(arg, " ", &ptr)) { + /* TODO: Find a "clever" way to get the different values without + * multiple "strcmp" + */ + + if (!strcmp(tok, "searchmoves")) { /* moves list */ + ; + } else if (!strcmp(tok, "wtime")) { /* integer */ + ; + } else if (!strcmp(tok, "btime")) { /* integer */ + ; + } else if (!strcmp(tok, "winc")) { /* integer */ + ; + } else if (!strcmp(tok, "binc")) { /* integer */ + ; + } else if (!strcmp(tok, "movestogo")) { /* integer */ + ; + } else if (!strcmp(tok, "depth")) { /* integer */ + if ((val = strtok_r(arg, " ", &ptr))) + search_uci.depth = atoi(val); + ; + } else if (!strcmp(tok, "nodes")) { /* integer */ + ; + } else if (!strcmp(tok, "mate")) { /* integer */ + ; + } else if (!strcmp(tok, "movetime")) { /* integer */ + ; + } else if (!strcmp(tok, "ponder")) { /* no param */ + ; + } else if (!strcmp(tok, "infinite")) { /* no param */ + ; + } + + } + search(pos); + return 1; +} + int do_moves(__unused pos_t *pos, char *arg) { char *saveptr = NULL, *token, check[8]; move_t move; movelist_t movelist; - saveptr = NULL; token = strtok_r(arg, " ", &saveptr); while (token) { move = move_from_str(token);