Fix PF_ANY for SELFATARI, CAPTURE, AESCAPE after recent changes
[pachi/peepo.git] / tactics.h
blob19483ec98655308fcc470584c3bbcdba3ff24042
1 #ifndef ZZGO_TACTICS_H
2 #define ZZGO_TACTICS_H
4 /* Advanced tactical checks non-essential to the board implementation. */
6 #include "board.h"
7 #include "debug.h"
9 struct move_queue;
11 /* Check if this move is undesirable self-atari (resulting group would have
12 * only single liberty and not capture anything; ko is allowed); we mostly
13 * want to avoid these moves. The function actually does a rather elaborate
14 * tactical check, allowing self-atari moves that are nakade, eye falsification
15 * or throw-ins. */
16 static bool is_bad_selfatari(struct board *b, enum stone color, coord_t to);
18 /* Check if escaping on this liberty by given group in atari would play out
19 * a simple ladder. */
20 /* Two ways of ladder reading can be enabled separately; simple first-line
21 * ladders and trivial middle-board ladders. */
22 static bool is_ladder(struct board *b, coord_t coord, group_t laddered,
23 bool border_ladders, bool middle_ladders);
25 /* Checks if there are any stones in n-vincinity of coord. */
26 bool board_stone_radar(struct board *b, coord_t coord, int distance);
28 /* Measure various distances on the board: */
29 /* Distance from the edge; on edge returns 0. */
30 static int coord_edge_distance(coord_t c, struct board *b);
31 /* Distance of two points in gridcular metric - this metric defines
32 * circle-like structures on the square grid. */
33 static int coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b);
35 /* Construct a "common fate graph" from given coordinate; that is, a weighted
36 * graph of intersections where edges between all neighbors have weight 1,
37 * but edges between neighbors of same color have weight 0. Thus, this is
38 * "stone chain" metric in a sense. */
39 /* The output are distanes from start stored in given [board_size2()] array;
40 * intersections further away than maxdist have all distance maxdist+1 set. */
41 void cfg_distances(struct board *b, coord_t start, int *distances, int maxdist);
43 /* Compute an extra komi describing the "effective handicap" black receives
44 * (returns 0 for even game with 7.5 komi). @stone_value is value of single
45 * handicap stone, 7 is a good default. */
46 /* This is just an approximation since in reality, handicap seems to be usually
47 * non-linear. */
48 float board_effective_handicap(struct board *b, int first_move_value);
50 /* Decide if the given player wins counting on the board, considering
51 * that given groups are dead. (To get the list of dead groups, use
52 * e.g. groups_of_status().) */
53 bool pass_is_safe(struct board *b, enum stone color, struct move_queue *mq);
55 /* Returns estimated number of remaining moves for one player until end of game. */
56 int board_estimated_moves_left(struct board *b);
58 /* To avoid running out of time, assume we always have at least 30 more moves
59 * to play if we don't have more precise information from gtp time_left: */
60 #define MIN_MOVES_LEFT 30
63 bool is_bad_selfatari_slow(struct board *b, enum stone color, coord_t to);
64 static inline bool
65 is_bad_selfatari(struct board *b, enum stone color, coord_t to)
67 /* More than one immediate liberty, thumbs up! */
68 if (immediate_liberty_count(b, to) > 1)
69 return false;
71 return is_bad_selfatari_slow(b, color, to);
74 bool is_border_ladder(struct board *b, coord_t coord, enum stone lcolor);
75 bool is_middle_ladder(struct board *b, coord_t coord, enum stone lcolor);
76 static inline bool
77 is_ladder(struct board *b, coord_t coord, group_t laddered,
78 bool border_ladders, bool middle_ladders)
80 enum stone lcolor = board_at(b, group_base(laddered));
82 if (DEBUGL(6))
83 fprintf(stderr, "ladder check - does %s play out %s's laddered group %s?\n",
84 coord2sstr(coord, b), stone2str(lcolor), coord2sstr(laddered, b));
86 /* First, special-case first-line "ladders". This is a huge chunk
87 * of ladders we actually meet and want to play. */
88 if (border_ladders
89 && neighbor_count_at(b, coord, S_OFFBOARD) == 1
90 && neighbor_count_at(b, coord, lcolor) == 1) {
91 bool l = is_border_ladder(b, coord, lcolor);
92 if (DEBUGL(6)) fprintf(stderr, "border ladder solution: %d\n", l);
93 return l;
96 if (middle_ladders) {
97 bool l = is_middle_ladder(b, coord, lcolor);
98 if (DEBUGL(6)) fprintf(stderr, "middle ladder solution: %d\n", l);
99 return l;
102 if (DEBUGL(6)) fprintf(stderr, "no ladder to be checked\n");
103 return false;
107 static inline int
108 coord_edge_distance(coord_t c, struct board *b)
110 int x = coord_x(c, b), y = coord_y(c, b);
111 int dx = x > board_size(b) / 2 ? board_size(b) - 1 - x : x;
112 int dy = y > board_size(b) / 2 ? board_size(b) - 1 - y : y;
113 return (dx < dy ? dx : dy) - 1 /* S_OFFBOARD */;
116 static inline int
117 coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b)
119 int dx = abs(coord_dx(c1, c2, b)), dy = abs(coord_dy(c1, c2, b));
120 return dx + dy + (dx > dy ? dx : dy);
123 #endif