-
RCS file: /sources/gnugo/gnugo/engine/board.h,v
retrieving revision 1.34
diff -u -r1.34 board.h
|
|
|
|
| 36 | 36 | * character access is very slow. |
| 37 | 37 | */ |
| 38 | 38 | |
| | 39 | /* simple test for old machines */ |
| | 40 | #if SIZEOF_INT >= 4 |
| | 41 | #define INT_INTERSECTION |
| | 42 | typedef int Intersection; |
| | 43 | #else |
| 39 | 44 | typedef unsigned char Intersection; |
| | 45 | #endif |
| 40 | 46 | |
| 41 | 47 | /* FIXME: This is very ugly but we can't include hash.h until we have |
| 42 | 48 | * defined Intersection. And we do need to include it before using |
| … |
… |
|
| 135 | 141 | |
| 136 | 142 | /* Note that POS(-1, -1) == 0 |
| 137 | 143 | * DELTA() is defined so that POS(i+di, j+dj) = POS(i, j) + DELTA(di, dj). |
| | 144 | * For details look in the documentation. |
| 138 | 145 | */ |
| 139 | 146 | #define BOARDSIZE ((MAX_BOARD + 2) * (MAX_BOARD + 1) + 1) |
| 140 | 147 | #define BOARDMIN (MAX_BOARD + 2) |
| … |
… |
|
| 148 | 155 | #define NS (MAX_BOARD + 1) |
| 149 | 156 | #define WE 1 |
| 150 | 157 | #define SOUTH(pos) ((pos) + NS) |
| 151 | | #define WEST(pos) ((pos) - 1) |
| | 158 | #define WEST(pos) ((pos) - WE) |
| 152 | 159 | #define NORTH(pos) ((pos) - NS) |
| 153 | | #define EAST(pos) ((pos) + 1) |
| 154 | | #define SW(pos) ((pos) + NS - 1) |
| 155 | | #define NW(pos) ((pos) - NS - 1) |
| 156 | | #define NE(pos) ((pos) - NS + 1) |
| 157 | | #define SE(pos) ((pos) + NS + 1) |
| | 160 | #define EAST(pos) ((pos) + WE) |
| | 161 | #define SW(pos) ((pos) + NS - WE) |
| | 162 | #define NW(pos) ((pos) - NS - WE) |
| | 163 | #define NE(pos) ((pos) - NS + WE) |
| | 164 | #define SE(pos) ((pos) + NS + WE) |
| 158 | 165 | #define SS(pos) ((pos) + 2 * NS) |
| 159 | | #define WW(pos) ((pos) - 2) |
| | 166 | #define WW(pos) ((pos) - 2 * WE) |
| 160 | 167 | #define NN(pos) ((pos) - 2 * NS) |
| 161 | | #define EE(pos) ((pos) + 2) |
| | 168 | #define EE(pos) ((pos) + 2 * WE) |
| 162 | 169 | |
| 163 | 170 | #define DIRECT_NEIGHBORS(pos1, pos2) \ |
| 164 | 171 | ((pos1) == SOUTH(pos2) \ |
| … |
… |
|
| 260 | 267 | /* Functions handling the permanent board state. */ |
| 261 | 268 | void clear_board(void); |
| 262 | 269 | int test_gray_border(void); |
| 263 | | void setup_board(Intersection new_board[MAX_BOARD][MAX_BOARD], int ko_pos, |
| 264 | | int *last, float new_komi, int w_captured, int b_captured); |
| 265 | 270 | void add_stone(int pos, int color); |
| 266 | 271 | void remove_stone(int pos); |
| 267 | 272 | void play_move(int pos, int color); |
| … |
… |
|
| 271 | 276 | void restore_board(struct board_state *state); |
| 272 | 277 | |
| 273 | 278 | /* Information about the permanent board. */ |
| 274 | | int get_last_move(void); |
| 275 | | int get_last_player(void); |
| | 279 | inline int get_last_move(void); |
| | 280 | inline int get_last_player(void); |
| 276 | 281 | int get_last_opponent_move(int color); |
| 277 | 282 | int stones_on_board(int color); |
| 278 | 283 | |
| 279 | 284 | /* Functions handling the variable board state. */ |
| 280 | | int trymove(int pos, int color, const char *message, int str); |
| | 285 | int trymove(int pos, int color, const char *message, int str_pos); |
| 281 | 286 | int tryko(int pos, int color, const char *message); |
| 282 | 287 | void popgo(void); |
| 283 | 288 | int komaster_trymove(int pos, int color, |
| 284 | 289 | const char *message, int str, |
| 285 | 290 | int *is_conditional_ko, int consider_conditional_ko); |
| 286 | | int get_komaster(void); |
| 287 | | int get_kom_pos(void); |
| | 291 | inline int get_komaster(void); |
| | 292 | inline int get_kom_pos(void); |
| 288 | 293 | |
| 289 | 294 | int move_in_stack(int pos, int cutoff); |
| 290 | | void get_move_from_stack(int k, int *move, int *color); |
| | 295 | inline void get_move_from_stack(int k, int *move, int *color); |
| 291 | 296 | void dump_stack(void); |
| 292 | 297 | void do_dump_stack(void); |
| 293 | 298 | |
| 294 | | void reset_trymove_counter(void); |
| 295 | | int get_trymove_counter(void); |
| | 299 | void dump_incremental_board(void); |
| | 300 | |
| | 301 | inline void reset_trymove_counter(void); |
| | 302 | inline int get_trymove_counter(void); |
| 296 | 303 | |
| 297 | 304 | /* move properties */ |
| 298 | | int is_pass(int pos); |
| | 305 | inline int is_pass(int pos); |
| 299 | 306 | int is_legal(int pos, int color); |
| 300 | 307 | int is_suicide(int pos, int color); |
| 301 | | int is_illegal_ko_capture(int pos, int color); |
| | 308 | inline int is_illegal_ko_capture(int pos, int color); |
| 302 | 309 | int is_allowed_move(int pos, int color); |
| 303 | 310 | int is_ko(int pos, int color, int *ko_pos); |
| 304 | 311 | int is_ko_point(int pos); |
| … |
… |
|
| 306 | 313 | int is_self_atari(int pos, int color); |
| 307 | 314 | |
| 308 | 315 | /* Purely gemoetric functions */ |
| 309 | | int is_edge_vertex(int pos); |
| 310 | | int is_corner_vertex(int pos); |
| 311 | | int edge_distance(int pos); |
| 312 | | int square_dist(int pos1, int pos2); |
| | 316 | inline int is_edge_vertex(int pos); |
| | 317 | inline int is_corner_vertex(int pos); |
| | 318 | inline int edge_distance(int pos); |
| | 319 | inline int square_dist(int pos1, int pos2); |
| 313 | 320 | |
| 314 | 321 | /* Basic string information. */ |
| 315 | | int find_origin(int str); |
| 316 | | int chainlinks(int str, int adj[MAXCHAIN]); |
| 317 | | int chainlinks2(int str, int adj[MAXCHAIN], int lib); |
| 318 | | int chainlinks3(int str, int adj[MAXCHAIN], int lib); |
| 319 | | int extended_chainlinks(int str, int adj[MAXCHAIN], int both_colors); |
| 320 | | |
| 321 | | int liberty_of_string(int pos, int str); |
| 322 | | int second_order_liberty_of_string(int pos, int str); |
| 323 | | int neighbor_of_string(int pos, int str); |
| 324 | | int has_neighbor(int pos, int color); |
| 325 | | int same_string(int str1, int str2); |
| 326 | | int adjacent_strings(int str1, int str2); |
| | 322 | inline int find_origin(int str_pos); |
| | 323 | int chainlinks(int str_pos, int adj[MAXCHAIN]); |
| | 324 | int chainlinks2(int str_pos, int adj[MAXCHAIN], int lib); |
| | 325 | int chainlinks3(int str_pos, int adj[MAXCHAIN], int lib); |
| | 326 | int extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors); |
| | 327 | |
| | 328 | int liberty_of_string(int pos, int str_pos); |
| | 329 | int liberty_of_string2(int pos, int str_pos); |
| | 330 | int second_order_liberty_of_string(int pos, int str_pos); |
| | 331 | int neighbor_of_string(int pos, int str_pos); |
| | 332 | inline int has_neighbor(int pos, int color); |
| | 333 | inline int same_string(int str1_pos, int str2_pos); |
| | 334 | int adjacent_strings(int str1_pos, int str2_pos); |
| 327 | 335 | void mark_string(int str, signed char mx[BOARDMAX], signed char mark); |
| 328 | 336 | int are_neighbors(int pos1, int pos2); |
| 329 | 337 | |
| 330 | | /* Count and/or find liberties at (pos). */ |
| 331 | | int countlib(int str); |
| 332 | | int findlib(int str, int maxlib, int *libs); |
| | 338 | /* Count and/or find liberties at (pos) */ |
| | 339 | inline int countlib(int str_pos); |
| | 340 | int findlib(int str_pos, int maxlib, int *libs); |
| 333 | 341 | int fastlib(int pos, int color, int ignore_captures); |
| 334 | 342 | int approxlib(int pos, int color, int maxlib, int *libs); |
| 335 | 343 | int accuratelib(int pos, int color, int maxlib, int *libs); |
| 336 | | int count_common_libs(int str1, int str2); |
| 337 | | int find_common_libs(int str1, int str2, int maxlib, int *libs); |
| 338 | | int have_common_lib(int str1, int str2, int *lib); |
| | 344 | int count_common_libs(int str1_pos, int str2_pos); |
| | 345 | int find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs); |
| | 346 | int have_common_lib(int str1_pos, int str2_pos, int *lib); |
| 339 | 347 | |
| 340 | 348 | /* Count the number of stones in a string. */ |
| 341 | | int countstones(int str); |
| 342 | | int findstones(int str, int maxstones, int *stones); |
| 343 | | int count_adjacent_stones(int str1, int str2, int maxstones); |
| | 349 | inline int countstones(int str_pos); |
| | 350 | int findstones(int str_pos, int maxstones, int *stones); |
| | 351 | int count_adjacent_stones(int str1_pos, int str2_pos, int maxstones); |
| 344 | 352 | |
| 345 | 353 | /* Special function for reading.c */ |
| 346 | | void incremental_order_moves(int move, int color, int string, |
| | 354 | void incremental_order_moves(int move, int color, int target_pos, |
| 347 | 355 | int *number_edges, int *number_same_string, |
| 348 | 356 | int *number_own, int *number_opponent, |
| 349 | 357 | int *captured_stones, int *threatened_stones, |
| 350 | 358 | int *saved_stones, int *number_open); |
| 351 | 359 | |
| 352 | 360 | /* Board caches initialization functions. */ |
| 353 | | void clear_approxlib_cache(void); |
| 354 | | void clear_accuratelib_cache(void); |
| | 361 | inline void clear_approxlib_cache(void); |
| | 362 | inline void clear_accuratelib_cache(void); |
| 355 | 363 | |
| 356 | 364 | |
| 357 | 365 | /* Is this point inside the board? */ |
| … |
… |
|
| 381 | 389 | * south, west, north, east, southwest, northwest, northeast, southeast. |
| 382 | 390 | * Defined in board.c. |
| 383 | 391 | */ |
| 384 | | extern int deltai[8]; /* = { 1, 0, -1, 0, 1, -1, -1, 1}; */ |
| 385 | | extern int deltaj[8]; /* = { 0, -1, 0, 1, -1, -1, 1, 1}; */ |
| 386 | | extern int delta[8]; /* = { NS, -1, -NS, 1, NS-1, -NS-1, -NS+1, NS+1}; */ |
| | 392 | extern const int deltai[8]; /* = { 1, 0, -1, 0, 1, -1, -1, 1}; */ |
| | 393 | extern const int deltaj[8]; /* = { 0, -1, 0, 1, -1, -1, 1, 1}; */ |
| | 394 | extern const int delta[8]; /* = { NS, -WE, -NS, WE, NS-WE, -NS-WE, -NS+WE, NS+WE}; */ |
| 387 | 395 | |
| 388 | 396 | |
| 389 | 397 | |
-
RCS file: /sources/gnugo/gnugo/engine/boardlib.c,v
retrieving revision 1.12
diff -u -r1.12 boardlib.c
|
|
|
|
| 29 | 29 | /* The board state itself. */ |
| 30 | 30 | int board_size = DEFAULT_BOARD_SIZE; /* board size */ |
| 31 | 31 | Intersection board[BOARDSIZE]; |
| 32 | | int board_ko_pos; |
| | 32 | int board_ko_pos; /* Position of a ko (captured stone). */ |
| 33 | 33 | int white_captured; /* number of black and white stones captured */ |
| 34 | 34 | int black_captured; |
| 35 | 35 | |
| … |
… |
|
| 54 | 54 | /* Hashing of positions. */ |
| 55 | 55 | Hash_data board_hash; |
| 56 | 56 | |
| 57 | | int stackp; /* stack pointer */ |
| | 57 | int stackp; /* moves stack depth */ |
| 58 | 58 | int position_number; /* position number */ |
| 59 | 59 | |
| 60 | 60 | /* Some statistics gathered partly in board.c and hash.c */ |
-
RCS file: /sources/gnugo/gnugo/engine/breakin.c,v
retrieving revision 1.26
diff -u -r1.26 breakin.c
|
|
|
|
| 367 | 367 | |
| 368 | 368 | if (used[pos2]) |
| 369 | 369 | break; |
| 370 | | } |
| | 370 | } |
| 371 | 371 | |
| 372 | 372 | used[pos] = 1; |
| 373 | 373 | if (ON_BOARD(pos2)) |
| … |
… |
|
| 440 | 440 | } |
| 441 | 441 | } |
| 442 | 442 | |
| 443 | | void |
| | 443 | inline void |
| 444 | 444 | clear_break_in_list() |
| 445 | 445 | { |
| 446 | 446 | num_break_ins = 0; |
-
RCS file: /sources/gnugo/gnugo/engine/cache.c,v
retrieving revision 1.50
diff -u -r1.50 cache.c
|
|
|
|
| 39 | 39 | /* ---------------------------------------------------------------- */ |
| 40 | 40 | |
| 41 | 41 | static void tt_init(Transposition_table *table, int memsize); |
| 42 | | static void tt_clear(Transposition_table *table); |
| | 42 | inline static void tt_clear(Transposition_table *table); |
| 43 | 43 | |
| 44 | 44 | /* The transposition table itself. */ |
| 45 | 45 | Transposition_table ttable; |
| … |
… |
|
| 72 | 72 | calculate_hashval_for_tt(Hash_data *hashdata, int routine, int target1, |
| 73 | 73 | int target2, Hash_data *extra_hash) |
| 74 | 74 | { |
| 75 | | *hashdata = board_hash; /* from globals.c */ |
| | 75 | *hashdata = board_hash; /* from boardlib.c */ |
| 76 | 76 | hashdata_xor(*hashdata, routine_hash[routine]); |
| 77 | 77 | hashdata_xor(*hashdata, target1_hash[target1]); |
| 78 | 78 | if (target2 != NO_MOVE) |
| … |
… |
|
| 97 | 97 | keyhash_init(); |
| 98 | 98 | |
| 99 | 99 | if (memsize > 0) |
| 100 | | num_entries = memsize / sizeof(table->entries[0]); |
| | 100 | num_entries = memsize / sizeof(Hashentry); |
| 101 | 101 | else |
| 102 | 102 | num_entries = DEFAULT_NUMBER_OF_CACHE_ENTRIES; |
| 103 | 103 | |
| 104 | 104 | table->num_entries = num_entries; |
| 105 | | table->entries = malloc(num_entries * sizeof(table->entries[0])); |
| | 105 | table->entries = malloc(num_entries * sizeof(Hashentry)); |
| 106 | 106 | |
| 107 | 107 | if (table->entries == NULL) { |
| 108 | 108 | perror("Couldn't allocate memory for transposition table. \n"); |
| 109 | 109 | exit(1); |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | | table->is_clean = 0; |
| 113 | 112 | tt_clear(table); |
| 114 | 113 | } |
| 115 | 114 | |
| 116 | 115 | |
| 117 | 116 | /* Clear the transposition table. */ |
| 118 | 117 | |
| 119 | | static void |
| | 118 | inline static void |
| 120 | 119 | tt_clear(Transposition_table *table) |
| 121 | 120 | { |
| 122 | | if (!table->is_clean) { |
| 123 | | memset(table->entries, 0, table->num_entries * sizeof(table->entries[0])); |
| 124 | | table->is_clean = 1; |
| 125 | | } |
| | 121 | memset(table->entries, 0, table->num_entries * sizeof(Hashentry)); |
| 126 | 122 | } |
| 127 | | |
| 128 | | |
| | 123 | |
| | 124 | |
| 129 | 125 | /* Free the transposition table. */ |
| 130 | 126 | |
| 131 | | void |
| | 127 | inline void |
| 132 | 128 | tt_free(Transposition_table *table) |
| 133 | 129 | { |
| 134 | 130 | free(table->entries); |
| 135 | 131 | } |
| 136 | 132 | |
| 137 | 133 | |
| 138 | | /* Get result and move. Return value: |
| | 134 | /* Get result and move (the bigger remaining depth the lower depth). |
| | 135 | * Return value: |
| 139 | 136 | * 0 if not found |
| 140 | | * 1 if found, but depth too small to be trusted. In this case the move |
| | 137 | * 1 if found, but depth too big to be trusted. In this case the move |
| 141 | 138 | * can be used for move ordering. |
| 142 | | * 2 if found and depth is enough so that the result can be trusted. |
| | 139 | * 2 if found and depth is small enough so that the result can be trusted. |
| 143 | 140 | */ |
| 144 | 141 | |
| 145 | 142 | int |
| … |
… |
|
| 162 | 159 | |
| 163 | 160 | /* Get the correct entry and node. */ |
| 164 | 161 | entry = &table->entries[hashdata_remainder(hashval, table->num_entries)]; |
| 165 | | if (hashdata_is_equal(hashval, entry->deepest.key)) |
| 166 | | node = &entry->deepest; |
| | 162 | |
| | 163 | if (hashdata_is_equal(hashval, entry->most_reliable.key)) |
| | 164 | node = &entry->most_reliable; |
| 167 | 165 | else if (hashdata_is_equal(hashval, entry->newest.key)) |
| 168 | 166 | node = &entry->newest; |
| 169 | 167 | else |
| 170 | 168 | return 0; |
| 171 | 169 | |
| 172 | | stats.read_result_hits++; |
| | 170 | #ifndef GG_TURN_OFF_STATS |
| | 171 | ++stats.read_result_hits; |
| | 172 | #endif |
| 173 | 173 | |
| 174 | 174 | /* Return data. Only set the result if remaining depth in the table |
| 175 | 175 | * is big enough to be trusted. The move can always be used for move |
| … |
… |
|
| 177 | 177 | */ |
| 178 | 178 | if (move) |
| 179 | 179 | *move = hn_get_move(node->data); |
| | 180 | |
| 180 | 181 | if (remaining_depth <= (int) hn_get_remaining_depth(node->data)) { |
| 181 | 182 | if (value1) |
| 182 | 183 | *value1 = hn_get_value1(node->data); |
| 183 | 184 | if (value2) |
| 184 | 185 | *value2 = hn_get_value2(node->data); |
| 185 | | stats.trusted_read_result_hits++; |
| | 186 | |
| | 187 | #ifndef GG_TURN_OFF_STATS |
| | 188 | ++stats.trusted_read_result_hits; |
| | 189 | #endif |
| | 190 | |
| 186 | 191 | return 2; |
| 187 | 192 | } |
| 188 | 193 | |
| … |
… |
|
| 201 | 206 | { |
| 202 | 207 | Hash_data hashval; |
| 203 | 208 | Hashentry *entry; |
| 204 | | Hashnode *deepest; |
| | 209 | Hashnode *most_reliable; |
| 205 | 210 | Hashnode *newest; |
| 206 | 211 | unsigned int data; |
| 207 | 212 | /* Get routine costs definitions from liberty.h. */ |
| … |
… |
|
| 220 | 225 | |
| 221 | 226 | /* Get the entry and nodes. */ |
| 222 | 227 | entry = &table->entries[hashdata_remainder(hashval, table->num_entries)]; |
| 223 | | deepest = &entry->deepest; |
| | 228 | most_reliable = &entry->most_reliable; |
| 224 | 229 | newest = &entry->newest; |
| 225 | 230 | |
| 226 | 231 | /* See if we found an already existing node. */ |
| 227 | | if (hashdata_is_equal(hashval, deepest->key) |
| 228 | | && remaining_depth >= (int) hn_get_remaining_depth(deepest->data)) { |
| 229 | | |
| 230 | | /* Found deepest */ |
| 231 | | deepest->data = data; |
| 232 | | |
| | 232 | if (hashdata_is_equal(hashval, most_reliable->key)) |
| | 233 | { |
| | 234 | /* Found shallower node (can be trusted more likely) */ |
| | 235 | if (remaining_depth > (int) hn_get_remaining_depth(most_reliable->data)) |
| | 236 | most_reliable->data = data; |
| 233 | 237 | } |
| 234 | | else if (hashdata_is_equal(hashval, newest->key) |
| 235 | | && remaining_depth >= (int) hn_get_remaining_depth(newest->data)) { |
| 236 | | |
| | 238 | else if (hashdata_is_equal(hashval, newest->key)) |
| | 239 | { |
| 237 | 240 | /* Found newest */ |
| 238 | | newest->data = data; |
| 239 | | |
| 240 | | /* If newest has become deeper than deepest, then switch them. */ |
| 241 | | if (hn_get_remaining_depth(newest->data) |
| 242 | | > hn_get_remaining_depth(deepest->data)) { |
| 243 | | Hashnode temp; |
| 244 | | |
| 245 | | temp = *deepest; |
| 246 | | *deepest = *newest; |
| 247 | | *newest = temp; |
| | 241 | if (remaining_depth > (int) hn_get_remaining_depth(newest->data)) |
| | 242 | { |
| | 243 | newest->data = data; |
| | 244 | |
| | 245 | /* If newest reliability is bigger than most_reliable, switch them. */ |
| | 246 | if (hn_get_reliability(newest->data) > |
| | 247 | hn_get_reliability(most_reliable->data)) |
| | 248 | { |
| | 249 | Hashnode temp; |
| | 250 | |
| | 251 | temp = *most_reliable; |
| | 252 | *most_reliable = *newest; |
| | 253 | *newest = temp; |
| | 254 | } |
| 248 | 255 | } |
| 249 | | |
| 250 | 256 | } |
| 251 | | else if (hn_get_total_cost(data) > hn_get_total_cost(deepest->data)) { |
| 252 | | if (hn_get_total_cost(newest->data) < hn_get_total_cost(deepest->data)) |
| 253 | | *newest = *deepest; |
| 254 | | deepest->key = hashval; |
| 255 | | deepest->data = data; |
| 256 | | } |
| 257 | | else { |
| | 257 | /* Have new node. */ |
| | 258 | else if (hn_get_reliability(data) > |
| | 259 | hn_get_reliability(most_reliable->data)) |
| | 260 | { |
| | 261 | /* Replace most_reliable. */ |
| | 262 | most_reliable->key = hashval; |
| | 263 | most_reliable->data = data; |
| | 264 | } |
| | 265 | else |
| | 266 | { |
| 258 | 267 | /* Replace newest. */ |
| 259 | 268 | newest->key = hashval; |
| 260 | 269 | newest->data = data; |
| 261 | 270 | } |
| 262 | 271 | |
| 263 | | stats.read_result_entered++; |
| 264 | | table->is_clean = 0; |
| | 272 | #ifndef GG_TURN_OFF_STATS |
| | 273 | ++stats.read_result_entered; |
| | 274 | #endif |
| 265 | 275 | } |
| 266 | 276 | |
| 267 | 277 | |
| … |
… |
|
| 270 | 280 | }; |
| 271 | 281 | |
| 272 | 282 | /* Convert a routine as used in the cache table to a string. */ |
| 273 | | const char * |
| | 283 | inline const char * |
| 274 | 284 | routine_id_to_string(enum routine_id routine) |
| 275 | 285 | { |
| 276 | 286 | return routine_names[(int) routine]; |
| … |
… |
|
| 282 | 292 | * allocate a single node or if the allocation fails, the caching is |
| 283 | 293 | * disabled. |
| 284 | 294 | */ |
| 285 | | void |
| | 295 | inline void |
| 286 | 296 | reading_cache_init(int bytes) |
| 287 | 297 | { |
| 288 | 298 | tt_init(&ttable, bytes); |
| … |
… |
|
| 290 | 300 | |
| 291 | 301 | |
| 292 | 302 | /* Clear the cache for read results. */ |
| 293 | | void |
| | 303 | inline void |
| 294 | 304 | reading_cache_clear() |
| 295 | 305 | { |
| 296 | 306 | tt_clear(&ttable); |
| 297 | 307 | } |
| 298 | 308 | |
| 299 | | float |
| | 309 | inline float |
| 300 | 310 | reading_cache_default_size() |
| 301 | 311 | { |
| 302 | 312 | return DEFAULT_NUMBER_OF_CACHE_ENTRIES * sizeof(Hashentry) / 1024.0 / 1024.0; |
-
RCS file: /sources/gnugo/gnugo/engine/cache.h,v
retrieving revision 1.54
diff -u -r1.54 cache.h
|
|
|
|
| 32 | 32 | * (Reading/Hashing) for more information. |
| 33 | 33 | */ |
| 34 | 34 | |
| | 35 | #if SIZEOF_INT == 4 |
| | 36 | typedef unsigned int HASHNODE_DATATYPE; |
| | 37 | #elif SIZEOF_LONG == 4 |
| | 38 | typedef unsigned long HASHNODE_DATATYPE; |
| | 39 | #elif SIZEOF_INT > 4 |
| | 40 | typedef unsigned short HASHNODE_DATATYPE; |
| | 41 | #elif |
| | 42 | #error Long type size has to be at least 4 bytes. |
| | 43 | #endif |
| 35 | 44 | |
| 36 | 45 | /* Hashnode: a node stored in the transposition table. |
| 37 | 46 | * |
| 38 | 47 | * In addition to the position, the hash lock encodes the following data, |
| 39 | 48 | * all hashed: |
| 40 | | * komaster |
| 41 | | * kom_pos |
| | 49 | * ko |
| | 50 | * komaster (look in doc) |
| | 51 | * kom_pos (look in doc) |
| 42 | 52 | * routine |
| 43 | | * str1 |
| 44 | | * str2 |
| | 53 | * target1 |
| | 54 | * target2 |
| 45 | 55 | * extra hashvalue, optional (e.g. encoding a goal array) |
| 46 | 56 | * |
| 47 | 57 | * The data field packs into 32 bits the following |
| … |
… |
|
| 54 | 64 | * cost : 4 bits |
| 55 | 65 | * remaining_depth: 5 bits (depth - stackp) NOTE: HN_MAX_REMAINING_DEPTH |
| 56 | 66 | * |
| 57 | | * The last 9 bits together give an index for the total costs. |
| | 67 | * The last 9 bits together give a reliability index (bigger index means |
| | 68 | * more reliable result). |
| | 69 | * Values are results of analyzed position (WIN, LOSE, etc.) |
| 58 | 70 | */ |
| 59 | 71 | typedef struct { |
| 60 | 72 | Hash_data key; |
| 61 | | unsigned int data; /* Should be 32 bits, but only wastes 25% if 64 bits. */ |
| | 73 | HASHNODE_DATATYPE data; /* 32-bit value */ |
| 62 | 74 | } Hashnode; |
| 63 | 75 | |
| 64 | 76 | #define HN_MAX_REMAINING_DEPTH 31 |
| … |
… |
|
| 67 | 79 | /* Hashentry: an entry, with two nodes of the hash_table |
| 68 | 80 | */ |
| 69 | 81 | typedef struct { |
| 70 | | Hashnode deepest; |
| | 82 | Hashnode most_reliable; |
| 71 | 83 | Hashnode newest; |
| 72 | 84 | } Hashentry; |
| 73 | 85 | |
| … |
… |
|
| 76 | 88 | #define hn_get_value2(hn) ((hn >> 19) & 0x0f) |
| 77 | 89 | #define hn_get_move(hn) ((hn >> 9) & 0x3ff) |
| 78 | 90 | #define hn_get_cost(hn) ((hn >> 5) & 0x0f) |
| 79 | | #define hn_get_remaining_depth(hn) ((hn >> 0) & 0x1f) |
| 80 | | #define hn_get_total_cost(hn) ((hn >> 0) & 0x1ff) |
| | 91 | #define hn_get_remaining_depth(hn) ((hn/*>> 0*/) & 0x1f) |
| | 92 | #define hn_get_reliability(hn) ((hn/*>> 0*/) & 0x1ff) |
| 81 | 93 | |
| 82 | 94 | #define hn_create_data(remaining_depth, value1, value2, move, cost) \ |
| 83 | 95 | ((((value1) & 0x0f) << 23) \ |
| 84 | 96 | | (((value2) & 0x0f) << 19) \ |
| 85 | 97 | | (((move) & 0x3ff) << 9) \ |
| 86 | 98 | | (((cost) & 0x0f) << 5) \ |
| 87 | | | (((remaining_depth & 0x1f) << 0))) |
| | 99 | | (((remaining_depth & 0x1f)/*<< 0*/))) |
| 88 | 100 | |
| 89 | 101 | |
| 90 | 102 | /* Transposition_table: transposition table used for caching. */ |
| 91 | 103 | typedef struct { |
| 92 | 104 | unsigned int num_entries; |
| 93 | 105 | Hashentry *entries; |
| 94 | | int is_clean; |
| 95 | 106 | } Transposition_table; |
| 96 | 107 | |
| 97 | 108 | extern Transposition_table ttable; |
| … |
… |
|
| 101 | 112 | */ |
| 102 | 113 | #define DEFAULT_NUMBER_OF_CACHE_ENTRIES 350000 |
| 103 | 114 | |
| 104 | | void tt_free(Transposition_table *table); |
| | 115 | inline void tt_free(Transposition_table *table); |
| 105 | 116 | int tt_get(Transposition_table *table, enum routine_id routine, |
| 106 | 117 | int target1, int target2, int remaining_depth, |
| 107 | 118 | Hash_data *extra_hash, |
| … |
… |
|
| 141 | 152 | int q1 = board[str1] == EMPTY ? str1 : find_origin(str1); \ |
| 142 | 153 | int q2 = board[str2] == EMPTY ? str2 : find_origin(str2); |
| 143 | 154 | |
| | 155 | #define READ_FUNCTION_NAME read_function_name |
| | 156 | |
| 144 | 157 | #else |
| 145 | 158 | |
| 146 | 159 | #define TRACE_CACHED_RESULT(result, move) |
| 147 | 160 | #define TRACE_CACHED_RESULT2(result1, result2, move) |
| 148 | 161 | |
| | 162 | #ifndef GG_TURN_OFF_TRACES |
| | 163 | |
| 149 | 164 | #define SETUP_TRACE_INFO(name, str) \ |
| 150 | 165 | const char *read_function_name = name; \ |
| 151 | 166 | int q = str; |
| … |
… |
|
| 155 | 170 | int q1 = str1; \ |
| 156 | 171 | int q2 = str2; |
| 157 | 172 | |
| 158 | | #endif |
| 159 | | |
| 160 | | /* Trace messages in decidestring/decidedragon sgf file. */ |
| 161 | | void sgf_trace(const char *func, int str, int move, int result, |
| 162 | | const char *message); |
| 163 | | /* Trace messages in decideconnection sgf file. */ |
| 164 | | void sgf_trace2(const char *func, int str1, int str2, int move, |
| 165 | | const char *result, const char *message); |
| 166 | | /* Trace messages in decidesemeai sgf file. */ |
| 167 | | void sgf_trace_semeai(const char *func, int str1, int str2, int move, |
| 168 | | int result1, int result2, const char *message); |
| 169 | | |
| 170 | 173 | /* Macro to hide the call to sgf_trace(). Notice that a little black |
| 171 | 174 | * magic is going on here. Before using this macro, SETUP_TRACE_INFO |
| 172 | 175 | * must have been called to provide the variables read_function_name |
| … |
… |
|
| 190 | 193 | sgf_trace_semeai(read_function_name, q1, q2, move, \ |
| 191 | 194 | result1, result2, message) |
| 192 | 195 | |
| | 196 | #define READ_FUNCTION_NAME read_function_name |
| | 197 | |
| | 198 | #else // #ifndef GG_TURN_OFF_TRACES |
| | 199 | |
| | 200 | #define SETUP_TRACE_INFO(name, str) |
| | 201 | #define SETUP_TRACE_INFO2(name, str1, str2) |
| | 202 | #define SGFTRACE(move, result, message) (void)0 |
| | 203 | #define SGFTRACE2(move, result, message) (void)0 |
| | 204 | #define SGFTRACE_SEMEAI(move, result1, result2, message) (void)0 |
| | 205 | #define READ_FUNCTION_NAME NULL |
| | 206 | |
| | 207 | #endif // #ifndef GG_TURN_OFF_TRACES |
| | 208 | |
| | 209 | #endif // #if TRACE_READ_RESULTS |
| | 210 | |
| | 211 | /* Trace messages in decidestring/decidedragon sgf file. */ |
| | 212 | void sgf_trace(const char *func, int str, int move, int result, |
| | 213 | const char *message); |
| | 214 | /* Trace messages in decideconnection sgf file. */ |
| | 215 | void sgf_trace2(const char *func, int str1, int str2, int move, |
| | 216 | const char *result, const char *message); |
| | 217 | /* Trace messages in decidesemeai sgf file. */ |
| | 218 | void sgf_trace_semeai(const char *func, int str1, int str2, int move, |
| | 219 | int result1, int result2, const char *message); |
| | 220 | |
| 193 | 221 | |
| 194 | 222 | /* ================================================================ */ |
| 195 | 223 | |
| … |
… |
|
| 212 | 240 | do { \ |
| 213 | 241 | tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ |
| 214 | 242 | value, 0, move);\ |
| 215 | | if ((value) != 0 && (point) != 0) *(point) = (move); \ |
| | 243 | if ((point) != NULL && (value) != 0) \ |
| | 244 | *(point) = (move); \ |
| 216 | 245 | return (value); \ |
| 217 | 246 | } while (0) |
| 218 | 247 | |
| … |
… |
|
| 220 | 249 | do { \ |
| 221 | 250 | tt_update(&ttable, routine, str1, str2, remaining_depth, NULL, \ |
| 222 | 251 | value1, value2, move); \ |
| 223 | | if ((value1) != 0 && (point) != 0) *(point) = (move); \ |
| | 252 | if ((point) != NULL && (value1) != 0) \ |
| | 253 | *(point) = (move); \ |
| 224 | 254 | return; \ |
| 225 | 255 | } while (0) |
| 226 | 256 | |
| … |
… |
|
| 228 | 258 | do { \ |
| 229 | 259 | tt_update(&ttable, routine, str1, str2, remaining_depth, NULL,\ |
| 230 | 260 | value, 0, move);\ |
| 231 | | if ((value) != 0 && (point) != 0) *(point) = (move); \ |
| | 261 | if ((point) != NULL && (value) != 0) \ |
| | 262 | *(point) = (move); \ |
| 232 | 263 | return (value); \ |
| 233 | 264 | } while (0) |
| 234 | 265 | |
| … |
… |
|
| 236 | 267 | do { \ |
| 237 | 268 | tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, hash,\ |
| 238 | 269 | value, 0, move);\ |
| 239 | | if ((value) != 0 && (point) != 0) *(point) = (move); \ |
| | 270 | if ((point) != NULL && (value) != 0) \ |
| | 271 | *(point) = (move); \ |
| 240 | 272 | return (value); \ |
| 241 | 273 | } while (0) |
| 242 | 274 | |
| … |
… |
|
| 244 | 276 | do { \ |
| 245 | 277 | tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ |
| 246 | 278 | value1, value2, move);\ |
| 247 | | if ((value1) != 0 && (point) != 0) *(point) = (move); \ |
| | 279 | if ((point) != NULL && (value1) != 0) \ |
| | 280 | *(point) = (move); \ |
| 248 | 281 | return (value1); \ |
| 249 | 282 | } while (0) |
| 250 | 283 | |
-
RCS file: /sources/gnugo/gnugo/engine/clock.c,v
retrieving revision 1.26
diff -u -r1.26 clock.c
|
|
|
|
| 38 | 38 | #include "clock.h" |
| 39 | 39 | #include "gg_utils.h" |
| 40 | 40 | #include "board.h" |
| | 41 | #include "gnugo.h" |
| 41 | 42 | |
| 42 | 43 | /* Level data */ |
| 43 | 44 | static int level = DEFAULT_LEVEL; /* current level */ |
| … |
… |
|
| 68 | 69 | }; |
| 69 | 70 | |
| 70 | 71 | struct timer_data { |
| 71 | | struct remaining_time_data official; |
| 72 | | struct remaining_time_data estimated; |
| | 72 | struct remaining_time_data official; // time received from external source |
| | 73 | struct remaining_time_data estimated; // time counted by GnuGO |
| 73 | 74 | int time_out; |
| 74 | 75 | }; |
| 75 | 76 | |
| … |
… |
|
| 127 | 128 | * |
| 128 | 129 | * byo_time > 0 and byo_stones == 0 means no time settings. |
| 129 | 130 | */ |
| 130 | | void |
| | 131 | inline void |
| 131 | 132 | clock_settings(int time, int byo_time, int byo_stones) |
| 132 | 133 | { |
| 133 | 134 | if (time >= 0) |
| … |
… |
|
| 142 | 143 | /* Get time settings. Returns 1 if any time settings have been made, |
| 143 | 144 | * 0 otherwise. |
| 144 | 145 | */ |
| 145 | | int |
| | 146 | inline int |
| 146 | 147 | have_time_settings(void) |
| 147 | 148 | { |
| 148 | 149 | /* According to the semantics of the GTP command 'time_settings', the |
| … |
… |
|
| 220 | 221 | static int last_movenum = -1; |
| 221 | 222 | struct timer_data* const td |
| 222 | 223 | = (color == BLACK) ? &black_time_data : &white_time_data; |
| 223 | | double now = gg_gettimeofday(); |
| | 224 | double now; |
| 224 | 225 | |
| 225 | 226 | if (!have_time_settings()) |
| 226 | 227 | return; |
| 227 | 228 | |
| | 229 | now = gg_gettimeofday(); |
| | 230 | |
| 228 | 231 | if (last_movenum >= 0 |
| 229 | | && movenum == last_movenum + 1 |
| 230 | | && movenum > td->estimated.movenum) { |
| | 232 | && movenum == last_movenum + 1) { |
| 231 | 233 | double time_used = now - last_time; |
| 232 | 234 | td->estimated.time_left -= time_used; |
| 233 | 235 | td->estimated.movenum = movenum; |
| 234 | 236 | td->estimated.time_for_last_move = time_used; |
| 235 | 237 | if (td->estimated.time_left < 0) { |
| 236 | 238 | if (td->estimated.in_byoyomi || byoyomi_stones == 0) { |
| | 239 | |
| | 240 | #ifndef GG_TURN_OFF_DEBUGS |
| 237 | 241 | DEBUG(DEBUG_TIME, "%s ran out of time.\n", color_to_string(color)); |
| 238 | 242 | if (debug & DEBUG_TIME) |
| 239 | 243 | clock_print(color); |
| | 244 | #endif |
| | 245 | |
| 240 | 246 | td->time_out = 1; |
| 241 | 247 | } |
| 242 | 248 | else { |
| … |
… |
|
| 251 | 257 | } |
| 252 | 258 | else if (td->estimated.stones > 0) { |
| 253 | 259 | gg_assert(td->estimated.in_byoyomi); |
| 254 | | td->estimated.stones = td->estimated.stones - 1; |
| | 260 | --td->estimated.stones; |
| 255 | 261 | if (td->estimated.stones == 0) { |
| 256 | 262 | td->estimated.time_left = byoyomi_time; |
| 257 | 263 | td->estimated.stones = byoyomi_stones; |
| … |
… |
|
| 262 | 268 | last_movenum = movenum; |
| 263 | 269 | last_time = now; |
| 264 | 270 | |
| | 271 | #ifndef GG_TURN_OFF_DEBUGS |
| 265 | 272 | /* Update main timer. */ |
| 266 | 273 | if (debug & DEBUG_TIME) |
| 267 | 274 | clock_print(color); |
| | 275 | #endif |
| 268 | 276 | } |
| 269 | 277 | |
| 270 | 278 | |
| … |
… |
|
| 297 | 305 | |
| 298 | 306 | if (timer->stones == 0) { |
| 299 | 307 | /* Main time running. */ |
| 300 | | *time_left = timer->time_left + byoyomi_time; |
| | 308 | *time_left = timer->time_left; |
| 301 | 309 | if (byoyomi_time > 0) |
| | 310 | { |
| | 311 | *time_left += byoyomi_time; |
| 302 | 312 | *stones_left = byoyomi_stones; |
| | 313 | } |
| 303 | 314 | else { |
| 304 | 315 | /* Absolute time. Here we aim to be able to play at least X more |
| 305 | 316 | * moves or a total of Y moves. We choose Y as a third of the |
| … |
… |
|
| 331 | 342 | adjust_level_offset(int color) |
| 332 | 343 | { |
| 333 | 344 | double time_for_last_move; |
| 334 | | double time_left; |
| | 345 | double time_left, estimated_time; |
| 335 | 346 | int stones_left; |
| 336 | 347 | |
| 337 | 348 | if (!analyze_time_data(color, &time_for_last_move, &time_left, &stones_left)) |
| … |
… |
|
| 342 | 353 | * |
| 343 | 354 | * FIXME: Use rules with at least some theoretical basis. |
| 344 | 355 | */ |
| 345 | | if (time_left < time_for_last_move * (stones_left + 3)) |
| 346 | | level_offset--; |
| 347 | | if (time_left < time_for_last_move * stones_left) |
| 348 | | level_offset--; |
| 349 | | if (3 * time_left < 2 * time_for_last_move * stones_left) |
| 350 | | level_offset--; |
| 351 | | if (2 * time_left < time_for_last_move * stones_left) |
| 352 | | level_offset--; |
| 353 | | if (3 * time_left < time_for_last_move * stones_left) |
| 354 | | level_offset--; |
| 355 | | |
| 356 | | if (time_for_last_move == 0) |
| 357 | | time_for_last_move = 1; |
| 358 | | if (time_left > time_for_last_move * (stones_left + 6)) |
| 359 | | level_offset++; |
| 360 | | if (time_left > 2 * time_for_last_move * (stones_left + 6)) |
| 361 | | level_offset++; |
| | 356 | if (time_for_last_move < 0.1) |
| | 357 | time_for_last_move = 0.1; |
| | 358 | |
| | 359 | estimated_time = time_for_last_move * stones_left; |
| | 360 | |
| | 361 | if (time_left < estimated_time) |
| | 362 | { |
| | 363 | --level_offset; |
| | 364 | |
| | 365 | if (1.33 * time_left < estimated_time) |
| | 366 | { |
| | 367 | --level_offset; |
| | 368 | |
| | 369 | if (2 * time_left < estimated_time) |
| | 370 | { |
| | 371 | level_offset -= 2; |
| | 372 | |
| | 373 | if (4 * time_left < estimated_time) |
| | 374 | level_offset -= 2; |
| | 375 | } |
| | 376 | } |
| | 377 | } |
| | 378 | else if (0.8 * time_left > estimated_time) |
| | 379 | { |
| | 380 | ++level_offset; |
| | 381 | |
| | 382 | if (0.5 * time_left > estimated_time) |
| | 383 | level_offset += 2; |
| | 384 | } |
| 362 | 385 | |
| 363 | 386 | if (level + level_offset < min_level) |
| 364 | 387 | level_offset = min_level - level; |
| 365 | | |
| 366 | | if (level + level_offset > max_level) |
| | 388 | else if (level + level_offset > max_level) |
| 367 | 389 | level_offset = max_level - level; |
| 368 | 390 | |
| 369 | 391 | DEBUG(DEBUG_TIME, "New level %d (%d %C %f %f %d)\n", level + level_offset, |
| … |
… |
|
| 375 | 397 | /* Interface to level settings. */ |
| 376 | 398 | /********************************/ |
| 377 | 399 | |
| 378 | | int |
| | 400 | inline int |
| 379 | 401 | get_level() |
| 380 | 402 | { |
| 381 | 403 | return level + level_offset; |
| 382 | 404 | } |
| 383 | 405 | |
| 384 | | void |
| | 406 | inline void |
| 385 | 407 | set_level(int new_level) |
| 386 | 408 | { |
| 387 | 409 | level = new_level; |
| … |
… |
|
| 392 | 414 | min_level = level; |
| 393 | 415 | } |
| 394 | 416 | |
| 395 | | void |
| | 417 | inline void |
| 396 | 418 | set_max_level(int new_max) |
| 397 | 419 | { |
| 398 | 420 | max_level = new_max; |
| 399 | 421 | } |
| 400 | 422 | |
| 401 | | void |
| | 423 | inline void |
| 402 | 424 | set_min_level(int new_min) |
| 403 | 425 | { |
| 404 | 426 | min_level = new_min; |
-
RCS file: /sources/gnugo/gnugo/engine/clock.h,v
retrieving revision 1.15
diff -u -r1.15 clock.h
|
|
|
|
| 26 | 26 | #include "gnugo.h" |
| 27 | 27 | |
| 28 | 28 | /* initialization and activation */ |
| 29 | | void clock_settings(int maintime, int byotime, int byostones); |
| | 29 | inline void clock_settings(int maintime, int byotime, int byostones); |
| 30 | 30 | void init_timers(void); |
| 31 | 31 | |
| 32 | 32 | /* main access */ |
| 33 | 33 | void clock_push_button(int color); |
| 34 | 34 | void update_time_left(int color, int time_left, int stones); |
| 35 | 35 | void clock_print(int color); |
| 36 | | int have_time_settings(void); |
| | 36 | inline int have_time_settings(void); |
| 37 | 37 | |
| 38 | 38 | void adjust_level_offset(int color); |
| 39 | 39 | |
| 40 | 40 | /* Access to level settings. */ |
| 41 | | int get_level(void); |
| 42 | | void set_level(int new_level); |
| 43 | | void set_max_level(int new_max); |
| 44 | | void set_min_level(int new_min); |
| | 41 | inline int get_level(void); |
| | 42 | inline void set_level(int new_level); |
| | 43 | inline void set_max_level(int new_max); |
| | 44 | inline void set_min_level(int new_min); |
| 45 | 45 | |
| 46 | 46 | |
| 47 | 47 | #endif /* _CLOCK_H_ */ |
-
RCS file: /sources/gnugo/gnugo/engine/combination.c,v
retrieving revision 1.57
diff -u -r1.57 combination.c
|
|
|
|
| 761 | 761 | if (num_libs == 2) |
| 762 | 762 | all_potential_defenses[libs[1]] = 1; |
| 763 | 763 | } |
| 764 | | } |
| | 764 | } |
| 765 | 765 | |
| 766 | 766 | if (!IS_STONE(board[str])) { |
| 767 | 767 | /* Error situation. This could be caused by a wrong matcher status. */ |
| … |
… |
|
| 889 | 889 | continue; |
| 890 | 890 | |
| 891 | 891 | if (board[last_friendly] == EMPTY |
| 892 | | && !liberty_of_string(last_friendly, pos)) |
| | 892 | && !liberty_of_string2(last_friendly, pos)) |
| 893 | 893 | continue; |
| 894 | 894 | |
| 895 | 895 | if (debug & DEBUG_ATARI_ATARI) |
| … |
… |
|
| 1054 | 1054 | |
| 1055 | 1055 | if (!safe_move(move, color)) |
| 1056 | 1056 | continue; |
| 1057 | | } |
| | 1057 | } |
| 1058 | 1058 | |
| 1059 | 1059 | /* |
| 1060 | 1060 | * Play (move) and see if there is an attack. |
-
RCS file: /sources/gnugo/gnugo/engine/dragon.c,v
retrieving revision 1.162
diff -u -r1.162 dragon.c
|
|
|
|
| 594 | 594 | propagate_worm(str); |
| 595 | 595 | } |
| 596 | 596 | } |
| 597 | | } |
| | 597 | } |
| 598 | 598 | |
| 599 | 599 | /* Revise essentiality of critical dragons. Specifically, a critical |
| 600 | 600 | * dragon consisting entirely of inessential worms is considered |
-
RCS file: /sources/gnugo/gnugo/engine/endgame.c,v
retrieving revision 1.13
diff -u -r1.13 endgame.c
|
|
|
|
| 461 | 461 | int liberties; |
| 462 | 462 | int libs[MAXLIBS]; |
| 463 | 463 | int k; |
| | 464 | int color = board[str]; |
| | 465 | int origin = find_origin(str); |
| 464 | 466 | |
| 465 | | ASSERT1(IS_STONE(board[str]), str); |
| | 467 | ASSERT1(IS_STONE(color), str); |
| 466 | 468 | |
| 467 | 469 | *essential_liberties = 0; |
| 468 | 470 | *inessential_liberties = 0; |
| … |
… |
|
| 494 | 496 | if (worm[pos].attack_codes[0] != 0 || dragon[pos].status != ALIVE) |
| 495 | 497 | return 0; |
| 496 | 498 | |
| 497 | | if (board[pos] == board[str]) { |
| 498 | | if (find_origin(pos) != find_origin(str)) |
| | 499 | if (board[pos] == color) { |
| | 500 | if (find_origin(pos) != origin) |
| 499 | 501 | essential = 1; |
| 500 | 502 | } |
| 501 | 503 | else |
-
RCS file: /sources/gnugo/gnugo/engine/filllib.c,v
retrieving revision 1.37
diff -u -r1.37 filllib.c
|
|
|
|
| 310 | 310 | DEBUG(DEBUG_FILLLIB, |
| 311 | 311 | "Filllib: Nothing found, looking for threat to back-capture.\n"); |
| 312 | 312 | for (k = 0; k < 4; k++) { |
| 313 | | int d = delta[k]; |
| 314 | | if (board[pos + d] == other |
| 315 | | && worm[pos + d].attack_codes[0] != 0) { |
| | 313 | int checked_pos = pos + delta[k]; |
| | 314 | if (board[checked_pos] == other |
| | 315 | && worm[checked_pos].attack_codes[0] != 0) { |
| 316 | 316 | /* Just pick some other liberty. */ |
| 317 | 317 | /* FIXME: Something is odd about this code. */ |
| 318 | 318 | int libs[2]; |
| 319 | | if (findlib(pos + d, 2, libs) > 1) { |
| | 319 | if (findlib(checked_pos, 2, libs) > 1) { |
| 320 | 320 | if (is_legal(libs[0], color)) |
| 321 | 321 | *move = libs[0]; |
| 322 | 322 | else if (is_legal(libs[1], color)) |
| … |
… |
|
| 394 | 394 | */ |
| 395 | 395 | acode = attack(move, &apos); |
| 396 | 396 | gg_assert(acode != 0 && apos != NO_MOVE); |
| 397 | | |
| | 397 | |
| 398 | 398 | /* Find liberties. */ |
| 399 | 399 | liberties = findlib(move, MAXLIBS, libs); |
| 400 | 400 | |
| … |
… |
|
| 435 | 435 | if (attack(adjs[k], &bpos) == WIN) { |
| 436 | 436 | if (forbidden_moves[bpos]) |
| 437 | 437 | continue; |
| 438 | | if (liberty_of_string(bpos, adjs[k])) { |
| | 438 | if (liberty_of_string2(bpos, adjs[k])) { |
| 439 | 439 | *backfill_move = bpos; |
| 440 | 440 | return 1; |
| 441 | 441 | } |
| … |
… |
|
| 464 | 464 | if (attack(adjs[k], &bpos) == WIN) { |
| 465 | 465 | if (forbidden_moves[bpos]) |
| 466 | 466 | continue; |
| 467 | | if (liberty_of_string(bpos, adjs[k])) { |
| | 467 | if (liberty_of_string2(bpos, adjs[k])) { |
| 468 | 468 | *backfill_move = bpos; |
| 469 | 469 | return 1; |
| 470 | 470 | } |
| … |
… |
|
| 496 | 496 | popgo(); |
| 497 | 497 | for (k = 0; k < neighbors; k++) { |
| 498 | 498 | if (attack(adjs[k], &bpos) == WIN) { |
| 499 | | if (!forbidden_moves[bpos] && liberty_of_string(bpos, adjs[k])) { |
| | 499 | if (!forbidden_moves[bpos] && liberty_of_string2(bpos, adjs[k])) { |
| 500 | 500 | *backfill_move = bpos; |
| 501 | 501 | return 1; |
| 502 | 502 | } |
-
RCS file: /sources/gnugo/gnugo/engine/genmove.c,v
retrieving revision 1.116
diff -u -r1.116 genmove.c
|
|
|
|
| 73 | 73 | void |
| 74 | 74 | reset_engine() |
| 75 | 75 | { |
| | 76 | static int last_level = -1; |
| | 77 | int act_level; |
| | 78 | |
| 76 | 79 | /* To improve the reproducability of games, we restart the random |
| 77 | 80 | * number generator with the same seed for each move. Thus we don't |
| 78 | 81 | * have to know how many previous moves have been played, nor |
| … |
… |
|
| 98 | 101 | clear_break_in_list(); |
| 99 | 102 | |
| 100 | 103 | /* Set up depth values (see comments there for details). */ |
| 101 | | set_depth_values(get_level(), 0); |
| | 104 | act_level = get_level(); |
| | 105 | if (last_level != act_level) |
| | 106 | { |
| | 107 | set_depth_values(act_level, 0); |
| | 108 | last_level = act_level; |
| | 109 | } |
| 102 | 110 | } |
| 103 | 111 | |
| 104 | 112 | /* |
| … |
… |
|
| 117 | 125 | void |
| 118 | 126 | examine_position(int how_much, int aftermath_play) |
| 119 | 127 | { |
| | 128 | #ifndef GG_TURN_OFF_TRACES |
| 120 | 129 | int save_verbose = verbose; |
| | 130 | #endif |
| 121 | 131 | |
| 122 | 132 | purge_persistent_caches(); |
| 123 | 133 | |
| | 134 | #ifndef GG_TURN_OFF_TRACES |
| 124 | 135 | /* Don't print reading traces during make_worms and make_dragons unless |
| 125 | 136 | * the user really wants it (verbose == 3). |
| 126 | 137 | */ |
| 127 | 138 | if (verbose == 1 || verbose == 2) |
| 128 | 139 | --verbose; |
| | 140 | #endif |
| 129 | 141 | |
| 130 | 142 | if (NEEDS_UPDATE(worms_examined)) { |
| | 143 | |
| | 144 | #ifndef GG_TURN_OFF_TRACES |
| 131 | 145 | start_timer(0); |
| | 146 | #endif |
| | 147 | |
| 132 | 148 | make_worms(); |
| | 149 | |
| | 150 | #ifndef GG_TURN_OFF_TRACES |
| 133 | 151 | time_report(0, " make worms", NO_MOVE, 1.0); |
| | 152 | #endif |
| 134 | 153 | } |
| 135 | 154 | |
| 136 | 155 | if (how_much == EXAMINE_WORMS) { |
| | 156 | |
| | 157 | #ifndef GG_TURN_OFF_TRACES |
| 137 | 158 | verbose = save_verbose; |
| | 159 | #endif |
| | 160 | |
| 138 | 161 | gg_assert(test_gray_border() < 0); |
| 139 | 162 | return; |
| 140 | 163 | } |
| … |
… |
|
| 142 | 165 | if (stones_on_board(BLACK | WHITE) != 0) { |
| 143 | 166 | if (NEEDS_UPDATE(initial_influence_examined)) |
| 144 | 167 | compute_worm_influence(); |
| | 168 | |
| 145 | 169 | if (how_much == EXAMINE_INITIAL_INFLUENCE) { |
| | 170 | |
| | 171 | #ifndef GG_TURN_OFF_TRACES |
| 146 | 172 | verbose = save_verbose; |
| | 173 | #endif |
| | 174 | |
| 147 | 175 | gg_assert(test_gray_border() < 0); |
| 148 | 176 | return; |
| 149 | 177 | } |
| … |
… |
|
| 151 | 179 | if (how_much == EXAMINE_DRAGONS_WITHOUT_OWL) { |
| 152 | 180 | if (NEEDS_UPDATE(dragons_examined_without_owl)) |
| 153 | 181 | make_dragons(1); |
| | 182 | |
| | 183 | #ifndef GG_TURN_OFF_TRACES |
| 154 | 184 | verbose = save_verbose; |
| | 185 | #endif |
| | 186 | |
| 155 | 187 | gg_assert(test_gray_border() < 0); |
| 156 | 188 | return; |
| 157 | 189 | } |
| … |
… |
|
| 163 | 195 | dragons_examined_without_owl = position_number; |
| 164 | 196 | } |
| 165 | 197 | if (how_much == EXAMINE_DRAGONS) { |
| | 198 | |
| | 199 | #ifndef GG_TURN_OFF_TRACES |
| 166 | 200 | verbose = save_verbose; |
| | 201 | #endif |
| | 202 | |
| 167 | 203 | gg_assert(test_gray_border() < 0); |
| 168 | 204 | return; |
| 169 | 205 | } |
| … |
… |
|
| 173 | 209 | || how_much == EXAMINE_ALL) { |
| 174 | 210 | initialize_dragon_data(); |
| 175 | 211 | compute_scores(chinese_rules || aftermath_play); |
| | 212 | |
| | 213 | #ifndef GG_TURN_OFF_TRACES |
| 176 | 214 | verbose = save_verbose; |
| | 215 | #endif |
| | 216 | |
| 177 | 217 | gg_assert(test_gray_border() < 0); |
| 178 | 218 | return; |
| 179 | 219 | } |
| 180 | 220 | |
| | 221 | #ifndef GG_TURN_OFF_TRACES |
| 181 | 222 | verbose = save_verbose; |
| | 223 | #endif |
| 182 | 224 | |
| 183 | 225 | if (NEEDS_UPDATE(initial_influence2_examined)) { |
| 184 | 226 | compute_dragon_influence(); |
| … |
… |
|
| 197 | 239 | return; |
| 198 | 240 | } |
| 199 | 241 | |
| | 242 | #ifndef GG_TURN_OFF_TRACES |
| 200 | 243 | if (printworms) |
| 201 | 244 | show_dragons(); |
| | 245 | #endif |
| 202 | 246 | } |
| 203 | 247 | |
| 204 | 248 | |
| … |
… |
|
| 283 | 327 | /* This function collects move reasons can be generated immediately from |
| 284 | 328 | * the data gathered in the examine_position() phase. |
| 285 | 329 | */ |
| 286 | | void |
| | 330 | inline void |
| 287 | 331 | collect_move_reasons(int color) |
| 288 | 332 | { |
| 289 | 333 | worm_reasons(color); |
| … |
… |
|
| 306 | 350 | int allowed_moves[BOARDMAX], float *value, int *resign) |
| 307 | 351 | { |
| 308 | 352 | float average_score, pessimistic_score, optimistic_score; |
| 309 | | int save_verbose; |
| 310 | | int save_depth; |
| 311 | 353 | int move; |
| 312 | 354 | float dummy_value; |
| 313 | 355 | int use_thrashing_dragon_heuristics = 0; |
| 314 | 356 | |
| | 357 | #ifndef GG_TURN_OFF_TRACES |
| | 358 | int save_verbose; |
| | 359 | #endif |
| | 360 | |
| | 361 | #ifndef GG_TURN_OFF_ASSERTS |
| | 362 | int save_depth; |
| | 363 | #endif |
| | 364 | |
| 315 | 365 | if (!value) |
| 316 | 366 | value = &dummy_value; |
| 317 | 367 | |
| | 368 | #ifndef GG_TURN_OFF_TRACES |
| 318 | 369 | start_timer(0); |
| | 370 | #endif |
| | 371 | |
| | 372 | #ifndef GG_TURN_OFF_STATS |
| 319 | 373 | clearstats(); |
| | 374 | #endif |
| 320 | 375 | |
| 321 | 376 | /* Usually we would not recommend resignation. */ |
| 322 | 377 | if (resign) |
| … |
… |
|
| 332 | 387 | /* Prepare pattern matcher and reading code. */ |
| 333 | 388 | reset_engine(); |
| 334 | 389 | |
| | 390 | #ifndef GG_TURN_OFF_ASSERTS |
| 335 | 391 | /* Store the depth value so we can check that it hasn't changed when |
| 336 | 392 | * we leave this function. |
| 337 | 393 | */ |
| 338 | 394 | save_depth = depth; |
| | 395 | #endif |
| 339 | 396 | |
| 340 | 397 | /* If in mirror mode, try to find a mirror move. */ |
| 341 | 398 | if (play_mirror_go |
| … |
… |
|
| 348 | 405 | } |
| 349 | 406 | |
| 350 | 407 | /* Find out information about the worms and dragons. */ |
| | 408 | #ifndef GG_TURN_OFF_TRACES |
| 351 | 409 | start_timer(1); |
| | 410 | #endif |
| | 411 | |
| 352 | 412 | examine_position(EXAMINE_ALL, 0); |
| | 413 | |
| | 414 | #ifndef GG_TURN_OFF_TRACES |
| 353 | 415 | time_report(1, "examine position", NO_MOVE, 1.0); |
| | 416 | #endif |
| 354 | 417 | |
| 355 | 418 | |
| 356 | 419 | /* The score will be used to determine when we are safely |
| … |
… |
|
| 374 | 437 | average_score = -(white_score + black_score)/2.0; |
| 375 | 438 | choose_strategy(color, average_score, game_status(color)); |
| 376 | 439 | |
| | 440 | #ifndef GG_TURN_OFF_TRACES |
| 377 | 441 | if (printboard) { |
| 378 | 442 | if (printboard == 1) |
| 379 | 443 | fprintf(stderr, "\n dragon_status display:\n\n"); |
| … |
… |
|
| 387 | 451 | showboard(4); |
| 388 | 452 | } |
| 389 | 453 | } |
| | 454 | #endif |
| 390 | 455 | |
| 391 | 456 | gg_assert(stackp == 0); |
| 392 | 457 | |
| … |
… |
|
| 396 | 461 | |
| 397 | 462 | |
| 398 | 463 | /* Pick up moves that we know of already. */ |
| | 464 | #ifndef GG_TURN_OFF_TRACES |
| 399 | 465 | save_verbose = verbose; |
| 400 | 466 | if (verbose > 0) |
| 401 | 467 | verbose--; |
| | 468 | #endif |
| | 469 | |
| 402 | 470 | collect_move_reasons(color); |
| | 471 | |
| | 472 | #ifndef GG_TURN_OFF_TRACES |
| 403 | 473 | verbose = save_verbose; |
| 404 | 474 | time_report(1, "generate move reasons", NO_MOVE, 1.0); |
| | 475 | #endif |
| 405 | 476 | |
| 406 | 477 | /* Try to find empty corner moves. */ |
| 407 | 478 | fuseki(color); |
| … |
… |
|
| 420 | 491 | |
| 421 | 492 | /* The general pattern database. */ |
| 422 | 493 | shapes(color); |
| | 494 | |
| | 495 | #ifndef GG_TURN_OFF_TRACES |
| 423 | 496 | time_report(1, "shapes", NO_MOVE, 1.0); |
| | 497 | #endif |
| | 498 | |
| 424 | 499 | gg_assert(stackp == 0); |
| 425 | 500 | |
| 426 | 501 | /* Look for combination attacks and defenses against them. */ |
| 427 | 502 | combinations(color); |
| | 503 | |
| | 504 | #ifndef GG_TURN_OFF_TRACES |
| 428 | 505 | time_report(1, "combinations", NO_MOVE, 1.0); |
| | 506 | #endif |
| | 507 | |
| 429 | 508 | gg_assert(stackp == 0); |
| 430 | 509 | |
| 431 | 510 | /* Review the move reasons and estimate move values. */ |
| … |
… |
|
| 433 | 512 | pure_threat_value, pessimistic_score, allowed_moves, |
| 434 | 513 | use_thrashing_dragon_heuristics)) |
| 435 | 514 | TRACE("Move generation likes %1m with value %f\n", move, *value); |
| | 515 | |
| 436 | 516 | gg_assert(stackp == 0); |
| | 517 | |
| | 518 | #ifndef GG_TURN_OFF_TRACES |
| 437 | 519 | time_report(1, "review move reasons", NO_MOVE, 1.0); |
| | 520 | #endif |
| 438 | 521 | |
| 439 | 522 | |
| 440 | 523 | /* If the move value is 6 or lower, we look for endgame patterns too. */ |
| … |
… |
|
| 447 | 530 | use_thrashing_dragon_heuristics)) |
| 448 | 531 | TRACE("Move generation likes %1m with value %f\n", move, *value); |
| 449 | 532 | gg_assert(stackp == 0); |
| | 533 | |
| | 534 | #ifndef GG_TURN_OFF_TRACES |
| 450 | 535 | time_report(1, "endgame", NO_MOVE, 1.0); |
| | 536 | #endif |
| 451 | 537 | } |
| 452 | 538 | |
| 453 | 539 | /* If no move found yet, revisit any semeai and change the |
| … |
… |
|
| 465 | 551 | move, *value); |
| 466 | 552 | } |
| 467 | 553 | } |
| 468 | | time_report(1, "move reasons with revised semeai status", |
| 469 | | NO_MOVE, 1.0); |
| | 554 | |
| | 555 | #ifndef GG_TURN_OFF_TRACES |
| | 556 | time_report(1, "move reasons with revised semeai status", NO_MOVE, 1.0); |
| | 557 | #endif |
| 470 | 558 | } |
| 471 | 559 | |
| 472 | 560 | /* If still no move, fill a remaining liberty. This should pick up |
| … |
… |
|
| 478 | 566 | *value = 1.0; |
| 479 | 567 | TRACE("Filling a liberty at %1m\n", move); |
| 480 | 568 | record_top_move(move, *value); |
| 481 | | move_considered(move, *value); |
| | 569 | |
| | 570 | #ifndef GG_TURN_OFF_TRACES |
| | 571 | move_considered(move, *value); |
| 482 | 572 | time_report(1, "fill liberty", NO_MOVE, 1.0); |
| | 573 | #endif |
| 483 | 574 | } |
| 484 | 575 | else |
| 485 | 576 | move = PASS_MOVE; |
| … |
… |
|
| 492 | 583 | if (move == PASS_MOVE) { |
| 493 | 584 | if (play_out_aftermath |
| 494 | 585 | || capture_all_dead |
| 495 | | || (!doing_scoring && thrashing_dragon && pessimistic_score > 15.0)) |
| | 586 | || (!doing_scoring && thrashing_dragon && pessimistic_score > 1.0)) |
| 496 | 587 | move = aftermath_genmove(color, 0, allowed_moves); |
| 497 | 588 | |
| 498 | 589 | /* If we're instructed to capture all dead opponent stones, generate |
| … |
… |
|
| 506 | 597 | *value = 1.0; |
| 507 | 598 | TRACE("Aftermath move at %1m\n", move); |
| 508 | 599 | record_top_move(move, *value); |
| | 600 | |
| | 601 | #ifndef GG_TURN_OFF_TRACES |
| 509 | 602 | move_considered(move, *value); |
| 510 | 603 | time_report(1, "aftermath_genmove", NO_MOVE, 1.0); |
| | 604 | #endif |
| 511 | 605 | } |
| 512 | 606 | } |
| 513 | 607 | |
| … |
… |
|
| 534 | 628 | *resign = 1; |
| 535 | 629 | } |
| 536 | 630 | |
| | 631 | #ifndef GG_TURN_OFF_STATS |
| 537 | 632 | /* If statistics is turned on, this is the place to show it. */ |
| 538 | 633 | if (showstatistics) |
| 539 | 634 | showstats(); |
| | 635 | #endif |
| 540 | 636 | |
| | 637 | #ifndef GG_TURN_OFF_TRACES |
| 541 | 638 | if (showtime) { |
| 542 | 639 | double spent = time_report(0, "TIME to generate move at ", move, 1.0); |
| 543 | 640 | total_time += spent; |
| … |
… |
|
| 547 | 644 | slowest_movenum = movenum + 1; |
| 548 | 645 | } |
| 549 | 646 | } |
| | 647 | #endif |
| 550 | 648 | |
| 551 | 649 | /* Some consistency checks to verify that things are properly |
| 552 | 650 | * restored and/or have not been corrupted. |
| 553 | 651 | */ |
| 554 | 652 | gg_assert(stackp == 0); |
| 555 | 653 | gg_assert(test_gray_border() < 0); |
| | 654 | |
| | 655 | #ifndef GG_TURN_OFF_ASSERTS |
| 556 | 656 | gg_assert(depth == save_depth); |
| | 657 | #endif |
| 557 | 658 | |
| 558 | 659 | return move; |
| 559 | 660 | } |
| … |
… |
|
| 565 | 666 | * have considered. |
| 566 | 667 | */ |
| 567 | 668 | |
| 568 | | void |
| | 669 | inline void |
| 569 | 670 | move_considered(int move, float value) |
| 570 | 671 | { |
| 571 | 672 | if (value > potential_moves[move]) |
| … |
… |
|
| 682 | 783 | return 0; |
| 683 | 784 | } |
| 684 | 785 | |
| 685 | | /* Computer two territory estimates: for *upper, the status of all |
| | 786 | /* Compute two territory estimates: for *upper, the status of all |
| 686 | 787 | * cricital stones gets resolved in White's favor; vice verso for |
| 687 | 788 | * black. |
| 688 | 789 | */ |
| … |
… |
|
| 701 | 802 | NO_MOVE, "White territory estimate"); |
| 702 | 803 | black_score = influence_score(&move_influence, use_chinese_rules); |
| 703 | 804 | |
| | 805 | #ifndef GG_TURN_OFF_TRACES |
| 704 | 806 | if (verbose || showscore) { |
| 705 | 807 | if (white_score == black_score) |
| 706 | 808 | gprintf("Score estimate: %s %f\n", |
| … |
… |
|
| 711 | 813 | white_score > 0 ? "W " : "B ", gg_abs(white_score)); |
| 712 | 814 | fflush(stderr); |
| 713 | 815 | } |
| | 816 | #endif |
| 714 | 817 | } |
| 715 | 818 | |
| 716 | 819 | |
-
RCS file: /sources/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.81
diff -u -r1.81 globals.c
|
|
|
|
| 132 | 132 | float white_score; |
| 133 | 133 | float black_score; |
| 134 | 134 | |
| 135 | | int close_worms[BOARDMAX][4]; |
| | 135 | /* Close worms data. See liberty.h */ |
| | 136 | int close_worms[BOARDMAX][MAX_CLOSE_WORMS]; |
| 136 | 137 | int number_close_worms[BOARDMAX]; |
| 137 | | int close_black_worms[BOARDMAX][4]; |
| | 138 | int close_black_worms[BOARDMAX][MAX_CLOSE_WORMS]; |
| 138 | 139 | int number_close_black_worms[BOARDMAX]; |
| 139 | | int close_white_worms[BOARDMAX][4]; |
| | 140 | int close_white_worms[BOARDMAX][MAX_CLOSE_WORMS]; |
| 140 | 141 | int number_close_white_worms[BOARDMAX]; |
| 141 | 142 | |
| 142 | 143 | int false_eye_territory[BOARDMAX]; |
-
RCS file: /sources/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.133
diff -u -r1.133 gnugo.h
|
|
|
|
| 114 | 114 | /* global variables */ |
| 115 | 115 | /* ================================================================ */ |
| 116 | 116 | |
| | 117 | // final release option |
| | 118 | |
| | 119 | #if FINAL_RELEASE == 1 |
| | 120 | |
| | 121 | #define GG_TURN_OFF_ASSERTS |
| | 122 | #define GG_TURN_OFF_TRACES |
| | 123 | #define GG_TURN_OFF_STATS |
| | 124 | #define GG_TURN_OFF_DEBUGS |
| | 125 | |
| | 126 | #endif |
| 117 | 127 | |
| 118 | 128 | /* Miscellaneous debug options. */ |
| 119 | 129 | extern int quiet; /* Minimal output. */ |
| … |
… |
|
| 269 | 279 | /* influence.c */ |
| 270 | 280 | void debug_influence_move(int move); |
| 271 | 281 | |
| 272 | | |
| | 282 | #ifdef GG_TURN_OFF_TRACES |
| | 283 | #define TRACE (1) ? (void)0 : (void)gprintf |
| | 284 | #else |
| 273 | 285 | #define TRACE (!(verbose)) ? (void)0 : (void)gprintf |
| | 286 | #endif |
| | 287 | |
| | 288 | #ifdef GG_TURN_OFF_DEBUGS |
| | 289 | #define DEBUG (1) ? (void)0 : (void)DEBUG_func |
| | 290 | int DEBUG_func(int level, const char *fmt, ...); |
| | 291 | #else |
| 274 | 292 | |
| 275 | 293 | #ifdef HAVE_VARIADIC_DEFINE |
| 276 | 294 | |
| … |
… |
|
| 286 | 304 | |
| 287 | 305 | #endif /*HAVE_VARIADIC_DEFINE*/ |
| 288 | 306 | |
| | 307 | #endif /*GG_TURN_OFF_DEBUGS*/ |
| | 308 | |
| 289 | 309 | |
| 290 | 310 | /* genmove.c */ |
| 291 | 311 | #define EXAMINE_WORMS 1 |
-
RCS file: /sources/gnugo/gnugo/engine/hash.c,v
retrieving revision 1.38
diff -u -r1.38 hash.c
|
|
|
|
| 24 | 24 | #include "board.h" |
| 25 | 25 | #include "hash.h" |
| 26 | 26 | #include "random.h" |
| | 27 | #include "gnugo.h" |
| 27 | 28 | |
| 28 | 29 | #include <stdio.h> |
| 29 | 30 | #include <stdlib.h> |
| 30 | 31 | #include <limits.h> |
| | 32 | #include <string.h> |
| 31 | 33 | |
| 32 | 34 | |
| 33 | 35 | |
| … |
… |
|
| 58 | 60 | { |
| 59 | 61 | int i; |
| 60 | 62 | Hashvalue h = 0; |
| | 63 | const int limit = CHAR_BIT * sizeof(Hashvalue); |
| 61 | 64 | |
| 62 | | for (i = 0; 32*i < (int) (CHAR_BIT*sizeof(Hashvalue)); i++) |
| 63 | | h |= (Hashvalue) gg_urand() << 32*i; |
| | 65 | for (i = 0; i < limit; i += 32) |
| | 66 | h |= ((Hashvalue) gg_urand()) << i; |
| 64 | 67 | |
| 65 | 68 | return h; |
| 66 | 69 | } |
| … |
… |
|
| 118 | 121 | hashdata_xor(*target, black_hash[pos]); |
| 119 | 122 | } |
| 120 | 123 | |
| 121 | | if (ko_pos != 0) |
| | 124 | if (ko_pos != NO_MOVE) |
| 122 | 125 | hashdata_xor(*target, ko_hash[ko_pos]); |
| 123 | 126 | } |
| 124 | 127 | |
| 125 | 128 | /* Clear hashdata. */ |
| 126 | | void |
| | 129 | inline void |
| 127 | 130 | hashdata_clear(Hash_data *hd) |
| 128 | 131 | { |
| 129 | | int i; |
| 130 | | for (i = 0; i < NUM_HASHVALUES; i++) |
| 131 | | hd->hashval[i] = 0; |
| | 132 | memset(hd->hashval, 0, NUM_HASHVALUES * sizeof(Hashvalue)); |
| 132 | 133 | } |
| 133 | 134 | |
| 134 | 135 | /* Set or remove ko in the hash value and hash position. */ |
| 135 | | void |
| | 136 | inline void |
| 136 | 137 | hashdata_invert_ko(Hash_data *hd, int pos) |
| 137 | 138 | { |
| 138 | 139 | hashdata_xor(*hd, ko_hash[pos]); |
| … |
… |
|
| 140 | 141 | |
| 141 | 142 | |
| 142 | 143 | /* Set or remove a stone of COLOR at pos in a Hash_data. */ |
| 143 | | void |
| | 144 | inline void |
| 144 | 145 | hashdata_invert_stone(Hash_data *hd, int pos, int color) |
| 145 | 146 | { |
| 146 | 147 | if (color == BLACK) |
| … |
… |
|
| 151 | 152 | |
| 152 | 153 | |
| 153 | 154 | /* Set or remove the komaster value in the hash data. */ |
| 154 | | void |
| | 155 | inline void |
| 155 | 156 | hashdata_invert_komaster(Hash_data *hd, int komaster) |
| 156 | 157 | { |
| 157 | 158 | hashdata_xor(*hd, komaster_hash[komaster]); |
| 158 | 159 | } |
| 159 | 160 | |
| 160 | 161 | /* Set or remove the komaster position in the hash data. */ |
| 161 | | void |
| | 162 | inline void |
| 162 | 163 | hashdata_invert_kom_pos(Hash_data *hd, int kom_pos) |
| 163 | 164 | { |
| 164 | 165 | hashdata_xor(*hd, kom_pos_hash[kom_pos]); |
-
RCS file: /sources/gnugo/gnugo/engine/hash.h,v
retrieving revision 1.37
diff -u -r1.37 hash.h
|
|
|
|
| 87 | 87 | #define INIT_ZOBRIST_ARRAY(a) \ |
| 88 | 88 | hash_init_zobrist_array(a, (int) (sizeof(a) / sizeof(a[0]))) |
| 89 | 89 | |
| 90 | | void hashdata_clear(Hash_data *hd); |
| | 90 | inline void hashdata_clear(Hash_data *hd); |
| 91 | 91 | void hashdata_recalc(Hash_data *hd, Intersection *board, int ko_pos); |
| 92 | | void hashdata_invert_ko(Hash_data *hd, int pos); |
| 93 | | void hashdata_invert_stone(Hash_data *hd, int pos, int color); |
| 94 | | void hashdata_invert_komaster(Hash_data *hd, int komaster); |
| 95 | | void hashdata_invert_kom_pos(Hash_data *hd, int kom_pos); |
| | 92 | inline void hashdata_invert_ko(Hash_data *hd, int pos); |
| | 93 | inline void hashdata_invert_stone(Hash_data *hd, int pos, int color); |
| | 94 | inline void hashdata_invert_komaster(Hash_data *hd, int komaster); |
| | 95 | inline void hashdata_invert_kom_pos(Hash_data *hd, int kom_pos); |
| 96 | 96 | |
| 97 | 97 | char *hashdata_to_string(Hash_data *hashdata); |
| 98 | 98 | |
| … |
… |
|
| 100 | 100 | |
| 101 | 101 | /* ---------------------------------------------------------------- */ |
| 102 | 102 | |
| 103 | | /* There is no need to involve all bits in the remainder computation |
| 104 | | * as long as we only use it to compute a key into a hash table. 32 |
| 105 | | * random bits are sufficient to get an even distribution within any |
| 106 | | * hashtable of reasonable size. By never using more than 32 bits we |
| 107 | | * also reduce the platform dependency of the GNU Go engine. |
| 108 | | */ |
| | 103 | /* Calculates a place in the transposition table where to look up for |
| | 104 | a hash value. If sizeof(long) > sizeof(int) we truncate long to int |
| | 105 | because size of the transposition table wouldn't be greater than |
| | 106 | int. */ |
| 109 | 107 | #define hashdata_remainder(hd, num) \ |
| 110 | | (((hd).hashval[0] & 0xffffffffU) % (num)) |
| | 108 | (*((unsigned int*)((hd).hashval)) % (num)) |
| | 109 | |
| 111 | 110 | |
| 112 | 111 | #if NUM_HASHVALUES == 1 |
| 113 | 112 | |
-
RCS file: /sources/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.258
diff -u -r1.258 liberty.h
|
|
|
|
| 97 | 97 | "analyze_semeai" |
| 98 | 98 | |
| 99 | 99 | /* To prioritize between different types of reading, we give a cost |
| 100 | | * ranking to each of the routines above: |
| | 100 | * ranking to each of the routines above (bigger index means bigger |
| | 101 | * cost): |
| 101 | 102 | * |
| 102 | 103 | * 4 semeai |
| 103 | 104 | * 3 owl |
| … |
… |
|
| 111 | 112 | 3, 3, 4, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, -1 |
| 112 | 113 | |
| 113 | 114 | |
| 114 | | const char *routine_id_to_string(enum routine_id routine); |
| | 115 | inline const char *routine_id_to_string(enum routine_id routine); |
| 115 | 116 | |
| 116 | 117 | |
| 117 | 118 | /* This is used for both the dragon status and safety fields. |
| … |
… |
|
| 119 | 120 | * final status computed by the aftermath code. |
| 120 | 121 | */ |
| 121 | 122 | enum dragon_status { |
| | 123 | UNKNOWN, |
| 122 | 124 | DEAD, |
| 123 | 125 | ALIVE, |
| 124 | 126 | CRITICAL, |
| 125 | | UNKNOWN, |
| 126 | 127 | UNCHECKED, |
| 127 | 128 | CAN_THREATEN_ATTACK, |
| 128 | 129 | CAN_THREATEN_DEFENSE, |
| … |
… |
|
| 139 | 140 | }; |
| 140 | 141 | |
| 141 | 142 | #define DRAGON_STATUS_NAMES \ |
| | 143 | "unknown", \ |
| 142 | 144 | "dead", \ |
| 143 | 145 | "alive", \ |
| 144 | 146 | "critical", \ |
| 145 | | "unknown", \ |
| 146 | 147 | "unchecked", \ |
| 147 | 148 | "can threaten attack", \ |
| 148 | 149 | "can threaten defense", \ |
| … |
… |
|
| 194 | 195 | struct corner_db *database); |
| 195 | 196 | void dfa_match_init(void); |
| 196 | 197 | |
| 197 | | void reading_cache_init(int bytes); |
| 198 | | void reading_cache_clear(void); |
| 199 | | float reading_cache_default_size(void); |
| | 198 | inline void reading_cache_init(int bytes); |
| | 199 | inline void reading_cache_clear(void); |
| | 200 | inline float reading_cache_default_size(void); |
| 200 | 201 | |
| 201 | 202 | /* reading.c */ |
| 202 | 203 | int attack(int str, int *move); |
| … |
… |
|
| 345 | 346 | int surround_map(int dr, int pos); |
| 346 | 347 | |
| 347 | 348 | /* functions to add (or remove) move reasons */ |
| 348 | | void collect_move_reasons(int color); |
| | 349 | inline void collect_move_reasons(int color); |
| 349 | 350 | |
| 350 | 351 | void clear_move_reasons(void); |
| 351 | 352 | void add_lunch(int eater, int food); |
| … |
… |
|
| 652 | 653 | |
| 653 | 654 | void break_territories(int color_to_move, struct influence_data *q, |
| 654 | 655 | int store, int pos); |
| 655 | | void clear_break_in_list(void); |
| | 656 | inline void clear_break_in_list(void); |
| 656 | 657 | void break_in_move_reasons(int color); |
| 657 | 658 | |
| 658 | 659 | void choose_strategy(int color, float our_score, float game_status); |
| … |
… |
|
| 669 | 670 | |
| 670 | 671 | /* debugging support */ |
| 671 | 672 | void goaldump(const signed char goal[BOARDMAX]); |
| 672 | | void move_considered(int move, float value); |
| | 673 | inline void move_considered(int move, float value); |
| 673 | 674 | |
| 674 | 675 | |
| 675 | 676 | /* Transformation stuff. */ |
-
RCS file: /sources/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.135
diff -u -r1.135 move_reasons.c
|
|
|
|
| 1553 | 1553 | { |
| 1554 | 1554 | float new_strength; |
| 1555 | 1555 | int ii; |
| | 1556 | int aff_stone = board[affected]; |
| 1556 | 1557 | |
| 1557 | | ASSERT1(IS_STONE(board[affected]), affected); |
| | 1558 | ASSERT1(IS_STONE(aff_stone), affected); |
| 1558 | 1559 | |
| 1559 | 1560 | if (new_status == 0) |
| 1560 | 1561 | new_strength = 0.0; |
| … |
… |
|
| 1563 | 1564 | new_strength = DEFAULT_STRENGTH; |
| 1564 | 1565 | } |
| 1565 | 1566 | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1566 | | if (board[ii] == board[affected] |
| | 1567 | if (board[ii] == aff_stone |
| 1567 | 1568 | && same_string(ii, affected)) { |
| 1568 | 1569 | strength[ii] = new_strength; |
| 1569 | 1570 | safe_stones[ii] = new_status; |
-
RCS file: /sources/gnugo/gnugo/engine/optics.c,v
retrieving revision 1.105
diff -u -r1.105 optics.c
|
|
|
|
| 1748 | 1748 | int defense_point; |
| 1749 | 1749 | int attack_value; |
| 1750 | 1750 | int defense_value; |
| | 1751 | int other = OTHER_COLOR(color); |
| 1751 | 1752 | |
| 1752 | 1753 | memset(attack_values, 0, sizeof(attack_values)); |
| 1753 | 1754 | memset(defense_values, 0, sizeof(defense_values)); |
| … |
… |
|
| 1846 | 1847 | * string neighbors more than one empty vertex in the |
| 1847 | 1848 | * same eyespace. |
| 1848 | 1849 | */ |
| 1849 | | if (val < 2.0 && board[pos] == EMPTY && board[diag] == OTHER_COLOR(color) |
| | 1850 | if (val < 2.0 && board[pos] == EMPTY && board[diag] == other |
| 1850 | 1851 | && !is_edge_vertex(pos) && neighbor_of_string(pos, diag) |
| 1851 | 1852 | && countstones(diag) >= 3) { |
| 1852 | 1853 | int strings[3]; |
| … |
… |
|
| 1880 | 1881 | continue; |
| 1881 | 1882 | |
| 1882 | 1883 | for (r = 0; r < lib_count && adj_eye_count < 2; r++) |
| 1883 | | if (my_eye[libs[r]].color == OTHER_COLOR(color) |
| | 1884 | if (my_eye[libs[r]].color == other |
| 1884 | 1885 | && !my_eye[libs[r]].marginal) |
| 1885 | 1886 | adj_eye_count++; |
| 1886 | 1887 | if (adj_eye_count < 2) { |
| … |
… |
|
| 1889 | 1890 | } |
| 1890 | 1891 | } |
| 1891 | 1892 | } |
| 1892 | | } |
| | 1893 | } |
| 1893 | 1894 | |
| 1894 | 1895 | sum += val; |
| 1895 | 1896 | |
| … |
… |
|
| 2402 | 2403 | * liberties empty. |
| 2403 | 2404 | */ |
| 2404 | 2405 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 2405 | | if (mx[pos] == 1 || board[pos] != EMPTY || liberty_of_string(pos, str)) |
| | 2406 | if (mx[pos] == 1 || board[pos] != EMPTY || liberty_of_string2(pos, str)) |
| 2406 | 2407 | continue; |
| 2407 | 2408 | for (k = 0; k < 8; k++) { |
| 2408 | | if (ON_BOARD(pos + delta[k]) |
| 2409 | | && liberty_of_string(pos + delta[k], str)) { |
| | 2409 | int checked_pos = pos + delta[k]; |
| | 2410 | if (ON_BOARD(checked_pos) |
| | 2411 | && liberty_of_string(checked_pos, str)) { |
| 2410 | 2412 | play_move(pos, BLACK); |
| 2411 | 2413 | break; |
| 2412 | 2414 | } |
| … |
… |
|
| 2695 | 2697 | int eyes; |
| 2696 | 2698 | |
| 2697 | 2699 | for (k = 0; k < 4; k++) { |
| 2698 | | if (board[vertex + delta[k]] == BLACK) { |
| | 2700 | int checked_pos = vertex + delta[k]; |
| | 2701 | if (board[checked_pos] == BLACK) { |
| 2699 | 2702 | eyes = 0; |
| 2700 | | num_libs = findlib(vertex + delta[k], MAXLIBS, libs); |
| | 2703 | num_libs = findlib(checked_pos, MAXLIBS, libs); |
| 2701 | 2704 | |
| 2702 | 2705 | for (r = 0; r < num_libs; r++) |
| 2703 | 2706 | if (is_suicide(libs[r], WHITE)) |
| … |
… |
|
| 3646 | 3649 | /* If there are any isolated O stones, those should also be added to |
| 3647 | 3650 | * the playable vertices. |
| 3648 | 3651 | */ |
| 3649 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) |
| 3650 | | if (board[pos] == WHITE && !same_string(pos, POS(1, 0))) { |
| 3651 | | vertices[num_vertices] = vertices[num_vertices - 1]; |
| 3652 | | vertices[num_vertices - 1] = vertices[num_vertices - 2]; |
| 3653 | | vertices[num_vertices - 2] = vertices[num_vertices - 3]; |
| 3654 | | vertices[num_vertices - 3] = pos; |
| 3655 | | num_vertices++; |
| 3656 | | } |
| | 3652 | { |
| | 3653 | int pos_1_0 = POS(1, 0); |
| | 3654 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) |
| | 3655 | if (board[pos] == WHITE && !same_string(pos, pos_1_0)) { |
| | 3656 | vertices[num_vertices] = vertices[num_vertices - 1]; |
| | 3657 | vertices[num_vertices - 1] = vertices[num_vertices - 2]; |
| | 3658 | vertices[num_vertices - 2] = vertices[num_vertices - 3]; |
| | 3659 | vertices[num_vertices - 3] = pos; |
| | 3660 | num_vertices++; |
| | 3661 | } |
| | 3662 | } |
| 3657 | 3663 | |
| 3658 | 3664 | if (verbose) { |
| 3659 | 3665 | int k; |
-
RCS file: /sources/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.251
diff -u -r1.251 owl.c
|
|
|
|
| 480 | 480 | && !is_same_dragon(adjs[k], bpos) |
| 481 | 481 | && dragon[adjs[k]].crude_status == ALIVE) |
| 482 | 482 | adjacent_to_outside = 1; |
| 483 | | } |
| | 483 | } |
| 484 | 484 | |
| 485 | 485 | if ((adjacent_to_outside || countstones(str) > 6) |
| 486 | 486 | && s_worms < MAX_SEMEAI_WORMS) { |
| … |
… |
|
| 1576 | 1576 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 1577 | 1577 | if (IS_STONE(board[pos]) |
| 1578 | 1578 | && pos == find_origin(pos)) { |
| 1579 | | if (owla->goal[pos]) |
| 1580 | | net -= 75*countlib(pos); |
| 1581 | | if (owlb->goal[pos]) |
| 1582 | | net += 100*countlib(pos); |
| | 1579 | int count_lib = -1; |
| | 1580 | if (owla->goal[pos]) { |
| | 1581 | count_lib = countlib(pos); |
| | 1582 | net -= 75 * count_lib; |
| | 1583 | } |
| | 1584 | if (owlb->goal[pos]) { |
| | 1585 | if (count_lib < 0) |
| | 1586 | count_lib = countlib(pos); |
| | 1587 | net += 100 * count_lib; |
| | 1588 | } |
| 1583 | 1589 | } |
| 1584 | 1590 | } |
| 1585 | 1591 | if (!trymove(move, color, NULL, 0)) { |
| … |
… |
|
| 1589 | 1595 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 1590 | 1596 | if (IS_STONE(board[pos]) |
| 1591 | 1597 | && pos == find_origin(pos)) { |
| | 1598 | int count_lib = -1; |
| 1592 | 1599 | if (owla->goal[pos] |
| 1593 | | || (pos == move && liberty_of_goal(move, owla))) |
| 1594 | | net += 75*countlib(pos); |
| 1595 | | if (owlb->goal[pos]) |
| 1596 | | net -= 100*countlib(pos); |
| | 1600 | || (pos == move && liberty_of_goal(move, owla))) { |
| | 1601 | count_lib = countlib(pos); |
| | 1602 | net += 75 * count_lib; |
| | 1603 | } |
| | 1604 | if (owlb->goal[pos]) { |
| | 1605 | if (count_lib < 0) |
| | 1606 | count_lib = countlib(pos); |
| | 1607 | net -= 100 * count_lib; |
| | 1608 | } |
| 1597 | 1609 | } |
| 1598 | 1610 | } |
| 1599 | 1611 | |
| … |
… |
|
| 1929 | 1941 | int size = 0; |
| 1930 | 1942 | saveworm = MAX_GOAL_WORMS; |
| 1931 | 1943 | for (k = 0; k < MAX_GOAL_WORMS; k++) { |
| 1932 | | if (owl_goal_worm[k] == NO_MOVE) |
| | 1944 | int worm_goal = owl_goal_worm[k]; |
| | 1945 | if (worm_goal == NO_MOVE) |
| 1933 | 1946 | break; |
| 1934 | | if (board[owl_goal_worm[k]] == EMPTY |
| 1935 | | || countlib(owl_goal_worm[k]) > 1) |
| | 1947 | if (board[worm_goal] == EMPTY |
| | 1948 | || countlib(worm_goal) > 1) |
| 1936 | 1949 | continue; |
| 1937 | | if (worm[owl_goal_worm[k]].size > size) { |
| | 1950 | if (worm[worm_goal].size > size) { |
| 1938 | 1951 | saveworm = k; |
| 1939 | | size = worm[owl_goal_worm[k]].size; |
| | 1952 | size = worm[worm_goal].size; |
| 1940 | 1953 | } |
| 1941 | 1954 | } |
| 1942 | 1955 | if (saveworm != MAX_GOAL_WORMS && size >= 3) { |
| … |
… |
|
| 3554 | 3567 | if (ON_BOARD(*move + delta[k]) && board[*move + delta[k]] != color) |
| 3555 | 3568 | return 0; |
| 3556 | 3569 | |
| 3557 | | for (r = 4; r < 8; r++) |
| 3558 | | if (board[*move + delta[r]] == other |
| 3559 | | && countlib(*move + delta[r]) == 1) { |
| 3560 | | for (k = 0; k < 4; k++) |
| 3561 | | if (board[*move + delta[k]] == color |
| 3562 | | && countlib(*move + delta[k]) == 1 |
| 3563 | | && !adjacent_strings(*move + delta[r], *move + delta[k])) |
| | 3570 | for (r = 4; r < 8; r++) { |
| | 3571 | int checked_pos_r = *move + delta[r]; |
| | 3572 | if (board[checked_pos_r] == other |
| | 3573 | && countlib(checked_pos_r) == 1) { |
| | 3574 | for (k = 0; k < 4; k++) { |
| | 3575 | int checked_pos_k = *move + delta[k]; |
| | 3576 | if (board[checked_pos_k] == color |
| | 3577 | && countlib(checked_pos_k) == 1 |
| | 3578 | && !adjacent_strings(checked_pos_r, checked_pos_k)) |
| 3564 | 3579 | break; |
| | 3580 | } |
| 3565 | 3581 | |
| 3566 | 3582 | if (k == 4) { |
| 3567 | 3583 | int new_move; |
| 3568 | | findlib(*move + delta[r], 1, &new_move); |
| | 3584 | findlib(checked_pos_r, 1, &new_move); |
| 3569 | 3585 | TRACE("Changing eyefilling move at %1m to capture at %1m.\n", |
| 3570 | 3586 | *move, new_move); |
| 3571 | 3587 | *move = new_move; |
| 3572 | 3588 | return 1; |
| 3573 | 3589 | } |
| 3574 | 3590 | } |
| | 3591 | } |
| 3575 | 3592 | |
| 3576 | 3593 | return 0; |
| 3577 | 3594 | } |
| … |
… |
|
| 4999 | 5016 | mark_string(pos, component2, closest_component); |
| 5000 | 5017 | component_size[closest_component] += countstones(pos); |
| 5001 | 5018 | } |
| 5002 | | } |
| | 5019 | } |
| 5003 | 5020 | |
| 5004 | 5021 | /* Now find the biggest_component. */ |
| 5005 | 5022 | { |
-
RCS file: /sources/gnugo/gnugo/engine/persistent.c,v
retrieving revision 1.40
diff -u -r1.40 persistent.c
|
|
|
|
| 233 | 233 | return 0; |
| 234 | 234 | else if (!(p[pos] & (HIGH_LIBERTY_BIT | HIGH_LIBERTY_BIT2))) |
| 235 | 235 | continue; |
| 236 | | else if (((p[pos] & HIGH_LIBERTY_BIT) && countlib(pos) <= 4) |
| 237 | | || (p[pos] & HIGH_LIBERTY_BIT2 && countlib(pos) <= 3)) |
| 238 | | return 0; |
| | 236 | else { |
| | 237 | int count_lib = countlib(pos); |
| | 238 | if (((p[pos] & HIGH_LIBERTY_BIT) && count_lib <= 4) |
| | 239 | || ((p[pos] & HIGH_LIBERTY_BIT2) && count_lib <= 3)) |
| | 240 | return 0; |
| | 241 | } |
| 239 | 242 | } |
| 240 | 243 | |
| 241 | 244 | return 1; |
| … |
… |
|
| 336 | 339 | else { |
| 337 | 340 | for (r = 0; r < MAX_CACHE_DEPTH; r++) { |
| 338 | 341 | int apos = entry->stack[r]; |
| 339 | | int color = entry->move_color[r]; |
| 340 | | if (apos == 0) |
| | 342 | int color; |
| | 343 | if (apos == NO_MOVE) |
| 341 | 344 | break; |
| | 345 | color = entry->move_color[r]; |
| 342 | 346 | if (board[apos] == EMPTY |
| 343 | 347 | && trymove(apos, color, "purge_persistent_cache", 0)) |
| 344 | 348 | played_moves++; |
| … |
… |
|
| 354 | 358 | /* Move the last entry in the cache here and back up the loop |
| 355 | 359 | * counter to redo the test at this position in the cache. |
| 356 | 360 | */ |
| 357 | | if (0) |
| | 361 | #if 0 |
| 358 | 362 | gprintf("Purging entry %d from cache.\n", k); |
| | 363 | #endif |
| 359 | 364 | if (k < cache->current_size - 1) |
| 360 | 365 | *entry = cache->table[cache->current_size - 1]; |
| 361 | 366 | k--; |
| … |
… |
|
| 718 | 723 | int m, int n, float contribution) |
| 719 | 724 | { |
| 720 | 725 | int i, j, k; |
| | 726 | int pos_mn; |
| 721 | 727 | |
| 722 | 728 | /* If p[m][n] is EMPTY, we just give the contribution to close empty |
| 723 | 729 | * vertices. This is a rough simplification. |
| … |
… |
|
| 733 | 739 | /* Otherwise we give contribution to liberties and diagonal |
| 734 | 740 | * neighbors of the string at (m, n). |
| 735 | 741 | */ |
| | 742 | pos_mn = POS(m, n); |
| 736 | 743 | for (i = 0; i < board_size; i++) |
| 737 | 744 | for (j = 0; j < board_size; j++) { |
| 738 | 745 | if (BOARD(i, j) != EMPTY) |
| 739 | 746 | continue; |
| 740 | 747 | for (k = 0; k < 8; k++) { |
| 741 | | int di = deltai[k]; |
| 742 | | int dj = deltaj[k]; |
| 743 | | if (IS_STONE(BOARD(i+di, j+dj)) |
| 744 | | && same_string(POS(i+di, j+dj), POS(m, n))) { |
| | 748 | int di = i + deltai[k]; |
| | 749 | int dj = j + deltaj[k]; |
| | 750 | if (IS_STONE(BOARD(di, dj)) |
| | 751 | && same_string(POS(di, dj), pos_mn)) { |
| 745 | 752 | if (k < 4) { |
| 746 | 753 | values[POS(i, j)] += contribution; |
| 747 | 754 | break; |
| 748 | 755 | } |
| 749 | 756 | else { |
| 750 | | if (BOARD(i+di, j) == EMPTY || countlib(POS(i+di, j)) <= 2 |
| 751 | | || BOARD(i, j+dj) == EMPTY || countlib(POS(i, j+dj)) <= 2) |
| | 757 | if (BOARD(di, j) == EMPTY || countlib(POS(di, j)) <= 2 |
| | 758 | || BOARD(i, dj) == EMPTY || countlib(POS(i, dj)) <= 2) |
| 752 | 759 | values[POS(i, j)] += contribution; |
| 753 | 760 | break; |
| 754 | 761 | } |
| … |
… |
|
| 1345 | 1352 | if (board[pos] != EMPTY) |
| 1346 | 1353 | continue; |
| 1347 | 1354 | for (k = 0; k < 8; k++) { |
| | 1355 | int same_dragon; |
| 1348 | 1356 | int pos2 = pos + delta[k]; |
| 1349 | 1357 | if (IS_STONE(board[pos2]) |
| 1350 | | && (is_same_dragon(pos2, dr) |
| | 1358 | && ((same_dragon = is_same_dragon(pos2, dr)) |
| 1351 | 1359 | || (are_neighbor_dragons(pos2, dr) |
| 1352 | 1360 | && board[pos2] == board[dr])) |
| 1353 | 1361 | && (countlib(pos2) <= 4 |
| 1354 | 1362 | || is_edge_vertex(pos))) { |
| 1355 | 1363 | if (k < 4) { |
| 1356 | | if (is_same_dragon(pos2, dr)) |
| | 1364 | if (same_dragon) |
| 1357 | 1365 | values[pos] += contribution; |
| 1358 | 1366 | else |
| 1359 | 1367 | values[pos] += 0.5 * contribution; |
-
RCS file: /sources/gnugo/gnugo/engine/printutils.c,v
retrieving revision 1.56
diff -u -r1.56 printutils.c
|
|
|
|
| 24 | 24 | #include "hash.h" |
| 25 | 25 | #include "gg_utils.h" |
| 26 | 26 | #include "sgftree.h" |
| | 27 | #include "gnugo.h" |
| 27 | 28 | |
| 28 | 29 | #include <stdio.h> |
| 29 | 30 | #include <string.h> |
| … |
… |
|
| 35 | 36 | * This function underpins all the TRACE and DEBUG stuff. |
| 36 | 37 | * It accepts %c, %d, %f, %s, and %x as usual. But it |
| 37 | 38 | * also accepts %m, which takes TWO integers and writes a move. |
| | 39 | * It is possible to specify %1m, which takes one integer and |
| | 40 | * prints a move (integer means the board array index). |
| 38 | 41 | * Other accepted formats are |
| 39 | 42 | * %H: Print a hashvalue. |
| 40 | 43 | * %C: Print a color as a string. |
-
RCS file: /sources/gnugo/gnugo/engine/readconnect.c,v
retrieving revision 1.99
diff -u -r1.99 readconnect.c
|
|
|
|
| 246 | 246 | |
| 247 | 247 | /* if only one liberty after capture */ |
| 248 | 248 | if (trymove(lib, OTHER_COLOR(board[str]), "snapback", str)) { |
| 249 | | liberties = 0; |
| 250 | | if (IS_STONE(board[lib])) |
| 251 | | liberties = countlib(lib); |
| | 249 | liberties = countlib(lib); |
| 252 | 250 | popgo(); |
| 253 | 251 | sgf_dumptree = save_sgf_dumptree; |
| 254 | 252 | if (liberties > 1) |
| … |
… |
|
| 271 | 269 | int liberties, libs[MAXLIBS]; |
| 272 | 270 | int adj, adjs[MAXCHAIN]; |
| 273 | 271 | int neighb, neighbs[MAXCHAIN]; |
| | 272 | int color = board[str1]; |
| | 273 | int other = OTHER_COLOR(color); |
| 274 | 274 | |
| 275 | 275 | /* finds connection through two forbidden liberties for |
| 276 | 276 | * the opponent |
| … |
… |
|
| 288 | 288 | */ |
| 289 | 289 | liberties = findlib(str1, MAXLIBS, libs); |
| 290 | 290 | for (r = 0; r < liberties; r++) |
| 291 | | if (is_self_atari(libs[r], OTHER_COLOR(board[str1]))) |
| | 291 | if (is_self_atari(libs[r], other)) |
| 292 | 292 | for (k = 0; k < 4; k++) { |
| 293 | 293 | int pos = libs[r] + delta[k]; |
| 294 | | if (board[pos] == board[str1] |
| | 294 | if (board[pos] == color |
| 295 | 295 | && !same_string(pos, str1) |
| 296 | 296 | && !same_string(pos, str2)) { |
| 297 | 297 | /* try to connect pos to str2 in one move */ |
| 298 | 298 | /* play a common liberty */ |
| 299 | 299 | neighb = findlib(pos, MAXLIBS, neighbs); |
| 300 | 300 | for (s = 0; s < neighb; s++) |
| 301 | | if (liberty_of_string(neighbs[s], str2)) { |
| | 301 | if (liberty_of_string2(neighbs[s], str2)) { |
| 302 | 302 | res = 1; |
| 303 | 303 | add_zone(zn, libs[r]); |
| 304 | 304 | add_zone(zn, neighbs[s]); |
| … |
… |
|
| 492 | 492 | liberties = findlib(adjs[r], MAXLIBS, libs); |
| 493 | 493 | common_adj_liberty = 0; |
| 494 | 494 | for (s = 0; s < liberties; s++) |
| 495 | | if (liberty_of_string(libs[s], str2)) |
| | 495 | if (liberty_of_string2(libs[s], str2)) |
| 496 | 496 | common_adj_liberty = 1; |
| 497 | 497 | if (common_adj_liberty || adjacent_strings(adjs[r], str2)) { |
| 498 | 498 | for (s = 0; s < liberties; s++) |
| … |
… |
|
| 511 | 511 | liberties = findlib(adjs[r], MAXLIBS, libs); |
| 512 | 512 | common_adj_liberty = 0; |
| 513 | 513 | for (s = 0; s < liberties; s++) |
| 514 | | if (liberty_of_string(libs[s], str1)) |
| | 514 | if (liberty_of_string2(libs[s], str1)) |
| 515 | 515 | common_adj_liberty = 1; |
| 516 | 516 | if (common_adj_liberty || adjacent_strings(adjs[r], str1)) { |
| 517 | 517 | for (s = 0; s < liberties; s++) |
| … |
… |
|
| 530 | 530 | liberties = findlib(str1, MAXLIBS, libs); |
| 531 | 531 | for (r = 0; r < liberties; r++) { |
| 532 | 532 | if (board[SOUTH(libs[r])] == EMPTY) { |
| 533 | | if (liberty_of_string(SOUTH(libs[r]), str2)) { |
| | 533 | if (liberty_of_string2(SOUTH(libs[r]), str2)) { |
| 534 | 534 | add_array(moves, libs[r]); |
| 535 | 535 | add_array(moves, SOUTH(libs[r])); |
| 536 | 536 | } |
| 537 | 537 | } |
| 538 | 538 | |
| 539 | 539 | if (board[WEST(libs[r])] == EMPTY) { |
| 540 | | if (liberty_of_string(WEST(libs[r]), str2)) { |
| | 540 | if (liberty_of_string2(WEST(libs[r]), str2)) { |
| 541 | 541 | add_array(moves, libs[r]); |
| 542 | 542 | add_array(moves, WEST(libs[r])); |
| 543 | 543 | } |
| 544 | 544 | } |
| 545 | 545 | |
| 546 | 546 | if (board[NORTH(libs[r])] == EMPTY) { |
| 547 | | if (liberty_of_string(NORTH(libs[r]), str2)) { |
| | 547 | if (liberty_of_string2(NORTH(libs[r]), str2)) { |
| 548 | 548 | add_array(moves, libs[r]); |
| 549 | 549 | add_array(moves, NORTH(libs[r])); |
| 550 | 550 | } |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | if (board[EAST(libs[r])] == EMPTY) { |
| 554 | | if (liberty_of_string(EAST(libs[r]), str2)) { |
| | 554 | if (liberty_of_string2(EAST(libs[r]), str2)) { |
| 555 | 555 | add_array(moves, libs[r]); |
| 556 | 556 | add_array(moves, EAST(libs[r])); |
| 557 | 557 | } |
| … |
… |
|
| 561 | 561 | /* Liberties of str1 which are adjacent to a friendly string with |
| 562 | 562 | * common liberty with str2. |
| 563 | 563 | */ |
| 564 | | liberties = findlib(str1, MAXLIBS, libs); |
| | 564 | |
| | 565 | #ifndef GG_TURN_OFF_ASSERTS |
| | 566 | /* We got liberties from previous call to findlib. */ |
| | 567 | { |
| | 568 | int test_libs[MAXLIBS]; |
| | 569 | int t; |
| | 570 | gg_assert(liberties == findlib(str1, MAXLIBS, test_libs)); |
| | 571 | for (t = 0; t < liberties; ++t) |
| | 572 | gg_assert(libs[t] == test_libs[t]); |
| | 573 | } |
| | 574 | #endif |
| | 575 | |
| 565 | 576 | for (r = 0; r < liberties; r++) { |
| 566 | 577 | for (k = 0; k < 4; k++) { |
| 567 | 578 | int pos = libs[r] + delta[k]; |
| … |
… |
|
| 1495 | 1506 | SGFTree *save_sgf_dumptree = sgf_dumptree; |
| 1496 | 1507 | int save_count_variations = count_variations; |
| 1497 | 1508 | int result = 0; |
| | 1509 | int count_lib = countlib(str); |
| 1498 | 1510 | |
| 1499 | 1511 | /* We turn off the sgf traces here to avoid cluttering them up with |
| 1500 | 1512 | * naive_ladder moves. |
| … |
… |
|
| 1502 | 1514 | sgf_dumptree = NULL; |
| 1503 | 1515 | count_variations = 0; |
| 1504 | 1516 | |
| 1505 | | if (countlib(str) == 1) { |
| | 1517 | if (count_lib == 1) { |
| 1506 | 1518 | findlib(str, 1, move); |
| 1507 | 1519 | result = WIN; |
| 1508 | 1520 | } |
| 1509 | | else if (countlib(str) == 2) |
| | 1521 | else if (count_lib == 2) |
| 1510 | 1522 | result = simple_ladder(str, move); |
| 1511 | 1523 | |
| 1512 | 1524 | /* Turn the sgf traces back on. */ |
| … |
… |
|
| 2317 | 2329 | SGFTree *save_sgf_dumptree = sgf_dumptree; |
| 2318 | 2330 | int save_count_variations = count_variations; |
| 2319 | 2331 | int distance_limit; |
| | 2332 | int str2_onboard; |
| 2320 | 2333 | |
| 2321 | 2334 | /* We turn off the sgf traces here to avoid cluttering them up with |
| 2322 | 2335 | * tactical reading moves. |
| … |
… |
|
| 2447 | 2460 | } |
| 2448 | 2461 | |
| 2449 | 2462 | /* Modify the distance values for the moves with various bonuses. */ |
| | 2463 | if (ON_BOARD(str2)) |
| | 2464 | str2_onboard = 1; |
| | 2465 | else |
| | 2466 | str2_onboard = 0; |
| | 2467 | |
| 2450 | 2468 | for (r = 0; r < num_moves; r++) { |
| 2451 | 2469 | int move = moves[r]; |
| 2452 | 2470 | int adjacent_to_attacker = 0; |
| … |
… |
|
| 2476 | 2494 | gprintf("%o%1M -0.7, capture or atari of immediately connecting string\n", move); |
| 2477 | 2495 | } |
| 2478 | 2496 | } |
| 2479 | | } |
| | 2497 | } |
| 2480 | 2498 | else if (board[pos] == color) { |
| 2481 | | if (countlib(pos) <= 2) { |
| | 2499 | int count_lib = countlib(pos); |
| | 2500 | if (count_lib <= 2) { |
| 2482 | 2501 | distances[r] -= FP(0.2); |
| 2483 | 2502 | if (verbose > 0) |
| 2484 | 2503 | gprintf("%o%1M -0.2, adjacent to defender string with at most two liberties\n", move); |
| … |
… |
|
| 2491 | 2510 | * The following code compensates in such kind of situations. |
| 2492 | 2511 | * See connection:111 and gunnar:53 for example. |
| 2493 | 2512 | */ |
| 2494 | | if (!connect_move && countlib(pos) == 1 |
| | 2513 | if (!connect_move && count_lib == 1 |
| 2495 | 2514 | /* let's avoid ko and snapbacks */ |
| 2496 | 2515 | && accuratelib(move, other, 2, NULL) > 1) { |
| 2497 | 2516 | int adjs[MAXCHAIN]; |
| … |
… |
|
| 2523 | 2542 | * Neighbor strings with less than 3 liberties have already |
| 2524 | 2543 | * generated a bonus above. |
| 2525 | 2544 | */ |
| 2526 | | if ((liberty_of_string(move, str1) |
| | 2545 | if ((liberty_of_string2(move, str1) |
| 2527 | 2546 | && countlib(str1) == 3) |
| 2528 | | || (ON_BOARD(str2) && liberty_of_string(move, str2) |
| | 2547 | || (str2_onboard && liberty_of_string2(move, str2) |
| 2529 | 2548 | && countlib(str2) == 3)) { |
| 2530 | 2549 | distances[r] -= FP(0.1); |
| 2531 | 2550 | if (verbose > 0) |
| … |
… |
|
| 4235 | 4254 | int save_count_variations = count_variations; |
| 4236 | 4255 | int adj[MAXCHAIN]; |
| 4237 | 4256 | int libs[2]; |
| | 4257 | int count_lib = countlib(str); |
| 4238 | 4258 | |
| 4239 | 4259 | /* We turn off the sgf traces here to avoid cluttering them up with |
| 4240 | 4260 | * tactical reading moves. |
| … |
… |
|
| 4242 | 4262 | sgf_dumptree = NULL; |
| 4243 | 4263 | count_variations = 0; |
| 4244 | 4264 | |
| 4245 | | if (countlib(str) == 1 && find_defense(str, NULL) == 0) |
| | 4265 | if (count_lib == 1 && find_defense(str, NULL) == 0) |
| 4246 | 4266 | result = 1; |
| 4247 | 4267 | |
| 4248 | | if (countlib(str) == 2 |
| | 4268 | if (count_lib == 2 |
| 4249 | 4269 | && chainlinks2(str, adj, 1) == 0 |
| 4250 | 4270 | && findlib(str, 2, libs) == 2 |
| 4251 | 4271 | && approxlib(libs[0], board[str], 2, NULL) == 1 |
| … |
… |
|
| 4332 | 4352 | if (apos == bpos) |
| 4333 | 4353 | return 1; |
| 4334 | 4354 | |
| 4335 | | for (k = 0; k < 4; k++) |
| 4336 | | if (board[apos + delta[k]] == color |
| 4337 | | && countlib(apos + delta[k]) <= 3 |
| 4338 | | && liberty_of_string(bpos, apos + delta[k])) |
| | 4355 | for (k = 0; k < 4; k++) { |
| | 4356 | int checked_pos = apos + delta[k]; |
| | 4357 | if (board[checked_pos] == color |
| | 4358 | && countlib(checked_pos) <= 3 |
| | 4359 | && liberty_of_string(bpos, checked_pos)) |
| 4339 | 4360 | return 1; |
| | 4361 | } |
| 4340 | 4362 | |
| 4341 | 4363 | return 0; |
| 4342 | 4364 | } |
-
RCS file: /sources/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.168
diff -u -r1.168 reading.c
|
|
|
|
| 1032 | 1032 | int r; |
| 1033 | 1033 | |
| 1034 | 1034 | ASSERT1(IS_STONE(board[str]), str); |
| 1035 | | other = OTHER_COLOR(board[str]); |
| 1036 | 1035 | |
| 1037 | 1036 | /* Only handle strings with no way to capture immediately. |
| 1038 | 1037 | * For now, we treat ko the same as unconditionally. */ |
| … |
… |
|
| 1046 | 1045 | * |
| 1047 | 1046 | * The test against 6 liberties is just an optimization. |
| 1048 | 1047 | */ |
| | 1048 | other = OTHER_COLOR(board[str]); |
| 1049 | 1049 | liberties = findlib(str, MAXLIBS, libs); |
| 1050 | 1050 | if (liberties > 1 && liberties < 6) { |
| 1051 | 1051 | for (k = 0; k < liberties; k++) { |
| … |
… |
|
| 1065 | 1065 | |
| 1066 | 1066 | if (!ON_BOARD(bb) |
| 1067 | 1067 | || IS_STONE(board[bb]) |
| 1068 | | || liberty_of_string(bb, str)) |
| | 1068 | || liberty_of_string2(bb, str)) |
| 1069 | 1069 | continue; |
| 1070 | 1070 | |
| 1071 | 1071 | if (trymove(bb, other, "attack_threats-B", str)) { |
| … |
… |
|
| 1322 | 1322 | * it has already been done in the first loop of this function. |
| 1323 | 1323 | */ |
| 1324 | 1324 | num_adjacent_stones = count_adjacent_stones(adjs[j], str, missing); |
| 1325 | | if (!liberty_of_string(lib, str) |
| | 1325 | if (!liberty_of_string2(lib, str) |
| 1326 | 1326 | && num_adjacent_stones >= missing) { |
| 1327 | 1327 | *move = lib; |
| 1328 | 1328 | return 1; |
| … |
… |
|
| 1444 | 1444 | break_chain_moves(str, &moves); |
| 1445 | 1445 | set_up_snapback_moves(str, lib, &moves); |
| 1446 | 1446 | |
| 1447 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1447 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1448 | 1448 | DEFEND_TRY_MOVES(0, NULL); |
| 1449 | 1449 | |
| 1450 | 1450 | /* If the string is a single stone and a capture would give a ko, |
| … |
… |
|
| 1552 | 1552 | if (stackp <= backfill_depth) |
| 1553 | 1553 | special_rescue2_moves(str, libs, &moves); |
| 1554 | 1554 | |
| 1555 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1555 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1556 | 1556 | DEFEND_TRY_MOVES(0, &suggest_move); |
| 1557 | 1557 | |
| 1558 | 1558 | /* Look for backfilling moves. */ |
| … |
… |
|
| 1586 | 1586 | special_rescue4_moves(str, libs, &moves); |
| 1587 | 1587 | |
| 1588 | 1588 | /* Only order and test the new set of moves. */ |
| 1589 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1589 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1590 | 1590 | DEFEND_TRY_MOVES(0, &suggest_move); |
| 1591 | 1591 | |
| 1592 | 1592 | /* If we haven't found any useful moves in first batches, be more |
| … |
… |
|
| 1618 | 1618 | break_chain4_moves(str, &moves, be_aggressive); |
| 1619 | 1619 | |
| 1620 | 1620 | /* Only order and test the new set of moves. */ |
| 1621 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1621 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1622 | 1622 | DEFEND_TRY_MOVES(0, &suggest_move); |
| 1623 | 1623 | |
| 1624 | 1624 | RETURN_RESULT(savecode, savemove, move, "saved move"); |
| … |
… |
|
| 1680 | 1680 | if (stackp <= backfill2_depth) |
| 1681 | 1681 | hane_rescue_moves(str, libs, &moves); |
| 1682 | 1682 | |
| 1683 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1683 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1684 | 1684 | DEFEND_TRY_MOVES(1, &suggest_move); |
| 1685 | 1685 | |
| 1686 | 1686 | /* This looks a little too expensive. */ |
| … |
… |
|
| 1768 | 1768 | } |
| 1769 | 1769 | |
| 1770 | 1770 | /* Only order and test the new set of moves. */ |
| 1771 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1771 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1772 | 1772 | DEFEND_TRY_MOVES(1, &suggest_move); |
| 1773 | 1773 | |
| 1774 | 1774 | /* If nothing else works, we try playing a liberty of the |
| … |
… |
|
| 1783 | 1783 | break_chain3_moves(str, &moves, 0); |
| 1784 | 1784 | |
| 1785 | 1785 | /* Only order and test the new set of moves. */ |
| 1786 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1786 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1787 | 1787 | DEFEND_TRY_MOVES(1, &suggest_move); |
| 1788 | 1788 | |
| 1789 | 1789 | RETURN_RESULT(savecode, savemove, move, "saved move"); |
| … |
… |
|
| 1850 | 1850 | squeeze_moves(str, &moves); |
| 1851 | 1851 | } |
| 1852 | 1852 | |
| 1853 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1853 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1854 | 1854 | DEFEND_TRY_MOVES(1, &suggest_move); |
| 1855 | 1855 | |
| 1856 | 1856 | if (stackp <= depth) { |
| … |
… |
|
| 1859 | 1859 | bamboo_rescue_moves(str, liberties, libs, &moves); |
| 1860 | 1860 | } |
| 1861 | 1861 | |
| 1862 | | order_moves(str, &moves, color, read_function_name, *move); |
| | 1862 | order_moves(str, &moves, color, READ_FUNCTION_NAME, *move); |
| 1863 | 1863 | DEFEND_TRY_MOVES(1, &suggest_move); |
| 1864 | 1864 | |
| 1865 | 1865 | RETURN_RESULT(savecode, savemove, move, "saved move"); |
| … |
… |
|
| 2005 | 2005 | int other = OTHER_COLOR(color); |
| 2006 | 2006 | int newlibs[4]; |
| 2007 | 2007 | int liberties; |
| 2008 | | int newstr; |
| | 2008 | int astr_pos; |
| 2009 | 2009 | int k, r, s; |
| 2010 | 2010 | |
| 2011 | 2011 | for (r = 0; r < 2; r++) { |
| … |
… |
|
| 2017 | 2017 | continue; |
| 2018 | 2018 | |
| 2019 | 2019 | for (k = 0; k < 4; k++) { |
| 2020 | | if (board[alib + delta[k]] == color |
| 2021 | | && !same_string(alib + delta[k], str)) { |
| 2022 | | newstr = alib + delta[k]; |
| 2023 | | liberties = findlib(newstr, 4, newlibs); |
| | 2020 | astr_pos = alib + delta[k]; |
| | 2021 | if (board[astr_pos] == color |
| | 2022 | && !same_string(astr_pos, str)) { |
| | 2023 | liberties = findlib(astr_pos, 4, newlibs); |
| 2024 | 2024 | |
| 2025 | 2025 | for (s = 0; s < liberties && s < 4; s++) { |
| 2026 | 2026 | if (!is_self_atari(newlibs[s], color)) |
| 2027 | 2027 | ADD_CANDIDATE_MOVE(newlibs[s], 0, *moves, "special_rescue2"); |
| 2028 | 2028 | } |
| 2029 | | break_chain_moves(newstr, moves); |
| 2030 | | break_chain2_efficient_moves(newstr, moves); |
| 2031 | | edge_clamp_moves(newstr, moves); |
| | 2029 | break_chain_moves(astr_pos, moves); |
| | 2030 | break_chain2_efficient_moves(astr_pos, moves); |
| | 2031 | edge_clamp_moves(astr_pos, moves); |
| 2032 | 2032 | } |
| 2033 | 2033 | } |
| 2034 | 2034 | } |
| … |
… |
|
| 2284 | 2284 | |
| 2285 | 2285 | liberties2 = findlib(bpos, 4, libs2); |
| 2286 | 2286 | for (s = 0; s < liberties2; s++) |
| 2287 | | if (!liberty_of_string(libs2[s], str) |
| | 2287 | if (!liberty_of_string2(libs2[s], str) |
| 2288 | 2288 | && !is_self_atari(libs2[s], color)) |
| 2289 | 2289 | ADD_CANDIDATE_MOVE(libs2[s], 0, *moves, "special_rescue5-A"); |
| 2290 | 2290 | |
| … |
… |
|
| 2469 | 2469 | int alibs[2]; |
| 2470 | 2470 | int alib = accuratelib(apos, other, 2, alibs); |
| 2471 | 2471 | |
| 2472 | | if (liberty_of_string(apos, str)) |
| | 2472 | if (liberty_of_string2(apos, str)) |
| 2473 | 2473 | continue; |
| 2474 | 2474 | |
| 2475 | 2475 | if (alib >= 2) |
| … |
… |
|
| 2521 | 2521 | continue; |
| 2522 | 2522 | |
| 2523 | 2523 | for (r = 0; r < num_libs2; r++) |
| 2524 | | if (!liberty_of_string(libs2[r], str)) { |
| | 2524 | if (!liberty_of_string2(libs2[r], str)) { |
| 2525 | 2525 | potential_move = libs2[r]; |
| 2526 | 2526 | break; |
| 2527 | 2527 | } |
| … |
… |
|
| 2542 | 2542 | previous_liberty = potential_move; |
| 2543 | 2543 | potential_move = libs2[0]; |
| 2544 | 2544 | } |
| 2545 | | if (liberty_of_string(potential_move, str)) { |
| | 2545 | if (liberty_of_string2(potential_move, str)) { |
| 2546 | 2546 | potential_move = NO_MOVE; |
| 2547 | 2547 | break; |
| 2548 | 2548 | } |
| … |
… |
|
| 2642 | 2642 | if (board[cpos] != color || !same_string(cpos, str)) |
| 2643 | 2643 | continue; |
| 2644 | 2644 | |
| 2645 | | if (board[dpos] != EMPTY || !liberty_of_string(dpos, apos)) |
| | 2645 | if (board[dpos] != EMPTY || !liberty_of_string2(dpos, apos)) |
| 2646 | 2646 | continue; |
| 2647 | 2647 | |
| 2648 | 2648 | epos = dpos + up; |
| 2649 | 2649 | |
| 2650 | | if (board[epos] != EMPTY || !liberty_of_string(epos, apos)) |
| | 2650 | if (board[epos] != EMPTY || !liberty_of_string2(epos, apos)) |
| 2651 | 2651 | continue; |
| 2652 | 2652 | |
| 2653 | 2653 | if (approxlib(dpos, color, 3, NULL) < 3) |
| … |
… |
|
| 3112 | 3112 | /* If stackp > depth and any boundary chain is in atari, assume safe. |
| 3113 | 3113 | * However, if the captured chain is only of size 1, there can still |
| 3114 | 3114 | * be a working ladder, so continue if that is the case. |
| 3115 | | * Also if the string in atari shares its liberty with the |
| 3116 | | * attacked string, drawing it out may enable the ladder to |
| 3117 | | * continue. |
| | 3115 | * Also if the string in atari shares its liberty with the |
| | 3116 | * attacked string, drawing it out may enable the ladder to |
| | 3117 | * continue. |
| 3118 | 3118 | */ |
| 3119 | 3119 | if (stackp > depth |
| 3120 | 3120 | && countstones(adjs[r]) > 1 |
| … |
… |
|
| 3190 | 3190 | adj = chainlinks2(str, adjs, 2); |
| 3191 | 3191 | for (r = 0; r < adj; r++) { |
| 3192 | 3192 | int apos = adjs[r]; |
| 3193 | | if (liberty_of_string(libs[0], apos) |
| 3194 | | && liberty_of_string(libs[1], apos)) |
| | 3193 | if (liberty_of_string2(libs[0], apos) |
| | 3194 | && liberty_of_string2(libs[1], apos)) |
| 3195 | 3195 | break_chain_moves(apos, &moves); |
| 3196 | 3196 | } |
| 3197 | 3197 | |
| … |
… |
|
| 3230 | 3230 | abort(); |
| 3231 | 3231 | } /* switch (pass) */ |
| 3232 | 3232 | |
| 3233 | | order_moves(str, &moves, other, read_function_name, *move); |
| | 3233 | order_moves(str, &moves, other, READ_FUNCTION_NAME, *move); |
| 3234 | 3234 | ATTACK_TRY_MOVES(0, &suggest_move); |
| 3235 | 3235 | } |
| 3236 | 3236 | |
| … |
… |
|
| 3373 | 3373 | abort(); |
| 3374 | 3374 | } |
| 3375 | 3375 | |
| 3376 | | order_moves(str, &moves, other, read_function_name, *move); |
| | 3376 | order_moves(str, &moves, other, READ_FUNCTION_NAME, *move); |
| 3377 | 3377 | ATTACK_TRY_MOVES(1, &suggest_move); |
| 3378 | 3378 | } /* for (pass... */ |
| 3379 | 3379 | |
| … |
… |
|
| 3467 | 3467 | abort(); |
| 3468 | 3468 | } |
| 3469 | 3469 | |
| 3470 | | order_moves(str, &moves, other, read_function_name, *move); |
| | 3470 | order_moves(str, &moves, other, READ_FUNCTION_NAME, *move); |
| 3471 | 3471 | ATTACK_TRY_MOVES(1, &suggest_move); |
| 3472 | 3472 | } /* for (pass = ... */ |
| 3473 | 3473 | |
| … |
… |
|
| 3681 | 3681 | * chain links. |
| 3682 | 3682 | */ |
| 3683 | 3683 | for (s = 0; s < adj; s++) |
| 3684 | | if (liberty_of_string(apos, adjs[s])) { |
| | 3684 | if (liberty_of_string2(apos, adjs[s])) { |
| 3685 | 3685 | bpos = adjs[s]; |
| 3686 | 3686 | break; |
| 3687 | 3687 | } |
| … |
… |
|
| 3773 | 3773 | for (r = 0; r < adj; r++) { |
| 3774 | 3774 | findlib(adjs[r], 2, libs); |
| 3775 | 3775 | for (k = 0; k < 2; k++) { |
| 3776 | | if (!liberty_of_string(libs[k], str) |
| | 3776 | if (!liberty_of_string2(libs[k], str) |
| 3777 | 3777 | && ((ON_BOARD1(SOUTH(libs[k])) |
| 3778 | 3778 | && liberty_of_string(SOUTH(libs[k]), str)) |
| 3779 | 3779 | || (ON_BOARD1(WEST(libs[k])) |
| … |
… |
|
| 4019 | 4019 | for (k = 0; k < 4; k++) { |
| 4020 | 4020 | int l; |
| 4021 | 4021 | int up = delta[k]; |
| | 4022 | int up_apos; |
| 4022 | 4023 | |
| 4023 | 4024 | if (ON_BOARD(apos - up)) |
| 4024 | 4025 | continue; |
| 4025 | | if (board[apos + up] != color || !same_string(apos + up, str)) |
| | 4026 | up_apos = apos + up; |
| | 4027 | if (board[up_apos] != color || !same_string(up_apos, str)) |
| 4026 | 4028 | return; |
| 4027 | 4029 | |
| 4028 | 4030 | for (l = 0; l < 2; l++) { |
| … |
… |
|
| 4036 | 4038 | right = -right; |
| 4037 | 4039 | |
| 4038 | 4040 | cpos = apos + right; |
| 4039 | | dpos = apos + right + up; |
| | 4041 | dpos = up_apos + right; |
| 4040 | 4042 | epos = cpos + right; |
| 4041 | 4043 | fpos = dpos + right; |
| 4042 | 4044 | |
| … |
… |
|
| 4159 | 4161 | int min_liberties) |
| 4160 | 4162 | { |
| 4161 | 4163 | int r, s, t; |
| 4162 | | int color = OTHER_COLOR(board[str]); |
| | 4164 | int color = board[str]; |
| | 4165 | int other = OTHER_COLOR(color); |
| 4163 | 4166 | int xpos; |
| 4164 | 4167 | int adj; |
| 4165 | 4168 | int adj2; |
| … |
… |
|
| 4178 | 4181 | findlib(adjs[r], 2, libs); |
| 4179 | 4182 | for (t = 0; t < 2; t++) { |
| 4180 | 4183 | xpos = libs[t]; |
| 4181 | | if (approxlib(xpos, color, min_liberties, NULL) |
| | 4184 | if (approxlib(xpos, other, min_liberties, NULL) |
| 4182 | 4185 | + neighbor_of_string(xpos, str) >= min_liberties) |
| 4183 | 4186 | ADD_CANDIDATE_MOVE(xpos, 0, *moves, "defend_secondary_chain2-A"); |
| 4184 | 4187 | } |
| … |
… |
|
| 4187 | 4190 | adj2 = chainlinks2(adjs[r], adjs2, 1); |
| 4188 | 4191 | for (s = 0; s < adj2; s++) { |
| 4189 | 4192 | findlib(adjs2[s], 1, &xpos); |
| 4190 | | if (!is_self_atari(xpos, color)) |
| | 4193 | if (!is_self_atari(xpos, other)) |
| 4191 | 4194 | ADD_CANDIDATE_MOVE(xpos, 0, *moves, "defend_secondary_chain2-B"); |
| 4192 | 4195 | } |
| 4193 | 4196 | |
| … |
… |
|
| 4197 | 4200 | findlib(adjs2[s], 2, libs); |
| 4198 | 4201 | for (t = 0; t < 2; t++) { |
| 4199 | 4202 | /* Only atari if target has no easy escape with his other liberty. */ |
| 4200 | | if (approxlib(libs[1-t], OTHER_COLOR(color), 3, NULL) < 3 |
| 4201 | | && !is_self_atari(libs[t], color)) { |
| | 4203 | if (approxlib(libs[1-t], color, 3, NULL) < 3 |
| | 4204 | && !is_self_atari(libs[t], other)) { |
| 4202 | 4205 | ADD_CANDIDATE_MOVE(libs[t], 0, *moves, "defend_secondary_chain2-C"); |
| 4203 | 4206 | } |
| 4204 | 4207 | } |
| … |
… |
|
| 4365 | 4368 | if (!defend_secondary_chain1_moves(adjs[r], moves, 2)) |
| 4366 | 4369 | defend_secondary_chain2_moves(adjs[r], moves, 2); |
| 4367 | 4370 | } |
| 4368 | | } |
| | 4371 | } |
| 4369 | 4372 | |
| 4370 | 4373 | if (unsafe[0] && unsafe[1] |
| 4371 | 4374 | && (stackp <= backfill2_depth || have_common_lib(str, apos, NULL))) { |
| … |
… |
|
| 4823 | 4826 | |
| 4824 | 4827 | break_chain_moves(str, &moves); |
| 4825 | 4828 | set_up_snapback_moves(str, lib, &moves); |
| 4826 | | order_moves(str, &moves, color, read_function_name, NO_MOVE); |
| | 4829 | order_moves(str, &moves, color, READ_FUNCTION_NAME, NO_MOVE); |
| 4827 | 4830 | |
| 4828 | 4831 | for (k = 0; k < moves.num; k++) { |
| 4829 | 4832 | int ko_capture; |
| … |
… |
|
| 4869 | 4872 | * better. |
| 4870 | 4873 | */ |
| 4871 | 4874 | UPDATE_SAVED_KO_RESULT(savecode, savemove, acode, xpos); |
| 4872 | | } |
| | 4875 | } |
| 4873 | 4876 | else |
| 4874 | 4877 | popgo(); |
| 4875 | | } |
| | 4878 | } |
| 4876 | 4879 | else { |
| 4877 | 4880 | int ko_pos; |
| 4878 | 4881 | if (stackp <= ko_depth |
| … |
… |
|
| 5626 | 5629 | if (approxlib(libs[1], color, 4, NULL) <= 3) |
| 5627 | 5630 | ADD_CANDIDATE_MOVE(libs[0], 0, moves, "simple_ladder"); |
| 5628 | 5631 | |
| 5629 | | order_moves(str, &moves, other, read_function_name, NO_MOVE); |
| | 5632 | order_moves(str, &moves, other, READ_FUNCTION_NAME, NO_MOVE); |
| 5630 | 5633 | |
| 5631 | 5634 | for (k = 0; k < moves.num; k++) { |
| 5632 | 5635 | int ko_move; |
| … |
… |
|
| 5688 | 5691 | moves.num_tried = 0; |
| 5689 | 5692 | |
| 5690 | 5693 | break_chain_moves(str, &moves); |
| 5691 | | order_moves(str, &moves, color, read_function_name, NO_MOVE); |
| | 5694 | order_moves(str, &moves, color, READ_FUNCTION_NAME, NO_MOVE); |
| 5692 | 5695 | |
| 5693 | 5696 | for (k = 0; k < moves.num; k++) { |
| 5694 | 5697 | int ko_move; |
-
RCS file: /sources/gnugo/gnugo/engine/showbord.c,v
retrieving revision 1.29
diff -u -r1.29 showbord.c
|
|
|
|
| 343 | 343 | } |
| 344 | 344 | |
| 345 | 345 | |
| 346 | | #ifndef HAVE_VARIADIC_DEFINE |
| | 346 | #if !defined(HAVE_VARIADIC_DEFINE) || defined(GG_TURN_OFF_DEBUGS) |
| 347 | 347 | |
| 348 | 348 | /* See gnugo.h for related TRACE family macro definitions */ |
| 349 | 349 | |
-
RCS file: /sources/gnugo/gnugo/engine/unconditional.c,v
retrieving revision 1.5
diff -u -r1.5 unconditional.c
|
|
|
|
| 343 | 343 | |
| 344 | 344 | findstones(pos, 2, stones); |
| 345 | 345 | for (k = 0; k < 2 && isolated; k++) { |
| 346 | | for (r = 0; r < 8 && isolated; r++) { |
| | 346 | for (r = 0; r < 8; r++) { |
| 347 | 347 | pos2 = stones[k] + delta[r]; |
| 348 | 348 | if (!ON_BOARD(pos2) |
| 349 | 349 | || (board[pos2] == color |
| 350 | 350 | && !same_string(pos, pos2))) |
| | 351 | { |
| 351 | 352 | isolated = 0; |
| | 353 | break; |
| | 354 | } |
| 352 | 355 | } |
| 353 | 356 | } |
| 354 | 357 | |
| … |
… |
|
| 457 | 460 | locally_played_moves--; |
| 458 | 461 | } |
| 459 | 462 | } |
| 460 | | } |
| | 463 | } |
| 461 | 464 | if (countstones(pos) > 2) |
| 462 | 465 | break; |
| 463 | | } |
| | 466 | } |
| 464 | 467 | } |
| 465 | 468 | |
| 466 | 469 | /* Capture the strings involved in potential sekis. */ |
-
RCS file: /sources/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.115
diff -u -r1.115 utils.c
|
|
|
|
| 731 | 731 | void |
| 732 | 732 | set_depth_values(int level, int report_levels) |
| 733 | 733 | { |
| 734 | | static int node_limits[] = {500, 500, 450, 400, 400, 325, 275, |
| 735 | | 200, 150, 100, 75, 50}; |
| | 734 | const int node_limits[] = {500, 500, 450, 400, 400, 325, 275, |
| | 735 | 200, 150, 100, 75, 50}; |
| 736 | 736 | int depth_level; |
| 737 | 737 | |
| 738 | 738 | /* |
| … |
… |
|
| 858 | 858 | |
| 859 | 859 | depth_offset = 0; |
| 860 | 860 | |
| | 861 | #ifndef GG_TURN_OFF_TRACES |
| 861 | 862 | if (report_levels) { |
| 862 | 863 | fprintf(stderr, "at level %d:\n\n\ |
| 863 | 864 | depth: %d\n\ |
| … |
… |
|
| 889 | 890 | connect_depth2, connection_node_limit, breakin_depth, |
| 890 | 891 | breakin_node_limit); |
| 891 | 892 | } |
| | 893 | #else |
| | 894 | UNUSED(report_levels); |
| | 895 | #endif |
| 892 | 896 | } |
| 893 | 897 | |
| 894 | 898 | |
-
RCS file: /sources/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.170
diff -u -r1.170 value_moves.c
|
|
|
|
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | for (k = 0; k < strings; k++) { |
| | 72 | int count_lib; |
| 72 | 73 | if (worm[ss[k]].invincible) |
| 73 | 74 | continue; |
| | 75 | count_lib = countlib(ss[k]); |
| 74 | 76 | if (board[ss[k]] == color) { |
| 75 | 77 | int newlibs = approxlib(pos, color, MAXLIBS, NULL); |
| 76 | 78 | own_strings++; |
| 77 | | if (newlibs >= countlib(ss[k])) { |
| 78 | | if (countlib(ss[k]) <= 4) |
| | 79 | if (newlibs >= count_lib) { |
| | 80 | if (count_lib <= 4) |
| 79 | 81 | fewlibs++; |
| 80 | | if (countlib(ss[k]) <= 2) |
| | 82 | if (count_lib <= 2) |
| 81 | 83 | fewlibs++; |
| 82 | 84 | } |
| 83 | 85 | } |
| 84 | 86 | else { |
| 85 | | if (countlib(ss[k]) <= 2) |
| | 87 | if (count_lib <= 2) |
| 86 | 88 | fewlibs++; |
| 87 | | if (countlib(ss[k]) <= 1 && to_move) { |
| | 89 | if (count_lib <= 1 && to_move) { |
| 88 | 90 | int dummy[MAXCHAIN]; |
| 89 | 91 | fewlibs++; |
| 90 | 92 | fewlibs += chainlinks2(ss[k], dummy, 1); |
| … |
… |
|
| 765 | 767 | int potential_semeai_move_found = 0; |
| 766 | 768 | int other_move_reason_found = 0; |
| 767 | 769 | |
| 768 | | if (!ON_BOARD1(pos)) |
| | 770 | if (!ON_BOARD(pos)) |
| 769 | 771 | continue; |
| 770 | 772 | for (k = 0; k < MAX_REASONS; k++) { |
| 771 | 773 | < |