Moggy: can_be_captured() -> can_play_on_lib()
[pachi.git] / playout.c
blob09bee7448a1f258a5eccd5f20b372089a5e8a461
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_ownermap *ownermap,
17 struct playout_policy *policy)
19 gamelen = gamelen - b->moves;
20 if (gamelen < 10)
21 gamelen = 10;
23 enum stone color = starting_color;
24 coord_t urgent;
26 int passes = is_pass(b->last_move.coord);
28 while (gamelen-- && passes < 2) {
29 urgent = policy->choose(policy, b, color);
31 coord_t coord;
33 if (!is_pass(urgent)) {
34 struct move m;
35 m.coord = urgent; m.color = color;
36 if (board_play(b, &m) < 0) {
37 if (DEBUGL(8)) {
38 fprintf(stderr, "Urgent move %d,%d is ILLEGAL:\n", coord_x(urgent, b), coord_y(urgent, b));
39 board_print(b, stderr);
41 goto play_random;
43 coord = urgent;
44 } else {
45 play_random:
46 board_play_random(b, color, &coord, (ppr_permit) policy->permit, policy);
49 #if 0
50 /* For UCT, superko test here is downright harmful since
51 * in superko-likely situation we throw away literally
52 * 95% of our playouts; UCT will deal with this fine by
53 * itself. */
54 if (unlikely(b->superko_violation)) {
55 /* We ignore superko violations that are suicides. These
56 * are common only at the end of the game and are
57 * rather harmless. (They will not go through as a root
58 * move anyway.) */
59 if (group_at(b, coord)) {
60 if (DEBUGL(3)) {
61 fprintf(stderr, "Superko fun at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
62 if (DEBUGL(4))
63 board_print(b, stderr);
65 return 0;
66 } else {
67 if (DEBUGL(6)) {
68 fprintf(stderr, "Ignoring superko at %d,%d in\n", coord_x(coord, b), coord_y(coord, b));
69 board_print(b, stderr);
71 b->superko_violation = false;
74 #endif
76 if (DEBUGL(7)) {
77 fprintf(stderr, "%s %s\n", stone2str(color), coord2sstr(coord, b));
78 if (DEBUGL(8))
79 board_print(b, stderr);
82 if (unlikely(is_pass(coord))) {
83 passes++;
84 } else {
85 /* We don't care about nakade counters, since we want
86 * to avoid taking pre-nakade moves into account only
87 * if they happenned in the tree before nakade nodes;
88 * but this is always out of the tree. */
89 if (amafmap) {
90 if (amafmap->map[coord] == S_NONE || amafmap->map[coord] == color)
91 amafmap->map[coord] = color;
92 else if (amafmap->record_nakade)
93 amaf_op(amafmap->map[coord], +);
94 amafmap->game[amafmap->gamelen].coord = coord;
95 amafmap->game[amafmap->gamelen].color = color;
96 amafmap->gamelen++;
97 assert(amafmap->gamelen < sizeof(amafmap->game) / sizeof(amafmap->game[0]));
100 passes = 0;
103 color = stone_other(color);
106 float score = board_fast_score(b);
107 int result = (starting_color == S_WHITE ? score * 2 : - (score * 2));
109 if (DEBUGL(6)) {
110 fprintf(stderr, "Random playout result: %d (W %f)\n", result, score);
111 if (DEBUGL(7))
112 board_print(b, stderr);
115 if (ownermap) {
116 ownermap->playouts++;
117 foreach_point(b) {
118 ownermap->map[board_at(b, c)]++;
119 } foreach_point_end;
122 return result;