37#define ENGINE_N_POSITION 1024
65 va_start(args, format);
66 vprintf(format, args);
68 putchar(
'\n'); fflush(stdout);
73 va_start(args, format);
88 char protocol[32], cmd[32];
90 char *buffer_with_garbage;
96 fprintf(
engine_log->
f,
"received< \"%s\"\n", buffer_with_garbage);
99 if (buffer_with_garbage == NULL) {
104 buffer =
parse_word(buffer_with_garbage, protocol, 32);
106 if (strcmp(protocol,
"ENGINE-PROTOCOL") == 0) {
111 if (strcmp(cmd,
"stop") == 0) {
118 }
else if (strcmp(cmd,
"get-search-infos") == 0) {
125 if (strcmp(cmd,
"quit") == 0) {
133 condition_signal(event);
137 }
else if (*protocol ==
'\0') {
144 engine_send(
"ERROR: Unknown protocol \"%s\"", buffer_with_garbage);
147 free(buffer_with_garbage);
172 while (engine->
event->
loop && !feof(stdin) && !ferror(stdin)) {
220 n += sprintf(
engine_result + n,
", depth %d, @%d%%, %c%+d.00 <= v <= %c%+d.00, ",
243 if (search == NULL) {
244 engine_send(
"ERROR: Cannot allocate a new search engine.");
268static int engine_open(
Search *search,
const Board *board,
const int player,
const int alpha,
const int beta,
const int depth,
const int precision)
308 else score = (hash_data->
upper + hash_data->
lower) / 2;
325 search->
depth = depth;
334 else if (precision <= 73) k = 0;
335 else if (precision <= 87) k = 1;
336 else if (precision <= 95) k = 2;
337 else if (precision <= 98) k = 3;
338 else if (precision <= 99) k = 4;
383 if (engine == NULL) {
384 engine_send(
"ERROR: Cannot allocate a new engine.");
419 hash_feed(search->
pv_table, board, hash_code, depth, selectivity, lower, upper, move);
437 int i, selectivity, tmp;
439 Move *move, *child_move;
440 MoveList movelist[1], child_movelist[1];
443 else if (precision <= 73) selectivity = 0;
444 else if (precision <= 87) selectivity = 1;
445 else if (precision <= 95) selectivity = 2;
446 else if (precision <= 98) selectivity = 3;
447 else if (precision <= 99) selectivity = 4;
448 else selectivity = 5;
452 for (i = 0; i <= pv->
n_moves; ++i) {
453 current_depth = depth - i;
461 if (move->
x == pv->
move[i]) {
479 if (move && move->
x == pv->
move[i]) {
538 if (alpha < hash_data->lower) alpha = *old_score = hash_data->
lower;
539 if (beta > hash_data->
upper) beta = *old_score = hash_data->
upper;
545 bestmove->
score = *old_score;
554 cassio_debug(
"Edax does not skip the search : BAD PV!\n");
560 cassio_debug(
"Edax does not skip the search: unsolved score alpha %d < beta %d\n", alpha, beta);
585double engine_midgame_search(
void *v,
const char *position,
const double alpha,
const double beta,
const int depth,
const int precision)
593 if (search == NULL) {
594 engine_send(
"ERROR: Engine need to be initialized.");
601 old_score =
engine_open(search, board, player, floor(alpha), ceil(beta), depth, precision);
639 if (search == NULL) {
640 engine_send(
"ERROR: Engine need to be initialized.");
648 old_score =
engine_open(search, board, player, alpha, beta, depth, precision);
673 if (search == NULL) {
674 engine_send(
"ERROR: Engine need to be initialized.");
685 char *cmd = NULL, *param = NULL;
694 if (cmd == NULL || *cmd ==
'\0') {
696 }
else if (strcmp(cmd,
"init") == 0) {
699 }
else if (strcmp(cmd,
"get-version") == 0) {
703 }
else if (strcmp(cmd,
"new-position") == 0) {
707 }
else if (strcmp(cmd,
"feed-hash") == 0) {
708 int depth = 21, precision = 73, player;
716 if (
string == param)
engine_send(
"Error: in feed-hash, Edax cannot parse position.");
719 if (errno)
engine_send(
"Error: in feed-hash, Edax cannot parse lower.");
722 if (errno)
engine_send(
"Error: in feed-hash, Edax cannot parse upper.");
725 if (errno)
engine_send(
"Error: in feed-hash, Edax cannot parse depth.");
728 if (errno)
engine_send(
"Error: in feed-hash, Edax cannot parse precision.");
732 engine_feed_hash(engine, board, floor(lower), ceil(upper), depth, precision, pv);
739 }
else if (strcmp(cmd,
"empty-hash") == 0) {
742 }
else if (strcmp(cmd,
"quit") == 0 || strcmp(cmd,
"eof") == 0) {
751 }
else if (strcmp(cmd,
"midgame-search") == 0) {
753 int player, depth = 60, precision = 100;
760 if (s == param)
engine_send(
"ERROR: midgame-search cannot parse position.");
763 if (errno)
engine_send(
"ERROR: midgame-search cannot parse alpha.");
766 if (errno)
engine_send(
"ERROR: midgame_search cannot parse beta.");
769 if (errno)
engine_send(
"ERROR: midgame_search cannot parse depth.");
772 if (errno)
engine_send(
"ERROR: midgame_search cannot parse precision.");
780 }
else if (strcmp(cmd,
"endgame-search") == 0) {
782 int player, precision = 100;
789 if (s == param)
engine_send(
"ERROR: endgame_search cannot parse position.");
792 if (errno)
engine_send(
"ERROR: endgame_search cannot parse alpha.");
795 if (errno)
engine_send(
"ERROR: endgame_search cannot parse beta.");
798 if (errno)
engine_send(
"ERROR: endgame_search cannot parse precision.");
unsigned long long board_get_hash_code(const Board *board)
Compute a hash code.
Definition board.c:1134
void board_restore(Board *board, const Move *move)
Restore a board.
Definition board.c:487
void board_update(Board *board, const Move *move)
Update a board.
Definition board.c:469
int board_count_empties(const Board *board)
Check if the game is over.
Definition board.c:1216
int get_stability(const unsigned long long P, const unsigned long long O)
Estimate the stability.
Definition board.c:1067
char * board_to_string(const Board *board, const int player, char *s)
convert the to a compact string.
Definition board.c:1272
bool board_is_pass(const Board *board)
Check if current player should pass.
Definition board.c:1191
bool board_equal(const Board *b1, const Board *b2)
Compare two board for equality.
Definition board.c:335
int board_set(Board *board, const char *string)
Set a board from a string description.
Definition board.c:154
void board_pass(Board *board)
Passing move.
Definition board.c:503
void engine_stop(void *v)
Stop searching.
Definition cassio.c:670
static void engine_close(Search *search)
Finalize search.
Definition cassio.c:355
static void engine_wait_input(Engine *engine, char **cmd, char **param)
Engine wait input.
Definition cassio.c:157
void engine_loop(void)
Loop event.
Definition cassio.c:683
static Search * engine_create_search(void)
Create engine search.
Definition cassio.c:238
void feed_all_hash_table(Search *search, Board *board, const int depth, const int selectivity, const int lower, const int upper, const int move)
Definition cassio.c:414
Log engine_log[1]
Definition cassio.c:35
void * engine_init(void)
Create a new Othello engine.
Definition cassio.c:376
int engine_endgame_search(void *v, const char *position, const int alpha, const int beta, const int precision)
Endgame search.
Definition cassio.c:630
double engine_midgame_search(void *v, const char *position, const double alpha, const double beta, const int depth, const int precision)
Midgame search.
Definition cassio.c:585
static char last_line_sent[1024]
Definition cassio.c:42
static bool is_position_new(Engine *engine, Board *board)
Definition cassio.c:186
static void * engine_input_loop(void *v)
Read event loop.
Definition cassio.c:167
static char engine_result[1024]
Definition cassio.c:40
#define ENGINE_N_POSITION
Definition cassio.c:37
static bool skip_search(Engine *engine, int *old_score)
Check if a search has already been done here.
Definition cassio.c:520
static int engine_open(Search *search, const Board *board, const int player, const int alpha, const int beta, const int depth, const int precision)
Open search engine.
Definition cassio.c:268
static void engine_get_input(Engine *engine)
Read an input line.
Definition cassio.c:86
void engine_empty_hash(void *v)
Empty (ie completely clear) the engine hash table.
Definition cassio.c:501
void engine_free(void *v)
free resources allocated
Definition cassio.c:402
static void engine_observer(Result *result)
Call back function use by search to print its results.
Definition cassio.c:214
void engine_feed_hash(void *v, Board *board, int lower, int upper, const int depth, const int precision, Line *pv)
feed hash table
Definition cassio.c:433
static void engine_send(const char *format,...)
Send a message on stdout.
Definition cassio.c:61
#define SCORE_MAX
Definition const.h:58
#define SCORE_INF
Definition const.h:52
@ PASS
Definition const.h:37
@ NOMOVE
Definition const.h:37
#define VERSION_STRING
Definition const.h:88
@ WHITE
Definition const.h:43
@ BLACK
Definition const.h:42
@ RUNNING
Definition const.h:71
@ STOP_ON_DEMAND
Definition const.h:75
@ STOP_END
Definition const.h:76
@ PV_NODE
Definition const.h:81
#define SCORE_MIN
Definition const.h:55
void event_clear_messages(Event *event)
Remove all unprocessed messages.
Definition event.c:45
void event_init(Event *event)
Initialize a message event.
Definition event.c:23
void event_wait(Event *event, char **cmd, char **param)
Wait input.
Definition event.c:133
void event_free(Event *event)
Free a message event.
Definition event.c:67
void event_add_message(Event *event, char *message)
Add a new message at the bottom of the list.
Definition event.c:93
bool hash_get(HashTable *hash_table, const unsigned long long hash_code, HashData *data)
Find an hash table entry according to the evaluated board hash codes.
Definition hash-lock-free.c:600
void hash_clear(HashTable *hash_table)
Clear the hashtable.
Definition hash-lock-free.c:179
void hash_feed(HashTable *hash_table, const unsigned long long hash_code, const int depth, const int selectivity, const int lower, const int upper, const int move)
Feed hash table (from Cassio).
Definition hash-lock-free.c:496
void hash_cleanup(HashTable *hash_table)
Clear the hashtable.
Definition hash-lock-free.c:159
bool movelist_is_empty(const MoveList *movelist)
Check if the list is empty.
Definition move.c:537
void movelist_sort(MoveList *movelist)
Sort all moves.
Definition move.c:505
Move * movelist_first(MoveList *movelist)
Return the first move of the list.
Definition move.c:422
void line_init(Line *line, const int player)
Initialize a sequence of moves.
Definition move.c:549
void movelist_evaluate(MoveList *movelist, Search *search, const HashData *hash_data, const int alpha, const int depth)
Evaluate a list of move in order to sort it.
Definition move.c:436
int movelist_get_moves(MoveList *movelist, const Board *board)
Get moves from a position.
Definition move.c:298
char * line_to_string(const Line *line, int n, const char *separator, char *string)
Line to string.
Definition move.c:635
char * move_to_string(const int x, const int player, char *s)
Print out a move.
Definition move.c:76
Move * movelist_sort_bestmove(MoveList *movelist, const int move)
Sort a move as best.
Definition move.c:468
#define foreach_move(iter, movelist)
Definition move.h:78
Options options
Definition options.c:22
void iterative_deepening(Search *search, int alpha, int beta)
Iterative deepening.
Definition root.c:621
bool is_pv_ok(Search *search, int bestmove, int search_depth)
Check if PV is ok.
Definition root.c:83
int aspiration_search(Search *search, int alpha, int beta, const int depth, int score)
Aspiration window.
Definition root.c:451
void record_best_move(Search *search, const Board *init_board, const Move *bestmove, const int alpha, const int beta, const int depth)
Record best move.
Definition root.c:150
void search_time_init(Search *search)
Initialize the alloted time.
Definition search.c:697
void search_init(Search *search)
Init the main search.
Definition search.c:351
void search_free(Search *search)
Free the search allocated ressource.
Definition search.c:441
const Selectivity selectivity_table[]
Definition search.c:97
unsigned long long search_count_nodes(Search *search)
Return the number of nodes searched.
Definition search.c:1073
int get_pv_extension(const int depth, const int n_empties)
Compute the pv_extension.
Definition search.c:1012
void search_set_observer(Search *search, void(*observer)(Result *))
set observer.
Definition search.c:1095
void search_set_board(Search *search, const Board *board, const int player)
Set the board to analyze.
Definition search.c:593
void search_stop_all(Search *search, const Stop stop)
Stop the search.
Definition search.c:1335
long long search_time(Search *search)
Return the time spent by the search.
Definition search.c:1061
void statistics_sum_nodes(Search *search)
Cumulate node counts from the last search.
Definition stats.c:97
unsigned long long player
Definition board.h:27
unsigned long long opponent
Definition board.h:27
int lower
Definition search.h:36
int upper
Definition search.h:37
bool is_searching
Definition cassio.c:52
Search * search
Definition cassio.c:47
Event event[1]
Definition cassio.c:46
struct Engine::@4 last_position
Board board[ENGINE_N_POSITION]
Definition cassio.c:49
int n
Definition cassio.c:50
Thread thread
Definition event.h:24
volatile bool loop
Definition event.h:19
unsigned char move[2]
Definition hash.h:31
signed char lower
Definition hash.h:29
signed char upper
Definition hash.h:30
unsigned char selectivity
Definition hash.h:26
unsigned char depth
Definition hash.h:25
int n_moves
Definition move.h:37
char move[GAME_SIZE]
Definition move.h:36
LogFile.
Definition util.h:423
FILE * f
Definition util.h:424
int n_moves
Definition move.h:31
int score
Definition move.h:23
int x
Definition move.h:22
char * ui_log_file
Definition options.h:78
int alpha
Definition options.h:52
bool transgress_cassio
Definition options.h:38
int beta
Definition options.h:53
bool book_move
Definition search.h:50
int move
Definition search.h:44
unsigned long long n_nodes
Definition search.h:49
int score
Definition search.h:45
long long time
Definition search.h:48
int n_moves_left
Definition search.h:52
int selectivity
Definition search.h:43
Line pv[1]
Definition search.h:47
int depth
Definition search.h:42
int n_moves
Definition search.h:51
Bound bound[BOARD_SIZE+2]
Definition search.h:46
volatile long long spent
Definition search.h:126
int n_empties
Definition search.h:99
bool keep_date
Definition search.h:143
volatile unsigned long long child_nodes
Definition search.h:156
MoveList movelist[1]
Definition search.h:132
Result * result
Definition search.h:151
int depth_pv_extension
Definition search.h:121
int height
Definition search.h:133
int player
Definition search.h:100
struct Search::@25 options
int depth
Definition search.h:117
Bound stability_bound
Definition search.h:135
HashTable pv_table[1]
Definition search.h:104
HashTable hash_table[1]
Definition search.h:103
volatile Stop stop
Definition search.h:122
volatile unsigned long long n_nodes
Definition search.h:155
HashTable shallow_table[1]
Definition search.h:105
int selectivity
Definition search.h:118
NodeType node_type[GAME_SIZE]
Definition search.h:134
Board board[1]
Definition search.h:96
int percent
Definition search.h:28
void time_stamp(FILE *f)
Print local time.
Definition util.c:189
char * string_duplicate(const char *s)
Duplicate a string.
Definition util.c:299
char * parse_int(const char *string, int *result)
Parse an integer.
Definition util.c:761
void thread_create2(Thread *thread, void *(*function)(void *), void *data)
Create a thread.
Definition util.c:922
long long(* time_clock)(void)
Time clock.
Definition util.c:122
void string_to_lowercase(char *s)
Change all char of a string to lowercase.
Definition util.c:355
char * parse_real(const char *string, double *result)
Parse a real number (as a double floating point).
Definition util.c:796
char * string_read_line(FILE *f)
Read a line.
Definition util.c:265
char * parse_word(const char *string, char *word, unsigned int n)
Parse a word.
Definition util.c:562
char * parse_game(const char *string, const Board *board_init, Line *line)
Parse a sequence of moves.
Definition util.c:657
char * parse_board(const char *string, Board *board, int *player)
Parse a board.
Definition util.c:682
Miscellaneous utilities header.
#define log_close(l)
Close an opened log file.
Definition util.h:435
#define MIN(a, b)
Definition util.h:101
#define cassio_debug(...)
Display a message in cassio's "fenetre de rapport" .
Definition util.h:389
#define log_open(l, file)
open a log file if allowed.
Definition util.h:429
#define log_is_open(l)
Check if the log stream can be used.
Definition util.h:448
#define BOUND(var, min, max, name)
Definition util.h:104