/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* ================================================================ */
/* ================================================================ */
/* ================================================================ */
#define REVERSE_RESULT(result) (WIN - result)
double time_report(int n
, const char *occupation
, int move
, double mintime
);
void transformation_init(void);
void ascii_report_worm(char *string
);
void report_dragon(FILE *outfile
, int pos
);
void ascii_report_dragon(char *string
);
struct dragon_data2
*dragon2_func(int pos
);
/* Routine names used by persistent and non-persistent caching schemes. */
"owl_threatend_defense", \
"owl_connection_defends", \
/* To prioritize between different types of reading, we give a cost
* ranking to each of the routines above:
* -1 is left at the end for a consistency check.
3, 3, 4, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, -1
const char *routine_id_to_string(enum routine_id routine
);
/* This is used for both the dragon status and safety fields.
* Also used for unconditional status in struct worm_data and for the
* final status computed by the aftermath code.
#define DRAGON_STATUS_NAMES \
"can threaten defense", \
const char *status_to_string(enum dragon_status status
);
/* Forward struct declarations. */
struct fullboard_pattern
;
* Try to match a pattern in the database to the board. Callbacks for
typedef void (*matchpat_callback_fn_ptr
)(int anchor
, int color
,
struct pattern
*, int rotation
,
typedef void (*fullboard_matchpat_callback_fn_ptr
)(int move
,
struct fullboard_pattern
*,
typedef void (*corner_matchpat_callback_fn_ptr
)(int move
, int color
,
struct corner_pattern
*pattern
,
int *stones
, int num_stones
);
void matchpat(matchpat_callback_fn_ptr callback
, int color
,
struct pattern_db
*pdb
, void *callback_data
,
signed char goal
[BOARDMAX
]);
void matchpat_goal_anchor(matchpat_callback_fn_ptr callback
, int color
,
struct pattern_db
*pdb
, void *callback_data
,
signed char goal
[BOARDMAX
], int anchor_in_goal
);
void fullboard_matchpat(fullboard_matchpat_callback_fn_ptr callback
,
int color
, struct fullboard_pattern
*pattern
);
void corner_matchpat(corner_matchpat_callback_fn_ptr callback
, int color
,
struct corner_db
*database
);
void dfa_match_init(void);
void reading_cache_init(int bytes
);
void reading_cache_clear(void);
float reading_cache_default_size(void);
int attack(int str
, int *move
);
int find_defense(int str
, int *move
);
int attack_and_defend(int str
,
int *attack_code
, int *attack_point
,
int *defend_code
, int *defense_point
);
int attack_either(int astr
, int bstr
);
int defend_both(int astr
, int bstr
);
int break_through(int apos
, int bpos
, int cpos
);
int attack_threats(int pos
, int max_points
, int moves
[], int codes
[]);
int restricted_defend1(int str
, int *move
,
int num_forbidden_moves
, int *forbidden_moves
);
int restricted_attack2(int str
, int *move
,
int num_forbidden_moves
, int *forbidden_moves
);
int simple_ladder(int str
, int *move
);
#define MOVE_ORDERING_PARAMETERS 67
void tune_move_ordering(int params
[MOVE_ORDERING_PARAMETERS
]);
void draw_reading_shadow(void);
void persistent_cache_init(void);
void purge_persistent_caches(void);
void clear_persistent_caches(void);
int search_persistent_reading_cache(enum routine_id routine
, int str
,
void store_persistent_reading_cache(enum routine_id routine
, int str
,
int result
, int move
, int nodes
);
void reading_hotspots(float values
[BOARDMAX
]);
int search_persistent_connection_cache(enum routine_id routine
,
void store_persistent_connection_cache(enum routine_id routine
,
signed char connection_shadow
[BOARDMAX
]);
int search_persistent_breakin_cache(enum routine_id routine
,
int str
, Hash_data
*goal_hash
,
void store_persistent_breakin_cache(enum routine_id routine
,
int str
, Hash_data
*goal_hash
,
signed char breakin_shadow
[BOARDMAX
]);
int search_persistent_owl_cache(enum routine_id routine
,
int apos
, int bpos
, int cpos
,
int *result
, int *move
, int *move2
,
void store_persistent_owl_cache(enum routine_id routine
,
int apos
, int bpos
, int cpos
,
int result
, int move
, int move2
, int certain
,
int tactical_nodes
, signed char goal
[BOARDMAX
],
void owl_hotspots(float values
[BOARDMAX
]);
int search_persistent_semeai_cache(enum routine_id routine
,
int apos
, int bpos
, int cpos
, int color
,
int *resulta
, int *resultb
,
int *move
, int *certain
);
void store_persistent_semeai_cache(enum routine_id routine
,
int apos
, int bpos
, int cpos
, int color
,
int resulta
, int resultb
,
int move
, int certain
, int tactical_nodes
,
signed char goala
[BOARDMAX
],
signed char goalb
[BOARDMAX
]);
int string_connect(int str1
, int str2
, int *move
);
int disconnect(int str1
, int str2
, int *move
);
int fast_disconnect(int str1
, int str2
, int *move
);
int non_transitivity(int str1
, int str2
, int str3
, int *move
);
int break_in(int str
, const signed char goal
[BOARDMAX
], int *move
);
int block_off(int str1
, const signed char goal
[BOARDMAX
], int *move
);
int obvious_false_eye(int pos
, int color
);
void estimate_lunch_eye_value(int lunch
, int *min
, int *probable
, int *max
,
int appreciate_one_two_lunches
);
int owl_topological_eye(int pos
, int color
);
int vital_chain(int pos
);
int confirm_safety(int move
, int color
, int *defense_point
,
signed char safe_stones
[BOARDMAX
]);
int dragon_weak(int pos
);
float dragon_weakness(int pos
, int ignore_dead_dragons
);
int size_of_biggest_critical_dragon(void);
void change_dragon_status(int dr
, enum dragon_status status
);
float blunder_size(int move
, int color
, int *defense_point
,
signed char safe_stones
[BOARDMAX
]);
void set_depth_values(int level
, int report_levels
);
void modify_depth_values(int n
);
void increase_depth_values(void);
void decrease_depth_values(void);
int get_depth_modification(void);
int safe_move(int move
, int color
);
int does_secure(int color
, int move
, int pos
);
void compute_new_dragons(int dragon_origins
[BOARDMAX
]);
void join_dragons(int d1
, int d2
);
int dragon_escape(signed char goal
[BOARDMAX
], int color
,
signed char escape_value
[BOARDMAX
]);
void compute_refined_dragon_weaknesses(void);
void compute_strategic_sizes(void);
void compute_dragon_genus(int d
, struct eyevalue
*genus
, int eye_to_exclude
);
float crude_dragon_weakness(int safety
, struct eyevalue
*genus
, int has_lunch
,
float moyo_value
, float escape_route
);
int is_same_dragon(int d1
, int d2
);
int are_neighbor_dragons(int d1
, int d2
);
void mark_dragon(int pos
, signed char mx
[BOARDMAX
], signed char mark
);
int first_worm_in_dragon(int d
);
int next_worm_in_dragon(int w
);
int lively_dragon_exists(int color
);
void compute_dragon_influence(void);
void set_strength_data(int color
, signed char safe_stones
[BOARDMAX
],
float strength
[BOARDMAX
]);
void mark_inessential_stones(int color
, signed char safe_stones
[BOARDMAX
]);
void add_cut(int apos
, int bpos
, int move
);
void cut_reasons(int color
);
void get_lively_stones(int color
, signed char safe_stones
[BOARDMAX
]);
int is_same_worm(int w1
, int w2
);
int is_worm_origin(int w
, int pos
);
void propagate_worm(int pos
);
void find_connections(void);
int movelist_move_known(int move
, int max_points
, int points
[], int codes
[]);
void movelist_change_point(int move
, int code
, int max_points
,
int points
[], int codes
[]);
int compute_surroundings(int pos
, int apos
, int showboard
,
int is_surrounded(int pos
);
int does_surround(int move
, int dragon
);
void reset_surround_data(void);
int surround_map(int dr
, int pos
);
/* functions to add (or remove) move reasons */
void collect_move_reasons(int color
);
void clear_move_reasons(void);
void add_lunch(int eater
, int food
);
void add_attack_move(int pos
, int ww
, int code
);
void add_defense_move(int pos
, int ww
, int code
);
void add_attack_threat_move(int pos
, int ww
, int code
);
void remove_attack_threat_move(int pos
, int ww
);
void add_defense_threat_move(int pos
, int ww
, int code
);
void add_connection_move(int pos
, int dr1
, int dr2
);
void add_cut_move(int pos
, int dr1
, int dr2
);
void add_antisuji_move(int pos
);
void add_semeai_move(int pos
, int dr
);
void add_potential_semeai_attack(int pos
, int dr1
, int dr2
);
void add_potential_semeai_defense(int pos
, int dr1
, int dr2
);
void add_semeai_threat(int pos
, int dr
);
void add_owl_attack_move(int pos
, int dr
, int kworm
, int code
);
void add_owl_defense_move(int pos
, int dr
, int code
);
void add_owl_attack_threat_move(int pos
, int dr
, int code
);
void add_owl_defense_threat_move(int pos
, int dr
, int code
);
void add_owl_prevent_threat_move(int pos
, int dr
);
void add_owl_uncertain_defense_move(int pos
, int dr
);
void add_owl_uncertain_attack_move(int pos
, int dr
);
void add_gain_move(int pos
, int target1
, int target2
);
void add_loss_move(int pos
, int target1
, int target2
);
void add_my_atari_atari_move(int pos
, int size
);
void add_your_atari_atari_move(int pos
, int size
);
void add_vital_eye_move(int pos
, int eyespace
, int color
);
void add_invasion_move(int pos
);
void add_expand_territory_move(int pos
);
void add_expand_moyo_move(int pos
);
void add_strategical_attack_move(int pos
, int dr
);
void add_strategical_defense_move(int pos
, int dr
);
void add_worthwhile_threat_move(int pos
);
void add_replacement_move(int from
, int to
, int color
);
/* Parameters to add_either_move and add_all_move */
void add_either_move(int pos
, int reason1
, int target1
,
int reason2
, int target2
);
void add_all_move(int pos
, int reason1
, int target1
,
int reason2
, int target2
);
int set_minimum_move_value(int pos
, float value
);
void set_maximum_move_value(int pos
, float value
);
void set_minimum_territorial_value(int pos
, float value
);
void set_maximum_territorial_value(int pos
, float value
);
void add_shape_value(int pos
, float value
);
void add_followup_value(int pos
, float value
);
void add_reverse_followup_value(int pos
, float value
);
int list_move_reasons(FILE *out
, int pos
);
void print_all_move_values(FILE *output
);
void record_top_move(int move
, float val
);
void remove_top_move(int move
);
void scale_randomness(int pos
, float scaling
);
void compute_move_probabilities(float probabilities
[BOARDMAX
]);
void register_good_attack_threat(int move
, int target
);
int is_known_good_attack_threat(int move
, int target
);
void register_known_safe_move(int move
);
int is_known_safe_move(int move
);
int get_attack_threats(int pos
, int max_strings
, int strings
[]);
int get_defense_threats(int pos
, int max_strings
, int strings
[]);
void get_saved_worms(int pos
, signed char saved
[BOARDMAX
]);
void get_saved_dragons(int pos
, signed char saved
[BOARDMAX
]);
void mark_safe_stones(int color
, int move_pos
,
const signed char saved_dragons
[BOARDMAX
],
const signed char saved_worms
[BOARDMAX
],
signed char safe_stones
[BOARDMAX
]);
int owl_escape_value(int pos
);
int owl_goal_dragon(int pos
);
int owl_eyespace(int pos
);
int owl_big_eyespace(int pos
);
int owl_proper_eye(int pos
);
int owl_eye_size(int pos
);
int owl_strong_dragon(int pos
);
void owl_reasons(int color
);
void unconditional_life(int unconditional_territory
[BOARDMAX
], int color
);
void clear_unconditionally_meaningless_moves(void);
void find_unconditionally_meaningless_moves(int unconditional_territory
[BOARDMAX
],
int unconditionally_meaningless_move(int pos
, int color
,
void unconditional_move_reasons(int color
);
void find_superstring(int str
, int *num_stones
, int *stones
);
void find_superstring_conservative(int str
, int *num_stones
, int *stones
);
void find_superstring_liberties(int str
, int *liberties
, int *libs
,
void find_proper_superstring_liberties(int str
, int *liberties
, int *libs
,
void find_superstring_stones_and_liberties(int str
, int *num_stones
,
int *stones
, int *liberties
,
int *libs
, int liberty_cap
);
void superstring_chainlinks(int str
, int *num_adj
, int adj
[MAXCHAIN
],
void proper_superstring_chainlinks(int str
, int *num_adj
,
int adj
[MAXCHAIN
], int liberty_cap
);
int place_fixed_handicap(int handicap
); /* place stones on board only */
int place_free_handicap(int handicap
); /* place stones on board only */
int free_handicap_remaining_stones(void);
int free_handicap_total_stones(void);
/* Various different strategies for finding a move */
void semeai_move_reasons(int color
);
void endgame_shapes(int color
);
void combinations(int color
);
int atari_atari(int color
, int *attack_move
,
signed char defense_moves
[BOARDMAX
],
int atari_atari_confirm_safety(int color
, int tpos
, int *move
, int minsize
,
const signed char saved_dragons
[BOARDMAX
],
const signed char saved_worms
[BOARDMAX
]);
int atari_atari_blunder_size(int color
, int tpos
,
signed char defense_moves
[BOARDMAX
],
const signed char safe_stones
[BOARDMAX
]);
int review_move_reasons(int *move
, float *value
, int color
,
float pure_threat_value
, float our_score
,
int allowed_moves
[BOARDMAX
],
int use_thrashing_dragon_heuristics
);
void prepare_move_influence_debugging(int pos
, int color
);
int fill_liberty(int *move
, int color
);
int aftermath_genmove(int color
, int do_capture_dead_stones
,
int allowed_moves
[BOARDMAX
]);
enum dragon_status
aftermath_final_status(int color
, int pos
);
int mc_get_size_of_pattern_values_table(void);
int mc_load_patterns_from_db(const char *filename
, unsigned int *values
);
void mc_init_patterns(const unsigned int *values
);
int choose_mc_patterns(char *name
);
void list_mc_patterns(void);
void uct_genmove(int color
, int *move
, int *forbidden_moves
,
int *allowed_moves
, int nodes
, float *move_values
,
int owl_attack(int target
, int *attack_point
, int *certain
, int *kworm
);
int owl_defend(int target
, int *defense_point
, int *certain
, int *kworm
);
int owl_threaten_attack(int target
, int *attack1
, int *attack2
);
int owl_threaten_defense(int target
, int *defend1
, int *defend2
);
int owl_does_defend(int move
, int target
, int *kworm
);
int owl_confirm_safety(int move
, int target
, int *defense_point
, int *kworm
);
int owl_does_attack(int move
, int target
, int *kworm
);
int owl_connection_defends(int move
, int target1
, int target2
);
int owl_substantial(int str
);
void owl_analyze_semeai(int apos
, int bpos
,
int *resulta
, int *resultb
, int *semeai_move
,
int owl
, int *semeai_result_certain
);
void owl_analyze_semeai_after_move(int move
, int color
, int apos
, int bpos
,
int *resulta
, int *resultb
,
int *semeai_move
, int owl
,
int *semeai_result_certain
,
void set_limit_search(int value
);
void set_search_diamond(int pos
);
void reset_search_mask(void);
void set_search_mask(int pos
, int value
);
int oracle_play_move(int pos
, int color
);
void consult_oracle(int color
);
void summon_oracle(void);
void oracle_loadsgf(char *infilename
, char *untilstring
);
int oracle_threatens(int move
, int target
);
int within_search_area(int pos
);
int metamachine_genmove(int color
, float *value
);
void draw_search_area(void);
int genmove_restricted(int color
, int allowed_moves
[BOARDMAX
]);
void change_attack(int str
, int move
, int acode
);
void change_defense(int str
, int move
, int dcode
);
void change_attack_threat(int str
, int move
, int acode
);
void change_defense_threat(int str
, int move
, int dcode
);
int attack_move_known(int move
, int str
);
int defense_move_known(int move
, int str
);
int attack_threat_move_known(int move
, int str
);
int defense_threat_move_known(int move
, int str
);
void worm_reasons(int color
);
int semeai_move_reason_known(int move
, int dr
);
int does_attack(int move
, int str
);
int does_defend(int move
, int str
);
int double_atari(int move
, int color
, float *value
,
signed char safe_stones
[BOARDMAX
]);
int playing_into_snapback(int move
, int color
);
int play_attack_defend_n(int color
, int do_attack
, int num_moves
, ...);
int play_attack_defend2_n(int color
, int do_attack
, int num_moves
, ...);
int play_break_through_n(int color
, int num_moves
, ...);
int play_connect_n(int color
, int do_connect
, int num_moves
, ...);
int play_lib_n(int color
, int num_moves
, ...);
int cut_possible(int pos
, int color
);
int defend_against(int move
, int color
, int apos
);
int somewhere(int color
, int check_alive
, int num_moves
, ...);
int visible_along_edge(int color
, int apos
, int bpos
);
int test_symmetry_after_move(int move
, int color
, int strict
);
/* Printmoyo values, specified by -m flag. */
#define PRINTMOYO_TERRITORY 0x01
#define PRINTMOYO_MOYO 0x02
#define PRINTMOYO_AREA 0x04
/* The following have been borrowed by the influence functions below. */
#define PRINTMOYO_INITIAL_INFLUENCE 0x08
#define PRINTMOYO_PRINT_INFLUENCE 0x10
#define PRINTMOYO_NUMERIC_INFLUENCE 0x20
#define PRINTMOYO_PERMEABILITY 0x40
#define PRINTMOYO_STRENGTH 0x80
#define PRINTMOYO_ATTENUATION 0x100
#define PRINTMOYO_VALUE_TERRITORY 0x200
/* These values are used to communicate whether stones are safe or
* have been saved, when computing influence.
#define INFLUENCE_SAFE_STONE 1
#define INFLUENCE_SAVED_STONE 2
/* These values are used to communicate the status of stones when analyzing
* a move for potentially being a blunder.
#define OWL_SAVED_STONE 2
/* This format is used when exporting the moyo segmentation. */
#define MAX_MOYOS MAX_BOARD*MAX_BOARD
int number
; /* Number of moyos. */
int segmentation
[BOARDMAX
]; /* Numbers the moyos. */
float territorial_value
[MAX_MOYOS
];
/* We use a forward declaration of influence_data so that the rest
* of the engine can reference influence data. It can only be accessed
* in influence.c, however!
extern struct influence_data initial_black_influence
;
extern struct influence_data initial_white_influence
;
extern struct influence_data move_influence
;
extern struct influence_data followup_influence
;
#define INITIAL_INFLUENCE(color) ((color) == WHITE ? \
&initial_white_influence \
: &initial_black_influence)
#define OPPOSITE_INFLUENCE(color) (INITIAL_INFLUENCE(OTHER_COLOR(color)))
#define DEFAULT_STRENGTH 100.0
/* Influence functions. */
void compute_influence(int color
, const signed char safe_stones
[BOARDMAX
],
const float strength
[BOARDMAX
],
struct influence_data
*q
,
int move
, const char *trace_message
);
void compute_followup_influence(const struct influence_data
*base
,
struct influence_data
*q
,
int move
, const char *trace_message
);
void compute_escape_influence(int color
,
const signed char safe_stones
[BOARDMAX
],
const signed char goal
[BOARDMAX
],
const float strength
[BOARDMAX
],
signed char escape_value
[BOARDMAX
]);
float influence_delta_territory(const struct influence_data
*base
,
const struct influence_data
*q
, int color
,
int retrieve_delta_territory_cache(int pos
, int color
, float *move_value
,
const struct influence_data
*base
,
void store_delta_territory_cache(int pos
, int color
, float move_value
,
const struct influence_data
*base
,
int whose_territory(const struct influence_data
*q
, int pos
);
int whose_moyo(const struct influence_data
*q
, int pos
);
int whose_moyo_restricted(const struct influence_data
*q
, int pos
);
int whose_area(const struct influence_data
*q
, int pos
);
float influence_territory(const struct influence_data
*q
, int pos
, int color
);
void influence_get_territory_segmentation(struct influence_data
*q
,
void get_influence(const struct influence_data
*q
,
float white_influence
[BOARDMAX
],
float black_influence
[BOARDMAX
],
float white_strength
[BOARDMAX
],
float black_strength
[BOARDMAX
],
float white_attenuation
[BOARDMAX
],
float black_attenuation
[BOARDMAX
],
float white_permeability
[BOARDMAX
],
float black_permeability
[BOARDMAX
],
float territory_value
[BOARDMAX
],
int influence_regions
[BOARDMAX
],
int non_territory
[BOARDMAX
]);
float influence_score(const struct influence_data
*q
, int chinese_rules
);
float game_status(int color
);
void influence_mark_non_territory(int pos
, int color
);
int influence_considered_lively(const struct influence_data
*q
, int pos
);
void influence_erase_territory(struct influence_data
*q
, int pos
, int color
);
void break_territories(int color_to_move
, struct influence_data
*q
,
void clear_break_in_list(void);
void break_in_move_reasons(int color
);
void choose_strategy(int color
, float our_score
, float game_status
);
/* Eye space functions. */
int is_eye_space(int pos
);
int is_proper_eye_space(int pos
);
int is_marginal_eye_space(int pos
);
int max_eye_value(int pos
);
void test_eyeshape(int eyesize
, int *eye_vertices
);
int analyze_eyegraph(const char *coded_eyegraph
, struct eyevalue
*value
,
char *analyzed_eyegraph
);
void goaldump(const signed char goal
[BOARDMAX
]);
void move_considered(int move
, float value
);
/* Transformation stuff. */
#define MAX_OFFSET (2*MAX_BOARD - 1) * (2*MAX_BOARD - 1)
((dy + MAX_BOARD - 1) * (2*MAX_BOARD - 1) + (dx + MAX_BOARD - 1))
#define OFFSET_DELTA(dx, dy) (OFFSET(dx, dy) - OFFSET(0, 0))
#define CENTER_OFFSET(offset) (offset - OFFSET(0, 0))
#define TRANSFORM(offset, trans) (transformation[offset][trans])
#define AFFINE_TRANSFORM(offset, trans, delta)\
(transformation[offset][trans] + delta)
#define TRANSFORM2(x, y, tx, ty, trans)\
*tx = transformation2[trans][0][0] * (x) + transformation2[trans][0][1] * (y);\
*ty = transformation2[trans][1][0] * (x) + transformation2[trans][1][1] * (y);\
/* ================================================================ */
/* ================================================================ */
extern int disable_threat_computation
;
extern int disable_endgame_patterns
;
extern int doing_scoring
;
extern int depth
; /* deep reading cutoff */
extern int backfill_depth
; /* deep reading cutoff */
extern int backfill2_depth
; /* deep reading cutoff */
extern int break_chain_depth
; /* deep reading cutoff */
extern int superstring_depth
; /* deep reading cutoff */
extern int branch_depth
; /* deep reading cutoff */
extern int fourlib_depth
; /* deep reading cutoff */
extern int ko_depth
; /* deep ko reading cutoff */
extern int aa_depth
; /* deep global reading cutoff */
extern int depth_offset
; /* keeps track of temporary depth changes */
extern int owl_distrust_depth
; /* below this owl trusts the optics code */
extern int owl_branch_depth
; /* below this owl tries only one variation */
extern int owl_reading_depth
; /* owl does not read below this depth */
extern int owl_node_limit
; /* maximum number of nodes considered */
extern int semeai_branch_depth
;
extern int semeai_branch_depth2
;
extern int semeai_node_limit
;
extern int connect_depth
;
extern int connect_depth2
;
extern int connection_node_limit
;
extern int breakin_depth
;
extern int breakin_node_limit
;
extern int semeai_variations
; /* max variations considered reading semeai */
extern float best_move_values
[10];
extern int best_moves
[10];
extern int experimental_owl_ext
; /* use experimental owl (GAIN/LOSS) */
extern int experimental_semeai
; /* use experimental semeai module */
extern int experimental_connections
; /* use experimental connection module */
extern int alternate_connections
; /* use alternate connection module */
extern int owl_threats
; /* compute owl threats */
extern int experimental_break_in
; /* use experimental module breakin.c */
extern int cosmic_gnugo
; /* use center oriented influence */
extern int large_scale
; /* seek large scale captures */
extern int thrashing_dragon
; /* Dead opponent's dragon trying to live */
extern signed char thrashing_stone
[BOARDMAX
]; /* All thrashing stones. */
extern int transformation
[MAX_OFFSET
][8];
extern const int transformation2
[8][2][2];
/* Arrays pointing out the closest worms from each vertex. The first
* one is the closest worms of either color, the last two ones ignore
* worms of the other color. Beyond a certain distance from any worm
* no close worm is listed at all. Only the closest worm is listed
* and if more than one are equally close they are all listed. The
* number of equally close worms is given in the number_*_worms
* arrays. If more than MAX_CLOSE_WORMS are equally close, none is
* See compute_effective_worm_sizes() in worm.c for details.
#define MAX_CLOSE_WORMS 4
extern int close_worms
[BOARDMAX
][MAX_CLOSE_WORMS
];
extern int number_close_worms
[BOARDMAX
];
extern int close_black_worms
[BOARDMAX
][MAX_CLOSE_WORMS
];
extern int number_close_black_worms
[BOARDMAX
];
extern int close_white_worms
[BOARDMAX
][MAX_CLOSE_WORMS
];
extern int number_close_white_worms
[BOARDMAX
];
extern int false_eye_territory
[BOARDMAX
];
extern int forced_backfilling_moves
[BOARDMAX
];
extern double slowest_time
; /* Timing statistics */
extern int slowest_movenum
;
extern double total_time
;
unsigned char a
; /* number of eyes if attacker plays first twice */
unsigned char b
; /* number of eyes if attacker plays first */
unsigned char c
; /* number of eyes if defender plays first */
unsigned char d
; /* number of eyes if defender plays first twice */
float value
; /* Topological eye value. */
unsigned char type
; /* HALF_EYE or FALSE_EYE; */
int num_attacks
; /* number of attacking points */
int attack_point
[4]; /* the moves to attack a topological halfeye */
int num_defenses
; /* number of defending points */
int defense_point
[4]; /* the moves to defend a topological halfeye */
/* array of half-eye data */
extern struct half_eye_data half_eye
[BOARDMAX
];
* data concerning a worm. A copy is kept at each vertex of the worm.
#define MAX_TACTICAL_POINTS 10
int color
; /* its color */
int size
; /* its cardinality */
float effective_size
; /* stones and surrounding spaces */
int origin
; /* the origin of the string. Two vertices are in */
/* the same worm iff they have same origin. */
int liberties
; /* number of liberties */
int liberties2
; /* number of second order liberties */
int liberties3
; /* third order liberties (empty vertices at distance 3) */
int liberties4
; /* fourth order liberties */
int lunch
; /* if lunch != 0 then lunch points to a boundary */
/* worm which can be captured easily. */
int cutstone
; /* 1=potential cutting stone; 2=cutting stone */
int cutstone2
; /* Number of potential cuts involving the worm. */
int genus
; /* number of connected components of the complement, less one */
int inessential
; /* 1=inessential worm */
int invincible
; /* 1=strongly unconditionally non-capturable */
enum dragon_status unconditional_status
; /* ALIVE, DEAD, WHITE_TERRITORY,
BLACK_TERRITORY, UNKNOWN */
/* The following arrays keeps track of up to MAX_TACTICAL_POINTS
* different attack, defense, attack threat, and defense threat
* points with corresponding result codes. (0 = loss, 1 = bad ko, 2
* = good ko, 3 = win). The arrays are guaranteed to be sorted with
* respect to the codes so that the first element contains the best
int attack_points
[MAX_TACTICAL_POINTS
];
int attack_codes
[MAX_TACTICAL_POINTS
];
int defense_points
[MAX_TACTICAL_POINTS
];
int defense_codes
[MAX_TACTICAL_POINTS
];
int attack_threat_points
[MAX_TACTICAL_POINTS
];
int attack_threat_codes
[MAX_TACTICAL_POINTS
];
int defense_threat_points
[MAX_TACTICAL_POINTS
];
int defense_threat_codes
[MAX_TACTICAL_POINTS
];
extern struct worm_data worm
[BOARDMAX
];
/* Unconditionally meaningless moves. */
int meaningless_black_moves
[BOARDMAX
];
int meaningless_white_moves
[BOARDMAX
];
/* Surround cache (see surround.c) */
int dragon_number
; /* number of the (surrounded) beast */
signed char surround_map
[BOARDMAX
]; /* surround map */
extern struct surround_data surroundings
[MAX_SURROUND
];
extern int surround_pointer
;
* data concerning a dragon. A copy is kept at each stone of the string.
int color
; /* its color */
int id
; /* the index into the dragon2 array */
int origin
; /* the origin of the dragon. Two vertices are in the same */
/* dragon iff they have same origin. */
int size
; /* size of the dragon */
float effective_size
; /* stones and surrounding spaces */
enum dragon_status crude_status
; /* (ALIVE, DEAD, UNKNOWN, CRITICAL) */
enum dragon_status status
; /* best trusted status */
extern struct dragon_data dragon
[BOARDMAX
];
/* Supplementary data concerning a dragon. Only one copy is stored per
* dragon in the dragon2 array.
#define MAX_NEIGHBOR_DRAGONS 10
int origin
; /* the origin of the dragon */
int adjacent
[MAX_NEIGHBOR_DRAGONS
]; /* adjacent dragons */
int neighbors
; /* number of adjacent dragons */
int hostile_neighbors
; /* neighbors of opposite color */
int moyo_size
; /* size of surrounding influence moyo, */
float moyo_territorial_value
; /* ...and its territorial value */
enum dragon_status safety
; /* a more detailed status estimate */
float weakness
; /* a continuous estimate of the dragon's safety */
float weakness_pre_owl
; /* dragon safety based on pre-owl computations */
float strategic_size
; /* An effective size including weakness of neighbors */
int escape_route
; /* a measurement of likelihood of escape */
struct eyevalue genus
; /* the number of eyes (approximately) */
int heye
; /* coordinates of a half eye */
int lunch
; /* if lunch != 0 then lunch points to a boundary worm which */
/* can be captured easily. */
int surround_status
; /* Is it surrounded? */
int surround_size
; /* Size of the surrounding area */
int semeais
; /* number of semeais in which the dragon is involved */
int semeai_defense_code
;/* Result code for semeai defense. */
int semeai_defense_point
;/* Move found by semeai code to rescue dragon */
int semeai_defense_certain
;
int semeai_defense_target
; /* The opponent dragon involved in the semeai */
int semeai_attack_code
; /* Result code for semeai attack. */
int semeai_attack_point
; /* Move found by semeai code to kill dragon */
int semeai_attack_certain
;
int semeai_attack_target
; /* The opponent dragon involved in the semeai */
enum dragon_status owl_threat_status
; /* CAN_THREATEN_ATTACK/DEFENSE */
enum dragon_status owl_status
; /* (ALIVE, DEAD, UNKNOWN, CRITICAL, UNCHECKED) */
int owl_attack_point
; /* vital point for attack */
int owl_attack_code
; /* ko result code */
int owl_attack_certain
; /* 0 if owl reading node limit is reached */
int owl_attack_node_count
;
int owl_second_attack_point
;/* if attacker gets both attack points, wins */
int owl_defense_point
; /* vital point for defense */
int owl_defense_code
; /* ko result code */
int owl_defense_certain
; /* 0 if owl reading node limit is reached */
int owl_second_defense_point
;/* if defender gets both attack points, wins */
int owl_attack_kworm
; /* only valid when owl_attack_code is GAIN */
int owl_defense_kworm
; /* only valid when owl_defense_code is LOSS */
/* dragon2 is dynamically allocated */
extern int number_of_dragons
;
extern struct dragon_data2
*dragon2
;
/* Macros for accessing the dragon2 data with board coordinates and
* the dragon data with a dragon id.
#if 1 /* Trust DRAGON2 accesses */
#define DRAGON2(pos) dragon2[dragon[pos].id]
struct dragon_data2
*dragon2_func(int pos
);
#define DRAGON2(pos) (*dragon2_func(pos))
#define DRAGON(d) dragon[dragon2[d].origin]
extern float white_score
, black_score
;
/* Global variables to tune strategy. */
extern float minimum_value_weight
;
extern float maximum_value_weight
;
extern float invasion_malus_weight
;
extern float strategical_weight
;
extern float territorial_weight
;
extern float attack_dragon_weight
;
extern float followup_weight
;
int white_control
[BOARDMAX
];
int black_control
[BOARDMAX
];
enum dragon_status final_status
[BOARDMAX
];
#define MAX_EYE_ATTACKS 3
int color
; /* BLACK, WHITE, or GRAY */
int esize
; /* size of the eyespace */
int msize
; /* number of marginal vertices */
int origin
; /* The origin */
struct eyevalue value
; /* Number of eyes. */
/* The above fields are constant on the whole eyespace. */
/* ---------------------------------------------------------------- */
/* The below fields are not. */
unsigned char marginal
; /* This vertex is marginal */
unsigned char neighbors
; /* number of neighbors in eyespace */
unsigned char marginal_neighbors
; /* number of marginal neighbors */
struct vital_eye_points
{
int attack_points
[MAX_EYE_ATTACKS
];
int defense_points
[MAX_EYE_ATTACKS
];
extern struct vital_eye_points black_vital_points
[BOARDMAX
];
extern struct vital_eye_points white_vital_points
[BOARDMAX
];
extern struct eye_data white_eye
[BOARDMAX
];
extern struct eye_data black_eye
[BOARDMAX
];
/* Array with the information which was previously stored in the cut
* field and in the INHIBIT_CONNECTION bit of the type field in struct
extern int cutting_points
[BOARDMAX
];
/* The following declarations have to be postponed until after the
* definition of struct eye_data or struct half_eye_data.
void compute_eyes(int pos
, struct eyevalue
*value
,
int *attack_point
, int *defense_point
,
struct eye_data eye
[BOARDMAX
],
struct half_eye_data heye
[BOARDMAX
],
void compute_eyes_pessimistic(int pos
, struct eyevalue
*value
,
int *attack_point
, int *defense_point
,
struct eye_data eye
[BOARDMAX
],
struct half_eye_data heye
[BOARDMAX
]);
void propagate_eye(int pos
, struct eye_data eye
[BOARDMAX
]);
int find_eye_dragons(int origin
, struct eye_data eye
[BOARDMAX
], int eye_color
,
int dragons
[], int max_dragons
);
void make_domains(struct eye_data b_eye
[BOARDMAX
],
struct eye_data w_eye
[BOARDMAX
],
void partition_eyespaces(struct eye_data eye
[BOARDMAX
], int color
);
void find_half_and_false_eyes(int color
, struct eye_data eye
[BOARDMAX
],
struct half_eye_data heye
[BOARDMAX
],
int find_mask
[BOARDMAX
]);
void set_eyevalue(struct eyevalue
*e
, int a
, int b
, int c
, int d
);
int min_eye_threat(struct eyevalue
*e
);
int min_eyes(struct eyevalue
*e
);
int max_eyes(struct eyevalue
*e
);
int max_eye_threat(struct eyevalue
*e
);
void add_eyevalues(struct eyevalue
*e1
, struct eyevalue
*e2
,
int eye_move_urgency(struct eyevalue
*e
);
char *eyevalue_to_string(struct eyevalue
*e
);
int is_halfeye(struct half_eye_data heye
[BOARDMAX
], int pos
);
int is_false_eye(struct half_eye_data heye
[BOARDMAX
], int pos
);