is_ladder(): Extern inline switch between is_border_ladder() and is_middle_ladder()
[pachi/peepo.git] / playout.c
blobc4749b27e3eea3c5f39e56fe3984036aea0db207
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include "board.h"
7 #include "debug.h"
8 #include "engine.h"
9 #include "move.h"
10 #include "playout.h"
13 int
14 play_random_game(struct board *b, enum stone starting_color, int gamelen,
15 struct playout_amafmap *amafmap,
16 struct playout_policy *policy)
18 gamelen = gamelen - b->moves;
19 if (gamelen < 10)
20 gamelen = 10;
22 enum stone color = starting_color;
23 coord_t urgent;
25 int passes = is_pass(b->last_move.coord);
27 while (gamelen-- && passes < 2) {
28 urgent = policy->choose(policy, b, color);
30 coord_t coord;
32 if (!is_pass(urgent)) {
33 struct move m;
34 m.coord = urgent; m.color = color;
35 if (board_play(b, &m) < 0) {
36 if (DEBUGL(8)) {
37 fprintf(stderr, "Urgent move %d,%d is ILLEGAL:\n", coord_x(urgent, b), coord_y(urgent, b));
38 board_print(b, stderr);
40 goto play_random;
42 coord = urgent;
43 } else {
44 play_random:
45 board_play_random(b, color, &coord, (ppr_permit) policy->permit, policy);
48 #if 0
49 /* For UCT, superko test here is downright harmful since
50 * in superko-likely situation we throw away literally
51 * 95% of our playouts; UCT will deal with this fine by
52 * itself. */
53 if (unlikely(b->superko_violation)) {
54 /* We ignore superko violations that are suicides. These
55 * are common only at the end of the game and are
56 * rather harmless. (They will not go through as a root
57 * move anyway.) */
58 if (group_at(b, coord)) {
59 if (DEBUGL(3)) {
60 fprintf(stderr, "Superko fun at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
61 if (DEBUGL(4))
62 board_print(b, stderr);
64 return -1;
65 } else {
66 if (DEBUGL(6)) {
67 fprintf(stderr, "Ignoring superko at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
68 board_print(b, stderr);
70 b->superko_violation = false;
73 #endif
75 if (DEBUGL(7)) {
76 fprintf(stderr, "%s %s\n", stone2str(color), coord2sstr(coord, b));
77 if (DEBUGL(8))
78 board_print(b, stderr);
81 if (unlikely(is_pass(coord))) {
82 passes++;
83 } else {
84 /* We don't care about nakade counters, since we want
85 * to avoid taking pre-nakade moves into account only
86 * if they happenned in the tree before nakade nodes;
87 * but this is always out of the tree. */
88 if (amafmap) {
89 if (amafmap->map[coord] == S_NONE || amafmap->map[coord] == color)
90 amafmap->map[coord] = color;
91 else if (amafmap->record_nakade)
92 amaf_op(amafmap->map[coord], +);
93 amafmap->game[amafmap->gamelen].coord = coord;
94 amafmap->game[amafmap->gamelen].color = color;
95 amafmap->gamelen++;
96 assert(amafmap->gamelen < sizeof(amafmap->game) / sizeof(amafmap->game[0]));
99 passes = 0;
102 color = stone_other(color);
105 float score = board_fast_score(b);
106 bool result = (starting_color == S_WHITE ? (score > 0) : (score < 0));
108 if (DEBUGL(6)) {
109 fprintf(stderr, "Random playout result: %d (W %f)\n", result, score);
110 if (DEBUGL(7))
111 board_print(b, stderr);
114 return result;