Patternscan: Avoid overranking occurences of ko-take spatials
[pachi.git] / tactics / util.h
blob418935e1b205b079446320ebb5a8250d11be5d52
1 #ifndef PACHI_TACTICS_UTIL_H
2 #define PACHI_TACTICS_UTIL_H
4 /* Advanced tactical checks non-essential to the board implementation. */
6 #include "board.h"
7 #include "debug.h"
9 struct move_queue;
11 /* Checks if there are any stones in n-vincinity of coord. */
12 bool board_stone_radar(struct board *b, coord_t coord, int distance);
14 /* Measure various distances on the board: */
15 /* Distance from the edge; on edge returns 0. */
16 static int coord_edge_distance(coord_t c, struct board *b);
17 /* Distance of two points in gridcular metric - this metric defines
18 * circle-like structures on the square grid. */
19 static int coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b);
21 /* Construct a "common fate graph" from given coordinate; that is, a weighted
22 * graph of intersections where edges between all neighbors have weight 1,
23 * but edges between neighbors of same color have weight 0. Thus, this is
24 * "stone chain" metric in a sense. */
25 /* The output are distanes from start stored in given [board_size2()] array;
26 * intersections further away than maxdist have all distance maxdist+1 set. */
27 void cfg_distances(struct board *b, coord_t start, int *distances, int maxdist);
29 /* Compute an extra komi describing the "effective handicap" black receives
30 * (returns 0 for even game with 7.5 komi). @stone_value is value of single
31 * handicap stone, 7 is a good default. */
32 /* This is just an approximation since in reality, handicap seems to be usually
33 * non-linear. */
34 floating_t board_effective_handicap(struct board *b, int first_move_value);
36 /* Decide if the given player wins counting on the board, considering
37 * that given groups are dead. (To get the list of dead groups, use
38 * e.g. groups_of_status().) */
39 bool pass_is_safe(struct board *b, enum stone color, struct move_queue *mq);
41 /* Returns estimated number of remaining moves for one player until end of game. */
42 int board_estimated_moves_left(struct board *b);
44 /* To avoid running out of time, assume we always have at least 30 more moves
45 * to play if we don't have more precise information from gtp time_left: */
46 #define MIN_MOVES_LEFT 30
48 /* Tactical evaluation of move @coord by color @color, given
49 * simulation end position @b. I.e., a move is tactically good
50 * if the resulting group stays on board until the game end.
51 * The value is normalized to [0,1]. */
52 /* We can also take into account surrounding stones, e.g. to
53 * encourage taking off external liberties during a semeai. */
54 static double board_local_value(bool scan_neis, struct board *b, coord_t coord, enum stone color);
57 static inline int
58 coord_edge_distance(coord_t c, struct board *b)
60 int x = coord_x(c, b), y = coord_y(c, b);
61 int dx = x > board_size(b) / 2 ? board_size(b) - 1 - x : x;
62 int dy = y > board_size(b) / 2 ? board_size(b) - 1 - y : y;
63 return (dx < dy ? dx : dy) - 1 /* S_OFFBOARD */;
66 static inline int
67 coord_gridcular_distance(coord_t c1, coord_t c2, struct board *b)
69 int dx = abs(coord_dx(c1, c2, b)), dy = abs(coord_dy(c1, c2, b));
70 return dx + dy + (dx > dy ? dx : dy);
73 static inline double
74 board_local_value(bool scan_neis, struct board *b, coord_t coord, enum stone color)
76 if (scan_neis) {
77 /* Count surrounding friendly stones and our eyes. */
78 int friends = 0;
79 foreach_neighbor(b, coord, {
80 friends += board_at(b, c) == color || board_at(b, c) == S_OFFBOARD || board_is_one_point_eye(b, c, color);
81 });
82 return (double) (2 * (board_at(b, coord) == color) + friends) / 6.f;
83 } else {
84 return (board_at(b, coord) == color) ? 1.f : 0.f;
88 #endif