UCT: Fix pass-pass result determination
[pachi.git] / playout.c
blob09c761ae4c83f97ba0a76024c51e56de657bf6a6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "board.h"
6 #include "debug.h"
7 #include "engine.h"
8 #include "move.h"
9 #include "playout.h"
11 int
12 play_random_game(struct board *b, struct move *m, int gamelen,
13 playout_policeman policeman, void *policy)
15 if (b->superko_violation) {
16 if (DEBUGL(0)) {
17 fprintf(stderr, "\tILLEGAL: superko violation at root!\n");
18 board_print(b, stderr);
20 return -1;
23 struct board b2;
24 board_copy(&b2, b);
26 board_play_random(&b2, m->color, &m->coord);
27 if (!is_pass(m->coord) && !group_at(&b2, m->coord)) {
28 if (DEBUGL(4)) {
29 fprintf(stderr, "SUICIDE DETECTED at %d,%d:\n", coord_x(m->coord, b), coord_y(m->coord, b));
30 board_print(&b2, stderr);
32 board_done_noalloc(&b2);
33 return -3;
36 if (DEBUGL(3))
37 fprintf(stderr, "[%d,%d] playing random game of color %d\n", coord_x(m->coord, b), coord_y(m->coord, b), m->color);
39 gamelen = gamelen - b2.moves;
40 if (gamelen < 10)
41 gamelen = 10;
43 enum stone color = stone_other(m->color);
44 coord_t urgent;
46 int passes = is_pass(m->coord);
48 /* Special check: We probably tenukied the last opponent's move. But
49 * check if the opponent has lucrative local continuation for her last
50 * move! */
51 /* This check is ultra-important BTW. Without it domain checking does
52 * not bring that much of an advantage. It might even warrant it to by
53 * default do only this domain check. */
54 urgent = policeman(policy, b, m->color);
55 if (!is_pass(urgent))
56 goto play_urgent;
58 while (gamelen-- && passes < 2) {
59 urgent = policeman(policy, &b2, m->color);
61 coord_t coord;
63 if (!is_pass(urgent)) {
64 struct move m;
65 play_urgent:
66 m.coord = urgent; m.color = color;
67 if (board_play(&b2, &m) < 0) {
68 if (DEBUGL(8)) {
69 fprintf(stderr, "Urgent move %d,%d is ILLEGAL:\n", coord_x(urgent, b), coord_y(urgent, b));
70 board_print(&b2, stderr);
72 goto play_random;
74 coord = urgent;
75 } else {
76 play_random:
77 board_play_random(&b2, color, &coord);
80 if (unlikely(b2.superko_violation)) {
81 /* We ignore superko violations that are suicides. These
82 * are common only at the end of the game and are
83 * rather harmless. (They will not go through as a root
84 * move anyway.) */
85 if (group_at(&b2, coord)) {
86 if (DEBUGL(3)) {
87 fprintf(stderr, "Superko fun at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
88 if (DEBUGL(4))
89 board_print(&b2, stderr);
91 board_done_noalloc(&b2);
92 return -2;
93 } else {
94 if (DEBUGL(6)) {
95 fprintf(stderr, "Ignoring superko at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
96 board_print(&b2, stderr);
98 b2.superko_violation = false;
102 if (DEBUGL(8)) {
103 char *cs = coord2str(coord, b);
104 fprintf(stderr, "%s %s\n", stone2str(color), cs);
105 free(cs);
108 if (unlikely(is_pass(coord))) {
109 passes++;
110 } else {
111 passes = 0;
114 color = stone_other(color);
117 float score = board_fast_score(&b2);
118 bool result = (m->color == S_WHITE ? (score > 0) : (score < 0));
120 if (DEBUGL(6)) {
121 fprintf(stderr, "Random playout result: %d (W %f)\n", result, score);
122 if (DEBUGL(7))
123 board_print(&b2, stderr);
126 board_done_noalloc(&b2);
127 return result;