File: liberty.h

package info (click to toggle)
gnugo 3.8-4
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 17,312 kB
  • ctags: 4,228
  • sloc: ansic: 56,439; perl: 3,771; lisp: 2,789; sh: 730; makefile: 700; python: 682; awk: 113; sed: 22
file content (1065 lines) | stat: -rw-r--r-- 41,512 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * 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.                                            *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef _LIBERTY_H_
#define _LIBERTY_H_

#include "board.h"
#include "hash.h"
#include "gnugo.h"
#include "winsocket.h"

/* ================================================================ */
/*                           public variables                       */
/* ================================================================ */


/* ================================================================ */


#define FALSE_EYE          1
#define HALF_EYE           2


#define REVERSE_RESULT(result)		(WIN - result)


void start_timer(int n);
double time_report(int n, const char *occupation, int move, double mintime);
void showstats(void);
void clearstats(void);

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. */
enum routine_id {
  OWL_ATTACK,
  OWL_DEFEND,
  SEMEAI,
  FIND_DEFENSE,
  ATTACK,
  CONNECT,
  DISCONNECT,
  BREAK_IN,
  BLOCK_OFF,
  OWL_THREATEN_ATTACK,
  OWL_THREATEN_DEFENSE,
  OWL_DOES_DEFEND,
  OWL_DOES_ATTACK,
  OWL_CONNECTION_DEFENDS,
  OWL_SUBSTANTIAL,
  OWL_CONFIRM_SAFETY,
  ANALYZE_SEMEAI,
  NUM_CACHE_ROUTINES
};

#define ROUTINE_NAMES \
  "owl_attack", \
  "owl_defend", \
  "semeai", \
  "find_defense", \
  "attack", \
  "connect", \
  "disconnect", \
  "break_in", \
  "block_off", \
  "owl_threaten_attack", \
  "owl_threatend_defense", \
  "owl_does_defend", \
  "owl_does_attack", \
  "owl_connection_defends", \
  "owl_substantial", \
  "owl_confirm_safety", \
  "analyze_semeai"

/* To prioritize between different types of reading, we give a cost
 * ranking to each of the routines above:
 *
 * 4 semeai
 * 3 owl
 * 2 break-in
 * 1 connection
 * 0 tactical reading
 *
 * -1 is left at the end for a consistency check.
 */
#define ROUTINE_COSTS \
  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.
 */
enum dragon_status {
  DEAD,
  ALIVE,
  CRITICAL,
  UNKNOWN,
  UNCHECKED,
  CAN_THREATEN_ATTACK,
  CAN_THREATEN_DEFENSE, 
  INESSENTIAL,
  TACTICALLY_DEAD,
  ALIVE_IN_SEKI,
  STRONGLY_ALIVE,
  INVINCIBLE,
  INSUBSTANTIAL,
  WHITE_TERRITORY,
  BLACK_TERRITORY,
  DAME,
  NUM_DRAGON_STATUS
};

#define DRAGON_STATUS_NAMES \
  "dead", \
  "alive", \
  "critical", \
  "unknown", \
  "unchecked", \
  "can threaten attack", \
  "can threaten defense", \
  "inessential", \
  "tactically dead", \
  "alive in seki", \
  "strongly alive", \
  "invincible", \
  "insubstantial", \
  "white_territory", \
  "black_territory", \
  "dame"

const char *status_to_string(enum dragon_status status);


/* Forward struct declarations. */
struct pattern;
struct pattern_db;
struct fullboard_pattern;
struct corner_pattern;
struct corner_db;
struct half_eye_data;
struct movelist;

/*
 * Try to match a pattern in the database to the board. Callbacks for
 * each match.
 */
typedef void (*matchpat_callback_fn_ptr)(int anchor, int color,
                                         struct pattern *, int rotation,
                                         void *data);
typedef void (*fullboard_matchpat_callback_fn_ptr)(int move,
                                                   struct fullboard_pattern *,
                                                   int rotation);
typedef void (*corner_matchpat_callback_fn_ptr)(int move, int color,
						struct corner_pattern *pattern,
						int trans,
						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);

/* reading.c */
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);

/* persistent.c */
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,
				    int *result, int *move);
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,
				       int str1, int str2,
				       int *result, int *move);
void store_persistent_connection_cache(enum routine_id routine,
				       int str1, int str2,
				       int result, int move,
				       int tactical_nodes,
				       signed char connection_shadow[BOARDMAX]);
int search_persistent_breakin_cache(enum routine_id routine,
				    int str, Hash_data *goal_hash,
				    int breakin_node_limit,
				    int *result, int *move);
void store_persistent_breakin_cache(enum routine_id routine,
				    int str, Hash_data *goal_hash,
				    int result, int move,
				    int tactical_nodes,
				    int breakin_node_limit,
				    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,
				int *certain);
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],
				int goal_color);
void owl_hotspots(float values[BOARDMAX]);
int search_persistent_semeai_cache(enum routine_id routine,
			           int apos, int bpos, int cpos, int color,
				   Hash_data *goal_hash,
				   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,
				   Hash_data *goal_hash,
				   int resulta, int resultb,
				   int move, int certain, int tactical_nodes,
				   signed char goala[BOARDMAX],
				   signed char goalb[BOARDMAX]);


/* readconnect.c */
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);

struct eyevalue;
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_cuts(void);
void find_connections(void);

/* movelist.c */
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[]);

/* surround.c */
int compute_surroundings(int pos, int apos, int showboard,
			 int *surround_size);
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 */
#define ATTACK_STRING  1
#define DEFEND_STRING  2
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_lively(int pos);
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_mineye(int pos);
int owl_maxeye(int pos);
int owl_proper_eye(int pos);
int owl_eye_size(int pos);
int owl_lunch(int str);
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 color);
int unconditionally_meaningless_move(int pos, int color,
				     int *replacement_move);
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,
                                int liberty_cap);
void find_proper_superstring_liberties(int str, int *liberties, int *libs, 
                                       int liberty_cap);
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],
                            int liberty_cap);
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 fuseki(int color);
void semeai(void);
void semeai_move_reasons(int color);
void shapes(int color);
void endgame(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 save_verbose);
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 *move_frequencies);

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,
				   int recompute_dragons);

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.
 */
/* 	dead		0 */
#define SAFE_STONE 	1
#define OWL_SAVED_STONE	2

/* This format is used when exporting the moyo segmentation. */
#define MAX_MOYOS MAX_BOARD*MAX_BOARD

struct moyo_data
{
  int number; /* Number of moyos. */
  int segmentation[BOARDMAX]; /* Numbers the moyos. */
  int size[MAX_MOYOS];
  int owner[MAX_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!
 */
struct influence_data;
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 move);
int retrieve_delta_territory_cache(int pos, int color, float *move_value,
			           float *followup_value,
				   const struct influence_data *base,
				   Hash_data safety_hash);
void store_delta_territory_cache(int pos, int color, float move_value,
				 float followup_value,
				 const struct influence_data *base,
			         Hash_data safety_hash);

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,
	       			          struct moyo_data *moyo);
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,
		       int store, int pos);
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);


/* debugging support */
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)
#define OFFSET(dx, dy)\
  ((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)\
  do {\
    *tx = transformation2[trans][0][0] * (x) + transformation2[trans][0][1] * (y);\
    *ty = transformation2[trans][1][0] * (x) + transformation2[trans][1][1] * (y);\
  } while (0)


/* ================================================================ */
/*                         global variables                         */
/* ================================================================ */

extern int disable_threat_computation;
extern int disable_endgame_patterns;
extern int doing_scoring;

/* Reading parameters */
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
 * listed.
 *
 * 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_move;
extern int slowest_movenum;
extern double total_time;


struct eyevalue {
  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 */
};


struct half_eye_data {
  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

struct worm_data {
  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
   * result.
   */
  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) */

#define MAX_SURROUND 10

struct surround_data {
  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.
 */

struct dragon_data {
  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

struct dragon_data2 {
  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]
#else
struct dragon_data2 *dragon2_func(int pos);
#define DRAGON2(pos) (*dragon2_func(pos))
#endif

#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;

struct aftermath_data {
  int white_captured;
  int black_captured;
  int white_prisoners;
  int black_prisoners;
  int white_territory;
  int black_territory;
  int white_area;
  int black_area;
  int white_control[BOARDMAX];
  int black_control[BOARDMAX];
  enum dragon_status final_status[BOARDMAX];
};

#define MAX_EYE_ATTACKS 3

struct eye_data {
  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
 * eye_data.
 */
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],
		  int add_moves);
void compute_eyes_pessimistic(int pos, struct eyevalue *value,
                              int *pessimistic_min,
                              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],
		  int owl_call);
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,
		   struct eyevalue *sum);
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);

#endif  /* _LIBERTY_H_ */


/*
 * Local Variables:
 * tab-width: 8
 * c-basic-offset: 2
 * End:
 */