My Project
play.c
Go to the documentation of this file.
1
11#include "bit.h"
12#include "const.h"
13#include "game.h"
14#include "move.h"
15#include "opening.h"
16#include "options.h"
17#include "play.h"
18#include "settings.h"
19
20#include <assert.h>
21
27void play_init(Play *play, Book *book)
28{
29 search_init(play->search);
30 play->book = book;
32 play->search->options.header = " depth|score| time | nodes (N) | N/s | principal variation";
33 play->search->options.separator = "------+-----+--------------+-------------+----------+----------------------";
34 play->player = play->initial_player = BLACK;
35 play->time[0].left = options.time;
36 play->time[0].extra = 0;
37 play->time[1].left = options.time;
38 play->time[1].extra = 0;
39 play_new(play);
40 lock_init(play->ponder);
41 play->ponder->launched = false;
42 spin_init(play->result);
43 play->ponder->verbose = false;
44 memset(play->error_message, 0, PLAY_MESSAGE_MAX_LENGTH);
45 play_force_init(play, "F5");
46}
47
52void play_free(Play *play)
53{
55 search_free(play->search);
56}
57
62void play_new(Play *play)
63{
64 play->clock = real_clock();
65 play->time[0].spent = play->time[1].spent = 0;
66 *play->board = *play->initial_board;
67 play->player = play->initial_player;
68 play->ponder->board->player = play->ponder->board->opponent = 0;
70 play->i_game = play->n_game = 0;
71 play->state = IS_WAITING;
72 play->result->move = NOMOVE; // missing more initialisation ?
73 play->time[0].left = options.time;
74 play->time[1].left = options.time;
75 play->force.i_move = 0;
76}
77
84bool play_load(Play *play, const char *file)
85{
86 Game game[1];
87 FILE *f;
88 int i, l;
89 char ext[8], move[8];
90
91 f = fopen(file, "r");
92 if (f == NULL) {
93 sprintf(play->error_message, "Cannot open file %s\n", file);
94 return false;
95 }
96
97 l = strlen(file); strcpy(ext, file + l - 4); string_to_lowercase(ext);
98
99 if (strcmp(ext, ".txt") == 0) game_import_text(game, f);
100 else if (strcmp(ext, ".ggf") == 0) game_import_ggf(game, f);
101 else if (strcmp(ext, ".sgf") == 0) game_import_sgf(game, f);
102 else if (strcmp(ext, ".pgn") == 0) game_import_pgn(game, f);
103 else if (strcmp(ext, ".edx") == 0) game_read(game, f);
104 else {
105 sprintf(play->error_message, "Unknown game format extension: %s\n", ext);
106 fclose(f);
107 return false;
108 }
109
110 *play->initial_board = *game->initial_board;
111 play->initial_player = game->player;
112 play_new(play);
113 for (i = 0; i < 60 && game->move[i] != NOMOVE; ++i) {
114 if (play_must_pass(play)) play_move(play, PASS);
115 if (!play_move(play, game->move[i])) {
116 sprintf(play->error_message, "Illegal move #%d: %s\n", i, move_to_string(game->move[i], play->player, move));
117 fclose(f);
118 return false;
119 }
120 }
121
122 fclose(f);
123 return true;
124}
125
131void play_save(Play *play, const char *file)
132{
133 Game game[1];
134 FILE *f;
135 int i, j, l;
136 char ext[8];
137
138
139 game_init(game);
140 *game->initial_board = *play->initial_board;
141 game->player = play->initial_player;
142 for (i = j = 0; i < play->n_game; ++i) {
143 if (play->game[i].x != PASS) {
144 game->move[j++] = play->game[i].x;
145 }
146 }
147
148 f = fopen(file, "w");
149 if (f == NULL) {
150 warn("Cannot open file %s\n", file);
151 return;
152 }
153
154 l = strlen(file); strcpy(ext, file + l - 4); string_to_lowercase(ext);
155
156 if (strcmp(ext, ".txt") == 0) game_export_text(game, f);
157 else if (strcmp(ext, ".ggf") == 0) game_export_ggf(game, f);
158 else if (strcmp(ext, ".sgf") == 0) game_save_sgf(game, f, true);
159 else if (strcmp(ext, ".pgn") == 0) game_export_pgn(game, f);
160 else if (strcmp(ext, ".eps") == 0) game_export_eps(game, f);
161 else if (strcmp(ext, ".svg") == 0) game_export_svg(game, f);
162 else if (strcmp(ext, ".edx") == 0) game_write(game, f);
163 else warn("Unknown game format extension: %s\n", ext);
164
165 fclose(f);
166}
167
168
174void play_update(Play *play, Move *move)
175{
176 play_force_update(play);
177 board_update(play->board, move);
178 play->game[play->i_game] = *move;
179 play->n_game = ++play->i_game;
180 play->time[play->player].spent += real_clock() - play->clock;
181 play->clock = real_clock();
182 play->player ^= 1;
183}
184
191{
192 Board *board = play->board;
193 return can_move(board->player, board->opponent) == false &&
194 can_move(board->opponent, board->player) == false;
195}
196
203{
204 Board *board = play->board;
205 return can_move(board->player, board->opponent) == false &&
206 can_move(board->opponent, board->player) == true;
207}
208
214void play_go(Play *play, const bool update)
215{
216 extern Log xboard_log[1];
217
218 long long t_real = -real_clock();
219 long long t_cpu = -cpu_clock();
220 Move move[1];
221 Search *search = play->search;
222 char s_move[4];
223
224 if (play_is_game_over(play)) return;
225
226 if (play_force_go(play, move)) {
228
229 play->result->depth = 0;
230 play->result->selectivity = 0;
231 play->result->move = move->x;
232 play->result->score = 0;
233 play->result->book_move = false;
234 play->result->time = real_clock() + t_real;
235 play->result->n_nodes = 0;
236 line_init(play->result->pv, play->player);
237 line_push(play->result->pv, move->x);
238
239 if (options.verbosity) {
240 info("\n[Forced move %s]\n\n", move_to_string(move->x, play->player, s_move));
241 }
242
243 } else if (options.book_allowed && book_get_random_move(play->book, play->board, move, options.book_randomness)) {
245
246 play->result->depth = 0;
247 play->result->selectivity = 0;
248 play->result->move = move->x;
249 play->result->score = move->score;
250 play->result->book_move = true;
251 play->result->time = real_clock() + t_real;
252 play->result->n_nodes = 0;
253 line_init(play->result->pv, play->player);
254 book_get_line(play->book, play->board, move, play->result->pv);
255
256 if (options.verbosity) {
257 info("\n[book move]\n");
258 if (options.info) book_show(play->book, play->board);
259 info("\n\n");
260
261 if (play->type == UI_XBOARD) {
262 search->observer(play->result);
263 } else {
264 if (search->options.header) puts(search->options.header);
265 if (search->options.separator) puts(search->options.separator);
266 printf("book %+02d ", move->score);
267 line_print(play->result->pv, options.width - 54, " ", stdout);
268 putchar('\n');
269 if (search->options.separator) puts(search->options.separator);
270 }
271 }
272 } else if (play->state == IS_PONDERING && board_equal(play->board, play->ponder->board)) {
273 play->state = IS_THINKING;
274
276 if (options.verbosity) {
277 info("\n[switch from pondering to thinking (id.%d)]\n", play->search->id);
278 if (search->options.header) puts(search->options.header);
279 if (search->options.separator) puts(search->options.separator);
280 }
281
283 else search_set_game_time(search, play->time[play->player].left);
284
285 search_time_reset(search, play->board);
286 if (log_is_open(xboard_log)) {
287 fprintf(xboard_log->f, "edax search> cpu: %d\n", options.n_task);
288 fprintf(xboard_log->f, "edax search> time: spent while pondering = %.2f mini = %.2f; maxi = %.2f; extra = %.2f\n",
289 0.001 * search_time(search), 0.001 * search->time.mini, 0.001 * search->time.maxi, 0.001 * search->time.extra);
290 fprintf(xboard_log->f, "edax search> level: %d@%d%%\n",
292 }
293
294 search->observer(search->result);
295 thread_join(play->ponder->thread);
296 play->ponder->launched = false;
297 search->observer(search->result);
298
299 *play->result = *search->result;
300 play->state = IS_WAITING;
301 if (!board_get_move(play->board, search->result->move, move) && move->x != PASS) {
302 fatal_error("bad move found: %s\n", move_to_string(move->x, play->player, s_move));
303 }
304 if (options.verbosity) {
305 if (search->options.separator) puts(search->options.separator);
306 info("[stop thinking (id.%d)]\n", play->search->id);
307 }
308
309 } else {
310
312
313 play->state = IS_THINKING;
314
316 if (options.verbosity) {
317 info("\n[start thinking (id.%d)]\n", play->search->id);
318 if (search->options.header) puts(search->options.header);
319 if (search->options.separator) puts(search->options.separator);
320 }
321 search_set_board(search, play->board, play->player);
322 search_set_level(search, options.level, search->n_empties);
324 else search_set_game_time(search, play->time[play->player].left);
325
326 search_time_init(search); // redondant,
327 if (log_is_open(xboard_log)) {
328 fprintf(xboard_log->f, "edax search> cpu: %d\n", options.n_task);
329 fprintf(xboard_log->f, "edax search> time: left = %.2f mini = %.2f; maxi = %.2f; extra = %.2f\n",
330 0.001 * play->time[play->player].left, 0.001 * search->time.mini, 0.001 * search->time.maxi, 0.001 * search->time.extra);
331 fprintf(xboard_log->f, "edax search> level: %d@%d%%\n",
333 }
334
335 search_run(search);
336 *play->result = *search->result;
337 play->state = IS_WAITING;
338 if (!board_get_move(play->board, search->result->move, move) && move->x != PASS) {
339 fatal_error("bad move found: %s\n", move_to_string(move->x, play->player, s_move));
340 }
341 if (options.verbosity) {
342 if (search->options.separator) puts(search->options.separator);
343 info("[stop thinking] (id.%d)]\n", play->search->id);
344 }
345 }
346
347 t_real += real_clock() + 1;
348 t_cpu += cpu_clock() + 1;
349 info("[cpu usage: %.2f%%]\n", 100.0 * t_cpu / t_real);
350
351 if (options.play_type != EDAX_TIME_PER_MOVE) play->time[play->player].left -= t_real;
352
353 if (update) play_update(play, move);
354
355}
356
365void play_hint(Play *play, int n)
366{
367 Line pv[1];
368 Move *m;
369 Search *search = play->search;
370 MoveList book_moves[1];
371 GameStats stat;
372 Board b[1];
373
374 if (play_is_game_over(play)) return;
375
377
378 play->state = IS_THINKING;
379
381 if (options.verbosity) {
382 info("\n[start thinking]\n");
383 if (search->options.header) puts(search->options.header);
384 if (search->options.separator) puts(search->options.separator);
385 }
386 search_set_board(search, play->board, play->player);
387 search_set_level(search, options.level, search->n_empties);
388 if (n > search->movelist->n_moves) n = search->movelist->n_moves;
389 info("<hint %d moves>\n", n);
390
391 if (options.book_allowed && book_get_moves(play->book, play->board, book_moves)) {
392 foreach_move (m, book_moves) if (n) {
393 --n;
394 line_init(pv, play->player);
395 book_get_line(play->book, play->board, m, pv);
396 movelist_exclude(search->movelist, m->x);
397 if (play->type == UI_NBOARD) {
398 board_next(play->board, m->x, b);
399 book_get_game_stats(play->book, b, &stat);
400 printf("book "); line_print(pv, 10, NULL, stdout);
401 printf(" %d %llu %d\n", m->score, stat.n_lines, play->book->options.level);
402 } else {
403 printf("book %+02d ", m->score);
404 line_print(pv, options.width - 54, " ", stdout); putchar('\n');
405 }
406 }
407 }
408
409 while (n--) {
411 else search_set_game_time(search, play->time[play->player].left);
412 if (n) search->options.multipv_depth = 60;
413 search_run(search);
415 if (play->type == UI_NBOARD) {
416 printf("search "); line_print(search->result->pv, 10, NULL, stdout);
417 printf(" %d 0 %d\n", search->result->score, search->result->depth);
418 } else {
419 if (options.verbosity == 0) search->observer(search->result);
420 }
421 if (search->stop != STOP_END) break;
422 movelist_exclude(search->movelist, search->result->move);
423 }
424 if (options.verbosity) {
425 info("\n[stop thinking]\n");
426 if (search->options.separator) puts(search->options.separator);
427 }
428}
429
439void play_hint_for_lib(Play *play, int n, HintList* hintlist)
440{
441 Move *m;
442 Search *search = play->search;
443 MoveList book_moves[1];
444
445 Hint *hint = hintlist->hint + 1;
446 hintlist->n_hints = 0;
447
448 if (play_is_game_over(play)) return;
449
451
452 play->state = IS_THINKING;
453
455 search_set_board(search, play->board, play->player);
456 search_set_level(search, options.level, search->n_empties);
457 if (n > search->movelist->n_moves) n = search->movelist->n_moves;
458
459 if (options.book_allowed && book_get_moves(play->book, play->board, book_moves)) {
460 foreach_move (m, book_moves) if (n) {
461 --n;
462 line_init(hint->pv, play->player);
463 book_get_line(play->book, play->board, m, hint->pv);
464
465 hint->depth = 0;
466 hint->selectivity = 0;
467 hint->move = m->x;
468 hint->score = m->score;
469 hint->upper = 0;
470 hint->lower = 0;
471 hint->time = 0;
472 hint->n_nodes = 0;
473 hint->book_move = true;
474 ++hint;
475 ++(hintlist->n_hints);
476
477 movelist_exclude(search->movelist, m->x);
478 }
479 }
480
481 while (n--) {
483 else search_set_game_time(search, play->time[play->player].left);
484 if (n) search->options.multipv_depth = 60;
485 search_run(search);
487 line_init(hint->pv, play->player);
488
489 hint->depth = search->result->depth;
490 hint->selectivity = search->result->selectivity;
491 hint->move = search->result->move;
492 hint->score = search->result->score;
493 hint->upper = search->result->bound[search->result->move].upper;
494 hint->lower = search->result->bound[search->result->move].lower;
495 line_copy(hint->pv, search->result->pv, 0);
496 hint->time = search->result->time;
497 hint->n_nodes = search->result->n_nodes;
498 hint->book_move = false;
499 ++hint;
500 ++(hintlist->n_hints);
501
502 if (search->stop != STOP_END) break;
503 movelist_exclude(search->movelist, search->result->move);
504 }
505}
506
513void play_get_bookmove(Play *play, MoveList* book_moves)
514{
515 if (play_is_game_over(play)) return;
516
518
519 play->state = IS_THINKING;
520
521 if (options.book_allowed) {
522 book_get_moves(play->book, play->board, book_moves);
523 } else {
524 book_moves->n_moves = 0;
525 }
526}
527
535int play_get_bookmove_with_position(Play *play, MoveList* book_moves, Position* position)
536{
537 if (play_is_game_over(play)) return -1;
538
540
541 play->state = IS_THINKING;
542
543 if (options.book_allowed) {
544 return book_get_moves_with_position(play->book, play->board, book_moves, position);
545 } else {
546 book_moves->n_moves = 0;
547 return -1;
548 }
549}
550
556void play_hint_prepare(Play *play, MoveList* exclude_list)
557{
558 Move* m;
559 Search *search = play->search;
560
561 if (play_is_game_over(play)) return;
562
564
565 play->state = IS_THINKING;
566
568 search_set_board(search, play->board, play->player);
569 search_set_level(search, options.level, search->n_empties);
570 if (options.depth >= 0) search->options.depth = MIN(options.depth, search->n_empties);
572
573 if ( exclude_list ) {
574 foreach_move (m, exclude_list) {
575 movelist_exclude(search->movelist, m->x);
576 }
577 }
578}
579
580
589void play_hint_next(Play *play, Hint* hint, bool multiPvDepthMax)
590{
591 Move *m;
592 Search *search = play->search;
593 MoveList book_moves[1];
594
595 hint->depth = 0;
596 hint->selectivity = 0;
597 hint->move = NOMOVE;
598 hint->score = 0;
599 hint->upper = 0;
600 hint->lower = 0;
601 hint->time = 0;
602 hint->n_nodes = 0;
603 hint->book_move = false;
604
605 if (play_is_game_over(play)) return;
606 if (movelist_is_empty(search->movelist)) return;
607
608 if (options.book_allowed && book_get_moves(play->book, play->board, book_moves)) {
609 foreach_move (m, book_moves) {
610 line_init(hint->pv, play->player);
611 book_get_line(play->book, play->board, m, hint->pv);
612
613 hint->depth = 0;
614 hint->selectivity = 0;
615 hint->move = m->x;
616 hint->score = m->score;
617 hint->upper = 0;
618 hint->lower = 0;
619 hint->time = 0;
620 hint->n_nodes = 0;
621 hint->book_move = true;
622
623 if ( movelist_exclude(search->movelist, m->x) != NULL ) {
624 return;
625 }
626 }
627 }
628
630 else search_set_game_time(search, play->time[play->player].left);
631 if ( multiPvDepthMax ) search->options.multipv_depth = 60;
632 search_run(search);
633 line_init(hint->pv, play->player);
634 if ( multiPvDepthMax ) search->options.multipv_depth = MULTIPV_DEPTH;
635
636 hint->depth = search->result->depth;
637 hint->selectivity = search->result->selectivity;
638 hint->move = search->result->move;
639 hint->score = search->result->score;
640 hint->upper = search->result->bound[search->result->move].upper;
641 hint->lower = search->result->bound[search->result->move].lower;
642 line_copy(hint->pv, search->result->pv, 0);
643 hint->time = search->result->time;
644 hint->n_nodes = search->result->n_nodes;
645 hint->book_move = false;
646
647 movelist_exclude(search->movelist, search->result->move);
648}
649
662void* play_ponder_run(void *v)
663{
664 extern Log xboard_log[1];
665 Play *play = (Play*) v;
666 int player;
667 Search *search = play->search;
668 Board board[1];
669 Move move[1];
670 char m[4];
671
672 lock(play->ponder);
673 if (play->state == IS_PONDERING || play->state == IS_ANALYZING) {
674 *board = *play->board;
675 player = play->player;
677 search->options.keep_date = (play->state == IS_PONDERING && search->pv_table->date > 0);
678 if (play->ponder->verbose) search->options.verbosity = options.verbosity;
679 else search->options.verbosity = 0;
680
681 move->x = search_guess(search, board);
682
683 // guess opponent move and start the search
684 if (play->state == IS_PONDERING && move->x != NOMOVE) {
685 board_get_move(board, move->x, move);
686
687 board_update(board, move);
688 *play->ponder->board = *board;
689 search_set_board(search, board, player ^ 1);
690 search_set_level(search, options.level, search->n_empties);
691 search_run(search);
692 if (options.info && play->state == IS_PONDERING) {
693 printf("[ponder after %s id.%d: ", move_to_string(move->x, player, m), search->id);
694 result_print(search->result, stdout);
695 printf("]\n");
696 }
697 board_restore(board, move);
698 } else {
699 *play->ponder->board = *board;
700 search_set_board(search, board, player);
702 log_print(xboard_log, "edax (ponder)> start search\n");
703 search_run(search);
704 log_print(xboard_log, "edax (ponder)> search ended\n");
705 if (options.info && play->state == IS_PONDERING) {
706 printf("[ponder (without move) id.%d: ", search->id);
707 result_print(search->result, stdout);
708 printf("]\n");
709 }
710 }
711
712 info("[ponderation finished]\n");
713 play->state = IS_WAITING;
714 search->options.keep_date = false;
715 }
716 unlock(play->ponder);
717
718 return NULL;
719}
720
729void play_ponder(Play *play)
730{
731 if (play_is_game_over(play)) return;
732 if (options.can_ponder && play->state == IS_WAITING) {
733 play->ponder->board->player = play->ponder->board->opponent = 0;
734 play->state = IS_PONDERING;
735 info("\n[start ponderation]\n");
736 thread_create2(&play->ponder->thread, play_ponder_run, play); // modified for iOS by lavox. 2018/1/16
737 play->ponder->launched = true;
738 }
739}
740
750{
751 while (play->state == IS_PONDERING) {
752 info("[stop pondering]\n");
754 relax(10);
755 }
756
757 if (play->ponder->launched) {
758 info("[joining thread]\n");
759 thread_join(play->ponder->thread);
760 play->ponder->launched = false;
761 info("[thread joined]\n");
762 }
763}
764
769void play_stop(Play *play)
770{
772 info("[stop on user demand]\n");
773}
774
779void play_undo(Play *play)
780{
781 if (play->i_game > 0) {
783 lock(play->ponder);
784 play_force_restore(play);
785 board_restore(play->board, &play->game[--play->i_game]);
786 play->player ^= 1;
787 unlock(play->ponder);
788 }
789}
790
795void play_redo(Play *play)
796{
797 if (play->i_game < play->n_game) {
799 play_force_update(play);
800 board_update(play->board, &play->game[play->i_game++]);
801 play->player ^= 1;
802 }
803}
804
810void play_set_board(Play *play, const char *board)
811{
813 play->initial_player = board_set(play->initial_board, board);
814 if (play->initial_player == EMPTY) { /* bad board ? */
815 play->initial_board->opponent &= (~play->initial_board->player);
818 }
819 play_force_init(play, "");
820 play_new(play);
821}
822
828void play_set_board_from_FEN(Play *play, const char *board)
829{
831 play->initial_player = board_from_FEN(play->initial_board, board);
832 if (play->initial_player != EMPTY) {
833 play_force_init(play, "");
834 play_new(play);
835 }
836}
837
846void play_set_board_from_obj(Play *play, const Board *board, const int turn)
847{
849 play->initial_player = board_from_obj(play->initial_board, board, turn);
850 if (play->initial_board->player & play->initial_board->opponent) { /* bad board */
851 play->initial_board->opponent &= (~play->initial_board->player);
852 }
853 if (play->initial_player == EMPTY) { /* bad turn */
856 }
857 play_force_init(play, "");
858 play_new(play);
859}
860
866void play_game(Play *play, const char *string)
867{
868 Move move[1];
869 const char *next;
870
872
873 // convert an opening name to a move sequence...
874 next = opening_get_line(string);
875 if (next) string = next;
876
877 while ((next = parse_move(string, play->board, move)) != string || move->x == PASS) {
878 string = next;
879 play_update(play, move);
880 }
881}
882
889bool play_move(Play *play, int x)
890{
891 Move move[1];
892
893 *move = MOVE_INIT;
894 board_get_move(play->board, x, move);
895 if (board_check_move(play->board, move)) {
896 play_update(play, move);
897 return true;
898 } else {
899 return false;
900 }
901}
902
909bool play_user_move(Play *play, const char *string)
910{
911 Move move[1];
912
913 if (parse_move(string, play->board, move) != string) {
914 play_update(play, move);
915 return true;
916 } else {
917 return false;
918 }
919}
920
921
928{
929 return play->i_game ? play->game + play->i_game - 1 : NULL;
930}
931
932
943static int play_alternative(Play *play, Move *played, Move *alternative, int *depth, int *percent)
944{
945 Search *search = play->search;
946 Result *result = search->result;
947 Board excluded[1], board[1], unique[1];
948 Move *move;
949
950 search_set_board(search, play->board, play->player);
951 if (A1 <= played->x && played->x <= H8) {
952 movelist_exclude(search->movelist, played->x);
953 hash_exclude_move(search->pv_table, search->board, board_get_hash_code(search->board), played->x);
954 hash_exclude_move(search->hash_table, search->board, board_get_hash_code(search->board), played->x);
955 // also remove moves leading to symetrical positions
956 board_next(play->board, played->x, board);
957 board_unique(board, excluded);
958 foreach_move (move, search->movelist) {
959 board_next(play->board, move->x, board);
960 board_unique(board, unique);
961 if (board_equal(excluded, unique)) {
962 hash_exclude_move(search->pv_table, search->board, board_get_hash_code(search->board), move->x);
963 hash_exclude_move(search->hash_table, search->board, board_get_hash_code(search->board), move->x);
964 move = movelist_exclude(search->movelist, move->x);
965 }
966 }
967 }
968 if (search->movelist->n_moves >= 1 || played->x == NOMOVE) {
969 search_set_level(search, options.level, search->n_empties);
970 search->options.verbosity = 0;
971 search_run(search);
973 alternative->x = result->move;
974 alternative->score = result->score;
975 *depth = result->depth;
976 *percent = selectivity_table[result->selectivity].percent;
977 }
978 return search->movelist->n_moves;
979}
980
994static void play_write_analysis(Play *play, const Move *m, const Move *a, const int n_moves, const int depth, const int percent, FILE *f)
995{
996 char s[4];
997
998 if (n_moves >= 0) {
999 int n_empties = board_count_empties(play->board);
1000 fprintf(f, "%3d ", 61 - n_empties);
1001 if (depth == -1) fputs(" book ", f);
1002 else {
1003 fprintf(f, " %3d", depth);
1004 if (percent < 100) fprintf(f, "@%2d%%", percent);
1005 else fputs(" ", f);
1006 };
1007 fprintf(f, "%3d ", n_moves);
1008 fprintf(f, " %s %+3d ", move_to_string(m->x, play->player, s), m->score);
1009 if (n_moves > 0) {
1010 if (m->score > a->score) fputs(" > ", f);
1011 else if (m->score == a->score) fputs(" = ", f);
1012 else fputs( " < ", f);
1013 fprintf(f, " %+3d %s ", a->score, move_to_string(a->x, play->player, s));
1014 if (m->score < a->score) {
1015 if (depth == n_empties) {
1016 if (percent == 100) fputs("<- Mistake", f);
1017 else fputs("<- Possible mistake", f);
1018 } else {
1019 fputs("<- Edax disagrees", f);
1020 if (a->score - m->score > 4) fputs(" strongly", f);
1021 }
1022 }
1023 }
1024 putc('\n', f);
1025 }
1026}
1027
1033void play_analyze(Play *play, int n)
1034{
1035 int i, score, n_alternatives;
1036 int depth = 0, percent = 0, n_empties;
1037 Move *move, alternative[1];
1038 int n_exact[2] = {0, 0}, n_eval[2] = {0, 0};
1039 int n_error[2] = {0, 0}, n_rejection[2] = {0, 0};
1040 int disc_error[2] = {0, 0}, disc_rejection[2] = {0, 0};
1041 const char *clr = " \r";
1042
1043
1044 play_stop_pondering(play);
1045
1046 puts("\n N played alternative");
1047 puts("ply level alt. move score score move");
1048 puts("---+-------+-----+-----------+--+---------------");
1049
1050 search_cleanup(play->search);
1051 search_set_board(play->search, play->board, play->player);
1052 alternative->x = NOMOVE;
1053 play_alternative(play, alternative, alternative, &depth, &percent);
1054 score = alternative->score;
1055
1056 for (i = play->i_game - 1; i >= 0 && i >= play->i_game - n; --i) {
1057 move = play->game + i;
1058 move->score = -score;
1059 play->player ^= 1;
1060 board_restore(play->board, move);
1061 if (move->x == PASS) ++n;
1062
1063 n_empties = board_count_empties(play->board);
1064 n_alternatives = play_alternative(play, move, alternative, &depth, &percent);
1065 if (options.verbosity == 1) fputs(clr, stdout);
1066 play_write_analysis(play, move, alternative, n_alternatives, depth, percent, stdout);
1067
1068 score = move->score;
1069 if (n_alternatives > 0) {
1070 if (depth == n_empties && percent == 100) ++n_exact[play->player]; else ++n_eval[play->player];
1071 if (alternative->score > score) {
1072 if (depth == n_empties && percent == 100) {
1073 ++n_error[play->player];
1074 disc_error[play->player] += alternative->score - score;
1075 } else {
1076 ++n_rejection[play->player];
1077 disc_rejection[play->player] += alternative->score - score;
1078 }
1079 score = alternative->score;
1080 }
1081 }
1082 if (play->search->stop == STOP_ON_DEMAND) break;
1083 }
1084 puts("\n | rejections : discs | errors : discs | error rate |");
1085 printf("Black | %3d / %3d : %+4d | %3d / %3d : %+4d | %5.3f |\n",
1086 n_rejection[BLACK], n_eval[BLACK], disc_rejection[BLACK], n_error[BLACK], n_exact[BLACK], disc_error[BLACK], 1.0 * disc_error[BLACK] / n_exact[BLACK]);
1087 printf("White | %3d / %3d : %+4d | %3d / %3d : %+4d | %5.3f |\n",
1088 n_rejection[WHITE], n_eval[WHITE], disc_rejection[WHITE], n_error[WHITE], n_exact[WHITE], disc_error[WHITE], 1.0 * disc_error[WHITE] / n_exact[WHITE]);
1089
1090 if (i < 0 || i < play->i_game - n) ++i;
1091 for (; i < play->i_game; ++i) {
1092 board_update(play->board, play->game + i);
1093 play->player ^= 1;
1094 }
1095}
1096
1105static int play_book_alternative(Play *play, Move *played, Move* alternative)
1106{
1107 MoveList movelist[1];
1108 Move *exclude, *best;
1109 Board excluded[1], board[1], unique[1];
1110 Move *move;
1111
1112 if (book_get_moves(play->book, play->board, movelist)) {
1113 exclude = movelist_exclude(movelist, played->x);
1114
1115 if (exclude && exclude->x == played->x) {
1116 played->score = exclude->score;
1117 // also remove moves leading to symetrical positions
1118 board_next(play->board, played->x, board);
1119 board_unique(board, excluded);
1120 foreach_move (move, movelist) {
1121 board_next(play->board, move->x, board);
1122 board_unique(board, unique);
1123 if (board_equal(excluded, unique)) move = movelist_exclude(movelist, move->x);
1124 }
1125 if (movelist->n_moves) {
1126 best = movelist_best(movelist);
1127 *alternative = *best;
1128 }
1129 return movelist->n_moves;
1130 }
1131 }
1132 return -1;
1133}
1134
1140void play_book_analyze(Play *play, int n)
1141{
1142 int i, n_alternatives;
1143 Move *move, alternative[1];
1144
1145 play_stop_pondering(play);
1146
1147 puts("\n N played alternative");
1148 puts("ply level alt. move score score move");
1149 puts("---+-------+-----+-----------+--+---------------");
1150
1151 for (i = play->i_game - 1; i >= 0 && i >= play->i_game - n; --i) {
1152 move = play->game + i;
1153 play->player ^= 1;
1154 board_restore(play->board, move);
1155 if (move->x == PASS) ++n;
1156
1157 n_alternatives = play_book_alternative(play, move, alternative);
1158 play_write_analysis(play, move, alternative, n_alternatives, -1, 100, stdout);
1159
1160 if (play->search->stop == STOP_ON_DEMAND) break;
1161 }
1162
1163 if (i < 0 || i < play->i_game - n) ++i;
1164 for (; i < play->i_game; ++i) {
1165 board_update(play->board, play->game + i);
1166 play->player ^= 1;
1167 }
1168}
1169
1175void play_store(Play *play)
1176{
1177 Board board[1];
1178 int i;
1179 char file[FILENAME_MAX + 1];
1180
1181 file_add_ext(options.book_file, ".store", file);
1182
1183 play->book->stats.n_nodes = play->book->stats.n_links = 0;
1184
1185 *board = *play->initial_board;
1186 for (i = 0; i < play->n_game && board_check_move(board, play->game + i); ++i) {
1187 board_update(board, play->game + i);
1188 }
1189
1190 for (--i; i >= 0; --i) {
1191 book_add_board(play->book, board);
1192 board_restore(board, play->game + i);
1193 }
1194 book_add_board(play->book, board);
1195 if (play->book->stats.n_nodes + play->book->stats.n_links) {
1196 book_link(play->book);
1197 book_negamax(play->book);
1198 book_save(play->book, file);
1199 }
1200}
1201
1211void play_adjust_time(Play *play, const int left, const int extra)
1212{
1213 play->time[play->player].left = left;
1214 play->time[play->player].extra = extra;
1215}
1216
1225void play_print(Play *play, FILE *f)
1226{
1227 int i, j, x, discs[2], mobility[2], square;
1228 char history[64];
1229 const char *color = "?*O-." + 1;
1230 const char big_color[3][4] = {"|##", "|()", "| "};
1231 const char player[2][6] = {"Black", "White"};
1232 Board *board = play->board;
1233 const int p = play->player;
1234 const int o = !p;
1235 const int ip = play->player ^ (play->i_game & 1);
1236 unsigned long long moves;
1237
1238 moves = get_moves(board->player, board->opponent);
1239 discs[p] = bit_count(board->player);
1240 discs[o] = bit_count(board->opponent);
1241 mobility[p] = get_mobility(board->player, board->opponent);
1242 mobility[o] = get_mobility(board->opponent, board->player);
1243 memset(history, 0, 64);
1244 for (i = j = 0; i < play->i_game; i++) {
1245 x = play->game[i].x;
1246 if (A1 <= x && x <= H8) history[x] = ++j;
1247 }
1248
1249 fputs(" A B C D E F G H BLACK A B C D E F G H\n", f);
1250 for (i = 0; i < 8; i++) {
1251 fputc(i + '1', f);
1252 fputc(' ', f);
1253 for (j = 0; j < 8; j++) {
1254 x = i * 8 + j;
1255 if (p == BLACK) square = 2 - ((board->opponent >> x) & 1) - 2 * ((board->player >> x) & 1);
1256 else square = 2 - ((board->player >> x) & 1) - 2 * ((board->opponent >> x) & 1);
1257 if (square == EMPTY && (moves & x_to_bit(x))) ++square;
1258 fputc(color[square], f);
1259 fputc(' ', f);
1260 }
1261 fputc(i + '1', f);
1262
1263 switch(i) {
1264 case 0:
1265 fputs(" ", f); time_print(play->time[BLACK].spent, true, f); fputs(" ", f);
1266 break;
1267 case 1:
1268 fprintf(f," %2d discs %2d moves ", discs[BLACK], mobility[BLACK]);
1269 break;
1270 case 3:
1271 if (mobility[BLACK] + mobility[WHITE] == 0) fprintf(f," Game over ");
1272 else fprintf(f," ply %2d (%2d empties) ", play->i_game + 1, board_count_empties(board));
1273 break;
1274 case 4:
1275 if (mobility[BLACK] + mobility[WHITE] == 0) {
1276 if (discs[BLACK] > discs[WHITE]) fprintf(f," %s won ", player[BLACK]);
1277 else if (discs[BLACK] < discs[WHITE]) fprintf(f," %s won ", player[WHITE]);
1278 else fprintf(f," draw ");
1279 } else fprintf(f," %s's turn (%c) ",player[p], color[p]);
1280 break;
1281 case 6:
1282 fprintf(f," %2d discs %2d moves ",discs[WHITE], mobility[WHITE]);
1283 break;
1284 case 7:
1285 fputs(" ", f); time_print(play->time[WHITE].spent, true, f); fputs(" ", f);
1286 break;
1287 default:
1288 fputs(" ", f);
1289 break;
1290 }
1291 fputc(i + '1', f); fputc(' ', f);
1292 for (j = 0; j < 8; j++){
1293 x = i * 8 + j;
1294 if (history[x]) fprintf(f,"|%2d",history[x]);
1295 else {
1296 if (ip == BLACK) square = 2 - ((play->initial_board->opponent >> x) & 1) - 2 * ((play->initial_board->player >> x) & 1);
1297 else square = 2 - ((play->initial_board->player >> x) & 1) - 2 * ((play->initial_board->opponent >> x) & 1);
1298 fputs(big_color[square], f);
1299 }
1300 }
1301 fprintf(f, "| %1d\n", i + 1);
1302 }
1303 fputs(" A B C D E F G H WHITE A B C D E F G H\n", f);
1304 fflush(f);
1305}
1306
1313void play_force_init(Play *play, const char *string)
1314{
1315 Move move[1];
1316 const char *next;
1317 Board board[1];
1318
1319 play->force.n_move = play->force.i_move = 0;
1320 *board = *play->initial_board;
1321 play->force.real[play->force.n_move] = *board;
1322 board_unique(board, play->force.unique + play->force.n_move);
1323
1324 next = opening_get_line(string);
1325 if (next) string = next;
1326
1327 while ((next = parse_move(string, board, move)) != string || move->x == PASS) {
1328 string = next;
1329 play->force.move[play->force.n_move] = *move;
1330 board_update(board, move);
1331 ++play->force.n_move;
1332 play->force.real[play->force.n_move] = *board;
1333 board_unique(board, play->force.unique + play->force.n_move);
1334 }
1335}
1336
1346{
1347 Board unique[1];
1348 if (play->force.i_move < play->force.n_move) {
1349 board_unique(play->board, unique);
1350 if ((board_equal(unique, play->force.unique + play->force.i_move))) {
1351 ++play->force.i_move;
1352 }
1353 }
1354}
1355
1365{
1366 Board unique[1];
1367 if (play->force.i_move > 0) {
1368 board_unique(play->board, unique);
1369 if (board_equal(unique, play->force.unique + play->force.i_move)) {
1370 --play->force.i_move;
1371 }
1372 }
1373}
1374
1384bool play_force_go(Play *play, Move *move)
1385{
1386 Board unique[1];
1387 Board sym[1];
1388 int s, x;
1389
1390 if (play->force.i_move < play->force.n_move) {
1391 if (board_equal(play->board, play->force.real + play->force.i_move)) {
1392 *move = play->force.move[play->force.i_move];
1393 return true;
1394 }
1395
1396 board_unique(play->board, unique);
1397 if (board_equal(unique, play->force.unique + play->force.i_move)) {
1398 for (s = 1; s < 8; ++s) {
1399 board_symetry(play->force.real + play->force.i_move, s, sym);
1400 if (board_equal(play->board, sym)) {
1401 x = symetry(play->force.move[play->force.i_move].x, s);
1402 board_get_move(play->board, x, move);
1403 return true;
1404 }
1405 }
1406 }
1407 }
1408
1409 return false;
1410}
1411
1418void play_symetry(Play *play, const int sym)
1419{
1420 int i, x;
1421 Move move = MOVE_INIT;
1422 Board board[1];
1423
1424 board_symetry(play->initial_board, sym, play->initial_board);
1425 board_symetry(play->board, sym, play->board);
1426 *board = *play->initial_board;
1427 for (i = 0; i < play->n_game; ++i) {
1428 x = symetry(play->game[i].x, sym);
1429 board_get_move(board, x, &move);
1430 board_update(board, &move);
1431 play->game[i] = move;
1432 }
1433}
1434
1438const char* play_show_opening_name(Play *play, const char *(*opening_get_name)(const Board*))
1439{
1440 int i;
1441 Board board[1];
1442 const char *name;
1443 const char *last = NULL;
1444
1445 *board = *play->initial_board;
1446 for (i = 0; i < play->i_game; ++i) {
1447 board_update(board, play->game + i);
1448 name = opening_get_name(board);
1449 if (name != NULL) last = name;
1450 }
1451
1452 return last;
1453}
1454
DLL_API int bit_count(unsigned long long b)
Count the number of bits set to one in an unsigned long long.
Definition bit.c:72
#define x_to_bit(x)
Definition bit.h:43
bool board_check_move(const Board *board, Move *move)
Check if a move is legal.
Definition board.c:452
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
unsigned long long board_get_move(const Board *board, const int x, Move *move)
Compute a move.
Definition board.c:438
void board_swap_players(Board *board)
Swap players.
Definition board.c:137
int board_from_obj(Board *board, const Board *obj, const int turn)
Set a board from a Board object.
Definition board.c:258
int board_unique(const Board *board, Board *unique)
unique board
Definition board.c:379
void board_init(Board *board)
Set a board to the starting position.
Definition board.c:280
int get_mobility(const unsigned long long P, const unsigned long long O)
Count legal moves.
Definition board.c:833
bool board_equal(const Board *b1, const Board *b2)
Compare two board for equality.
Definition board.c:335
DLL_API unsigned long long get_moves(const unsigned long long P, const unsigned long long O)
Get legal moves.
Definition board.c:621
DLL_API bool can_move(const unsigned long long P, const unsigned long long O)
Check if a player can move.
Definition board.c:797
unsigned long long board_next(const Board *board, const int x, Board *next)
Compute a board resulting of a move played on a previous board.
Definition board.c:517
int board_set(Board *board, const char *string)
Set a board from a string description.
Definition board.c:154
void board_symetry(const Board *board, const int s, Board *sym)
symetric board
Definition board.c:347
int board_from_FEN(Board *board, const char *string)
Set a board from a string description.
Definition board.c:212
void book_show(Book *book, Board *board)
Display a position from the book.
Definition book.c:2155
void book_add_board(Book *book, const Board *board)
Add a position.
Definition book.c:2485
void book_get_line(Book *book, const Board *board, const Move *move, Line *line)
Get a variation from the book.
Definition book.c:2401
void book_negamax(Book *book)
Negamax a book.
Definition book.c:1684
bool book_get_random_move(Book *book, const Board *board, Move *move, const int randomness)
Get a move at random from the opening book.
Definition book.c:2426
int book_get_moves_with_position(Book *book, const Board *board, MoveList *movelist, Position *position)
Get a list of moves from the book.
Definition book.c:2380
void book_save(Book *book, const char *file)
Save an opening book.
Definition book.c:1622
bool book_get_moves(Book *book, const Board *board, MoveList *movelist)
Get a list of moves from the book.
Definition book.c:2360
void book_link(Book *book)
Link a book.
Definition book.c:1701
void book_get_game_stats(Book *book, const Board *board, GameStats *stat)
Get game statistics from a position.
Definition book.c:2444
@ UI_NBOARD
Definition const.h:113
@ UI_XBOARD
Definition const.h:114
#define TIME_MAX
Definition const.h:61
@ PASS
Definition const.h:37
@ NOMOVE
Definition const.h:37
@ A1
Definition const.h:29
@ H8
Definition const.h:36
@ WHITE
Definition const.h:43
@ EMPTY
Definition const.h:44
@ BLACK
Definition const.h:42
@ STOP_ON_DEMAND
Definition const.h:75
@ STOP_END
Definition const.h:76
@ STOP_PONDERING
Definition const.h:73
@ IS_THINKING
Definition const.h:103
@ IS_PONDERING
Definition const.h:101
@ IS_WAITING
Definition const.h:100
@ IS_ANALYZING
Definition const.h:102
void game_export_ggf(const Game *game, FILE *f)
Write a game to the Generic Game Format (ggf) file.
Definition game.c:713
void game_import_text(Game *game, FILE *f)
Read a game from a text file.
Definition game.c:451
void game_read(Game *game, FILE *f)
Read a game from a binary file.
Definition game.c:429
void game_import_ggf(Game *game, FILE *f)
Read a game from the Generic Game Format (ggf) file.
Definition game.c:582
void game_save_sgf(const Game *game, FILE *f, const bool multiline)
Write a game to the Generic Game Format (ggf) file.
Definition game.c:870
void game_export_text(const Game *game, FILE *f)
Write a game to a text file.
Definition game.c:467
void game_export_svg(const Game *game, FILE *f)
Definition game.c:1409
void game_init(Game *game)
Create an empty game.
Definition game.c:83
void game_import_pgn(Game *game, FILE *f)
Read a game from a pgn file.
Definition game.c:955
void game_import_sgf(Game *game, FILE *f)
Read a game from a sgf file.
Definition game.c:823
void game_export_eps(const Game *game, FILE *f)
Write a game to an eps file.
Definition game.c:1264
void game_write(const Game *game, FILE *f)
Write a game to a binary file.
Definition game.c:440
void game_export_pgn(const Game *game, FILE *f)
Write a game to a pgn file.
Definition game.c:1203
void hash_exclude_move(HashTable *hash_table, const unsigned long long hash_code, const int move)
Erase an hash table entry.
Definition hash-lock-free.c:629
Move * movelist_best(MoveList *movelist)
Return the best move of the list.
Definition move.c:411
void line_print(const Line *line, int width, const char *separator, FILE *f)
Print a move sequence.
Definition move.c:610
bool movelist_is_empty(const MoveList *movelist)
Check if the list is empty.
Definition move.c:537
void line_push(Line *line, const int x)
Add a move to the sequence.
Definition move.c:561
void line_init(Line *line, const int player)
Initialize a sequence of moves.
Definition move.c:549
Move * movelist_exclude(MoveList *movelist, const int move)
Exclude a move.
Definition move.c:516
const Move MOVE_INIT
Definition move.c:25
char * move_to_string(const int x, const int player, char *s)
Print out a move.
Definition move.c:76
int symetry(int x, const int sym)
Get a symetric square coordinate.
Definition move.c:47
void line_copy(Line *dest, const Line *src, const int from)
Copy part of a sequence to another sequence.
Definition move.c:591
#define foreach_move(iter, movelist)
Definition move.h:78
const char * opening_get_line(const char *opening_name)
Translate an opening name into its move sequence.
Definition opening.c:1305
Options options
Definition options.c:22
@ EDAX_TIME_PER_MOVE
Definition options.h:20
void play_hint_prepare(Play *play, MoveList *exclude_list)
prepare hint for libEdax
Definition play.c:556
bool play_must_pass(Play *play)
Check if player must pass.
Definition play.c:202
void play_store(Play *play)
store the game into the opening book
Definition play.c:1175
static int play_book_alternative(Play *play, Move *played, Move *alternative)
Seek for the best alternative move from the opening book.
Definition play.c:1105
void play_force_restore(Play *play)
Restore a forced line.
Definition play.c:1364
bool play_force_go(Play *play, Move *move)
Play a forced move.
Definition play.c:1384
void play_get_bookmove(Play *play, MoveList *book_moves)
get book move for libEdax
Definition play.c:513
void play_set_board(Play *play, const char *board)
Set a new board.
Definition play.c:810
void play_print(Play *play, FILE *f)
Print the game state.
Definition play.c:1225
void play_analyze(Play *play, int n)
Analyze a played game.
Definition play.c:1033
void play_hint(Play *play, int n)
Start thinking.
Definition play.c:365
void play_set_board_from_FEN(Play *play, const char *board)
Set a new board.
Definition play.c:828
void play_ponder(Play *play)
Ponder.
Definition play.c:729
void play_hint_for_lib(Play *play, int n, HintList *hintlist)
hint for libEdax
Definition play.c:439
void play_stop_pondering(Play *play)
Stop pondering.
Definition play.c:749
bool play_move(Play *play, int x)
Play a move.
Definition play.c:889
void play_update(Play *play, Move *move)
Update the game.
Definition play.c:174
void play_book_analyze(Play *play, int n)
Analyze a played game.
Definition play.c:1140
void play_new(Play *play)
Start a new game.
Definition play.c:62
void play_save(Play *play, const char *file)
Save a played game.
Definition play.c:131
void play_init(Play *play, Book *book)
Initialization.
Definition play.c:27
const char * play_show_opening_name(Play *play, const char *(*opening_get_name)(const Board *))
Print the opening name.
Definition play.c:1438
bool play_user_move(Play *play, const char *string)
Play a user move.
Definition play.c:909
Move * play_get_last_move(Play *play)
Get the last played move.
Definition play.c:927
void play_hint_next(Play *play, Hint *hint, bool multiPvDepthMax)
get next hint
Definition play.c:589
void play_force_init(Play *play, const char *string)
Initialize a forced line.
Definition play.c:1313
void play_game(Play *play, const char *string)
Play a move sequence.
Definition play.c:866
void play_force_update(Play *play)
Update a forced line.
Definition play.c:1345
void play_adjust_time(Play *play, const int left, const int extra)
adjust time.
Definition play.c:1211
static int play_alternative(Play *play, Move *played, Move *alternative, int *depth, int *percent)
Seek for the best alternative move.
Definition play.c:943
void * play_ponder_run(void *v)
do ponderation.
Definition play.c:662
void play_symetry(Play *play, const int sym)
Get the symetry of the actual position.
Definition play.c:1418
int play_get_bookmove_with_position(Play *play, MoveList *book_moves, Position *position)
get book move for libEdax
Definition play.c:535
bool play_load(Play *play, const char *file)
Load a saved game.
Definition play.c:84
void play_undo(Play *play)
Undo a move.
Definition play.c:779
bool play_is_game_over(Play *play)
Check if game is over.
Definition play.c:190
void play_redo(Play *play)
Redo a move.
Definition play.c:795
void play_go(Play *play, const bool update)
Start thinking.
Definition play.c:214
void play_stop(Play *play)
Stop thinking.
Definition play.c:769
void play_set_board_from_obj(Play *play, const Board *board, const int turn)
Set a new board.
Definition play.c:846
void play_free(Play *play)
Free resources.
Definition play.c:52
static void play_write_analysis(Play *play, const Move *m, const Move *a, const int n_moves, const int depth, const int percent, FILE *f)
Write a line if an analysis.
Definition play.c:994
Edax play control - header file.
#define PLAY_MESSAGE_MAX_LENGTH
Definition play.h:22
void * search_run(void *v)
Search the bestmove of a given board.
Definition root.c:810
void search_time_init(Search *search)
Initialize the alloted time.
Definition search.c:697
void search_set_level(Search *search, const int level, const int n_empties)
Set the search level.
Definition search.c:609
void search_init(Search *search)
Init the main search.
Definition search.c:351
void search_time_reset(Search *search, const Board *initial_board)
Reset the alloted time.
Definition search.c:732
void search_free(Search *search)
Free the search allocated ressource.
Definition search.c:441
const Selectivity selectivity_table[]
Definition search.c:97
void result_print(Result *result, FILE *f)
Print the current search result.
Definition search.c:1106
void search_cleanup(Search *search)
Clean-up some search data.
Definition search.c:578
void search_set_board(Search *search, const Board *board, const int player)
Set the board to analyze.
Definition search.c:593
int search_guess(Search *search, const Board *board)
Guess the bestmove of a given board.
Definition search.c:1369
void search_stop_all(Search *search, const Stop stop)
Stop the search.
Definition search.c:1335
void search_set_move_time(Search *search, const long long t)
set time to search.
Definition search.c:686
void search_set_ponder_level(Search *search, const int level, const int n_empties)
Set the search level while pondering.
Definition search.c:629
long long search_time(Search *search)
Return the time spent by the search.
Definition search.c:1061
void search_set_game_time(Search *search, const long long t)
set time to search.
Definition search.c:671
#define MULTIPV_DEPTH
Definition settings.h:122
Definition board.h:26
unsigned long long player
Definition board.h:27
unsigned long long opponent
Definition board.h:27
The opening book.
Definition book.h:25
struct Book::@2 stats
int n_links
Definition book.h:40
int level
Definition book.h:32
int n_nodes
Definition book.h:39
struct Book::@1 options
int lower
Definition search.h:36
int upper
Definition search.h:37
Game statistics.
Definition book.h:57
unsigned long long n_lines
Definition book.h:61
Definition game.h:22
char move[60]
Definition game.h:33
Board initial_board[1]
Definition game.h:23
char player
Definition game.h:34
unsigned char date
Definition hash.h:55
Definition search.h:81
Hint hint[MAX_MOVE+2]
Definition search.h:82
int n_hints
Definition search.h:83
Definition search.h:62
int move
Definition search.h:65
int depth
Definition search.h:63
bool book_move
Definition search.h:72
int score
Definition search.h:66
Line pv[1]
Definition search.h:69
int upper
Definition search.h:67
int selectivity
Definition search.h:64
unsigned long long n_nodes
Definition search.h:71
int lower
Definition search.h:68
long long time
Definition search.h:70
Definition move.h:35
LogFile.
Definition util.h:423
FILE * f
Definition util.h:424
Definition move.h:29
int n_moves
Definition move.h:31
Definition move.h:20
int score
Definition move.h:23
int x
Definition move.h:22
PlayType play_type
Definition options.h:42
bool book_allowed
Definition options.h:60
bool can_ponder
Definition options.h:43
int n_task
Definition options.h:29
int level
Definition options.h:40
int depth
Definition options.h:44
int width
Definition options.h:34
int book_randomness
Definition options.h:61
long long time
Definition options.h:41
bool info
Definition options.h:36
char * book_file
Definition options.h:59
int selectivity
Definition options.h:45
int verbosity
Definition options.h:32
Definition play.h:25
int player
Definition play.h:32
long long clock
Definition play.h:39
bool verbose
Definition play.h:57
Board board[1]
Definition play.h:26
int n_move
Definition play.h:49
long long spent
Definition play.h:41
Move game[80]
Definition play.h:34
Board unique[80]
Definition play.h:47
Result result[1]
Definition play.h:29
struct Play::@22 force
long long left
Definition play.h:42
int initial_player
Definition play.h:33
Board initial_board[1]
Definition play.h:27
Thread thread
Definition play.h:53
bool launched
Definition play.h:56
int n_game
Definition play.h:36
struct Play::@21 time[2]
Move move[80]
Definition play.h:48
Search search[1]
Definition play.h:28
volatile PlayState state
Definition play.h:37
struct Play::@23 ponder[1]
int type
Definition play.h:31
char error_message[PLAY_MESSAGE_MAX_LENGTH]
Definition play.h:59
Book * book
Definition play.h:30
int i_game
Definition play.h:35
Board real[80]
Definition play.h:46
int i_move
Definition play.h:50
long long extra
Definition play.h:43
A position stored in the book.
Definition book.h:77
Definition search.h:41
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 selectivity
Definition search.h:43
Line pv[1]
Definition search.h:47
int depth
Definition search.h:42
Bound bound[BOARD_SIZE+2]
Definition search.h:46
Definition search.h:95
struct Search::@24 time
long long maxi
Definition search.h:130
const char * separator
Definition search.h:145
int n_empties
Definition search.h:99
bool keep_date
Definition search.h:143
void(* observer)(Result *)
Definition search.h:153
long long extra
Definition search.h:125
MoveList movelist[1]
Definition search.h:132
Result * result
Definition search.h:151
const char * header
Definition search.h:144
int id
Definition search.h:101
struct Search::@25 options
int verbosity
Definition search.h:142
int depth
Definition search.h:117
long long mini
Definition search.h:129
HashTable pv_table[1]
Definition search.h:104
HashTable hash_table[1]
Definition search.h:103
volatile Stop stop
Definition search.h:122
int selectivity
Definition search.h:118
Board board[1]
Definition search.h:96
int multipv_depth
Definition search.h:147
int percent
Definition search.h:28
void time_print(long long t, bool justified, FILE *f)
Print time as "D:HH:MM:SS.CC".
Definition util.c:131
char * parse_move(const char *string, const Board *board, Move *move)
Parse a move.
Definition util.c:627
char * file_add_ext(const char *base, const char *ext, char *file)
Add an extension to a string.
Definition util.c:907
void thread_create2(Thread *thread, void *(*function)(void *), void *data)
Create a thread.
Definition util.c:922
void thread_join(Thread thread)
Join a thread.
Definition util.c:940
void string_to_lowercase(char *s)
Change all char of a string to lowercase.
Definition util.c:355
void relax(int t)
sleep for t ms.
Definition util.c:203
long long real_clock(void)
#define MIN(a, b)
Definition util.h:101
long long cpu_clock(void)
#define log_print(l,...)
Print into the log file.
Definition util.h:442
#define fatal_error(...)
Display an error message as "FATAL_ERROR : file name : function name : line number : ....
Definition util.h:349
#define info(...)
Display a message.
Definition util.h:382
#define warn(...)
Display a warning message as "WARNING : ... ".
Definition util.h:373
#define log_is_open(l)
Check if the log stream can be used.
Definition util.h:448
Log xboard_log[1]
Definition xboard.c:26