diff -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
|
old
|
new
|
|
| 2 | 2 | * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * |
| 3 | 3 | * http://www.gnu.org/software/gnugo/ for more information. * |
| 4 | 4 | * * |
| 5 | | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006 * |
| | 5 | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * |
| 6 | 6 | * by the Free Software Foundation. * |
| 7 | 7 | * * |
| 8 | 8 | * This program is free software; you can redistribute it and/or * |
| … |
… |
|
| 1778 | 1778 | liberties = string[str_nr].liberties; |
| 1779 | 1779 | to_copy = maxlib > liberties ? liberties : maxlib; |
| 1780 | 1780 | |
| 1781 | | if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES) { |
| | 1781 | if (to_copy <= MAX_LIBERTIES) { |
| 1782 | 1782 | /* The easy case, it suffices to copy liberty locations from the |
| 1783 | 1783 | * incrementally updated list. |
| 1784 | 1784 | */ |
diff -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
|
old
|
new
|
|
| 2 | 2 | * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * |
| 3 | 3 | * http://www.gnu.org/software/gnugo/ for more information. * |
| 4 | 4 | * * |
| 5 | | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006 * |
| | 5 | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * |
| 6 | 6 | * by the Free Software Foundation. * |
| 7 | 7 | * * |
| 8 | 8 | * This program is free software; you can redistribute it and/or * |
| … |
… |
|
| 41 | 41 | { |
| 42 | 42 | int other = OTHER_COLOR(color); |
| 43 | 43 | int something_captured = 1; /* To get into the first turn of the loop. */ |
| 44 | | int string_found = 0; |
| | 44 | int invincible_found = 0; |
| 45 | 45 | int moves_played = 0; |
| 46 | 46 | int save_moves; |
| 47 | 47 | int libs[MAXLIBS]; |
| … |
… |
|
| 53 | 53 | /* Nothing captured so far in this turn of the loop. */ |
| 54 | 54 | something_captured = 0; |
| 55 | 55 | |
| 56 | | /* Is there something left to try to capture? */ |
| 57 | | string_found = 0; |
| | 56 | /* If we found any invincible string in this turn of the loop. */ |
| | 57 | invincible_found = 0; |
| 58 | 58 | |
| 59 | 59 | /* Visit all friendly strings on the board. */ |
| 60 | 60 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 61 | | if (board[pos] != color || find_origin(pos) != pos) |
| | 61 | if (board[pos] != color || find_origin(pos) != pos |
| | 62 | || exceptions[pos]) |
| 62 | 63 | continue; |
| 63 | 64 | |
| 64 | | if (exceptions && exceptions[pos]) |
| 65 | | continue; |
| 66 | | |
| 67 | | string_found = 1; |
| 68 | | |
| 69 | 65 | /* Try to capture the string at pos. */ |
| 70 | 66 | liberties = findlib(pos, MAXLIBS, libs); |
| 71 | 67 | save_moves = moves_played; |
| 72 | | for (k = 0; k < liberties; k++) { |
| 73 | | if (trymove(libs[k], other, "unconditional_life", pos)) |
| 74 | | moves_played++; |
| 75 | | } |
| | 68 | for (k = 0; k < liberties; k++) |
| | 69 | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| 76 | 70 | |
| 77 | 71 | /* Successful if already captured or a single liberty remains. |
| 78 | 72 | * Otherwise we must rewind and take back the last batch of moves. |
| … |
… |
|
| 96 | 90 | moves_played++; |
| 97 | 91 | something_captured = 1; |
| 98 | 92 | } |
| 99 | | else |
| | 93 | else { |
| | 94 | invincible_found = 1; |
| | 95 | |
| 100 | 96 | while (moves_played > save_moves) { |
| 101 | 97 | popgo(); |
| 102 | 98 | moves_played--; |
| 103 | 99 | } |
| | 100 | } |
| 104 | 101 | } |
| 105 | 102 | } |
| 106 | 103 | |
| 107 | 104 | if (none_invincible) |
| 108 | | *none_invincible = !string_found; |
| | 105 | *none_invincible = !invincible_found; |
| 109 | 106 | |
| 110 | 107 | return moves_played; |
| 111 | 108 | } |
| … |
… |
|
| 148 | 145 | * 4. Play an opponent stone anywhere it can get one empty |
| 149 | 146 | * neighbor. (I.e. reduce two space eyes to one space eyes.) |
| 150 | 147 | * |
| 151 | | * Remaining opponent strings in atari and remaining liberties of the |
| 152 | | * unconditionally alive strings constitute the unconditional |
| 153 | | * territory. |
| | 148 | * Remaining opponent strings in atari (and its only liberty) and |
| | 149 | * remaining liberties of the unconditionally alive strings constitute |
| | 150 | * the unconditional territory. |
| 154 | 151 | * |
| 155 | 152 | * Opponent strings from the initial position placed on |
| 156 | 153 | * unconditional territory are unconditionally dead. |
| 157 | 154 | * |
| 158 | 155 | * - - - - - - - |
| 159 | 156 | * |
| | 157 | * Step 2 is done, because of such position (we have to extend a stone |
| | 158 | * in atari before reducing an eyespace): |
| | 159 | * |
| | 160 | * OOXOO |
| | 161 | * OX.XO |
| | 162 | * OX.XO |
| | 163 | * OXXXO |
| | 164 | * OX.XO |
| | 165 | * OXXXO |
| | 166 | * OOOOO |
| | 167 | * |
| | 168 | * - - - - - - - |
| | 169 | * |
| 160 | 170 | * The deficiency with this algorithm is that a certain class of sekis |
| 161 | 171 | * are considered as dead, e.g. this position: |
| 162 | 172 | * |
| … |
… |
|
| 183 | 193 | * 1. Run algorithm 1. |
| 184 | 194 | * 2. Return to the original position. |
| 185 | 195 | * 3. Capture all capturable O strings which according to algorithm 1 |
| 186 | | * do not belong to unconditional territory. |
| | 196 | * do belong to unconditional territory. |
| 187 | 197 | * 4. Play opponent stones on all liberties of the unconditionally |
| 188 | 198 | * alive strings except where illegal. (That the move order may |
| 189 | 199 | * determine exactly which liberties can be played legally is not |
| … |
… |
|
| 197 | 207 | * 9. Play an opponent stone anywhere it can get one empty |
| 198 | 208 | * neighbor. (I.e. reduce two space eyes to one space eyes.) |
| 199 | 209 | * |
| 200 | | * Remaining opponent strings in atari and remaining liberties of the |
| 201 | | * unconditionally alive strings constitute the unconditional |
| 202 | | * territory. |
| | 210 | * Remaining opponent strings in atari (and its only liberty) and |
| | 211 | * remaining liberties of the unconditionally alive strings constitute |
| | 212 | * the unconditional territory. |
| 203 | 213 | * |
| 204 | 214 | * Opponent strings from the initial position placed on |
| 205 | 215 | * unconditional territory are unconditionally dead. |
| … |
… |
|
| 263 | 273 | * .OXXXOO |
| 264 | 274 | * .OOOOO. |
| 265 | 275 | * |
| 266 | | * belong to different strings for the dead groups and to the same |
| 267 | | * string for the seki groups. |
| | 276 | * which belong to different strings for the dead groups and to the |
| | 277 | * same string for the seki groups. |
| 268 | 278 | * |
| 269 | 279 | * The trick to avoid misclassifying areas where the opponent can form |
| 270 | 280 | * a seki group but not an invincible group as unconditional territory |
| … |
… |
|
| 296 | 306 | * 10. Play an opponent stone anywhere it can get one empty |
| 297 | 307 | * neighbor. (I.e. reduce two space eyes to one space eyes.) |
| 298 | 308 | * |
| 299 | | * Remaining opponent strings in atari and remaining liberties of the |
| 300 | | * unconditionally alive strings constitute the unconditional |
| 301 | | * territory. |
| | 309 | * Remaining opponent strings in atari (and its only liberty) and |
| | 310 | * remaining liberties of the unconditionally alive strings constitute |
| | 311 | * the unconditional territory. |
| 302 | 312 | * |
| 303 | 313 | * Opponent strings from the initial position placed on |
| 304 | 314 | * unconditional territory are unconditionally dead. |
| … |
… |
|
| 313 | 323 | void |
| 314 | 324 | unconditional_life(int unconditional_territory[BOARDMAX], int color) |
| 315 | 325 | { |
| 316 | | int found_one; |
| 317 | 326 | int other = OTHER_COLOR(color); |
| 318 | 327 | int libs[MAXLIBS]; |
| 319 | 328 | int liberties; |
| … |
… |
|
| 335 | 344 | int isolated = 1; |
| 336 | 345 | int stones[2]; |
| 337 | 346 | int pos2; |
| | 347 | int checked_stone; |
| 338 | 348 | |
| 339 | 349 | if (board[pos] != color |
| 340 | 350 | || find_origin(pos) != pos |
| … |
… |
|
| 343 | 353 | |
| 344 | 354 | findstones(pos, 2, stones); |
| 345 | 355 | for (k = 0; k < 2 && isolated; k++) { |
| | 356 | checked_stone = stones[k]; |
| 346 | 357 | for (r = 0; r < 8; r++) { |
| 347 | | pos2 = stones[k] + delta[r]; |
| | 358 | pos2 = checked_stone + delta[r]; |
| 348 | 359 | if (!ON_BOARD(pos2) |
| 349 | 360 | || (board[pos2] == color |
| 350 | 361 | && !same_string(pos, pos2))) |
| … |
… |
|
| 384 | 395 | * alive strings except where illegal. |
| 385 | 396 | */ |
| 386 | 397 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 387 | | if (board[pos] != color || potential_sekis[pos] || find_origin(pos) != pos) |
| | 398 | if (board[pos] != color || find_origin(pos) != pos || potential_sekis[pos]) |
| 388 | 399 | continue; |
| 389 | 400 | |
| 390 | 401 | /* Play as many liberties as we can. */ |
| 391 | 402 | liberties = findlib(pos, MAXLIBS, libs); |
| 392 | 403 | for (k = 0; k < liberties; k++) { |
| 393 | | if (trymove(libs[k], other, "unconditional_life", pos)) |
| 394 | | moves_played++; |
| | 404 | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| 395 | 405 | } |
| 396 | 406 | } |
| 397 | 407 | |
| 398 | 408 | /* 2. Recursively extend opponent strings in atari, except where this |
| 399 | 409 | * would be suicide. |
| 400 | 410 | */ |
| 401 | | found_one = 1; |
| 402 | | while (found_one) { |
| 403 | | /* Nothing found so far in this turn of the loop. */ |
| 404 | | found_one = 0; |
| 405 | | |
| 406 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 407 | | if (board[pos] != other || countlib(pos) > 1) |
| 408 | | continue; |
| | 411 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 412 | if (board[pos] != other) |
| | 413 | continue; |
| 409 | 414 | |
| 410 | | /* Try to extend the string at (m, n). */ |
| | 415 | /* Try to extend the string. */ |
| | 416 | while (countlib(pos) == 1) { |
| 411 | 417 | findlib(pos, 1, libs); |
| 412 | | if (trymove(libs[0], other, "unconditional_life", pos)) { |
| | 418 | if (trymove(libs[0], other, "unconditional_life", pos)) |
| 413 | 419 | moves_played++; |
| 414 | | found_one = 1; |
| 415 | | } |
| | 420 | else |
| | 421 | break; |
| 416 | 422 | } |
| 417 | 423 | } |
| 418 | 424 | |
| … |
… |
|
| 422 | 428 | || board[pos] == EMPTY |
| 423 | 429 | || find_origin(pos) != pos) |
| 424 | 430 | continue; |
| | 431 | |
| | 432 | /* Try different rotations. */ |
| 425 | 433 | for (r = 0; r < 4; r++) { |
| 426 | 434 | int up = delta[r]; |
| 427 | 435 | int right = delta[(r + 1) % 4]; |
| … |
… |
|
| 432 | 440 | continue; |
| 433 | 441 | for (k = 0; k < 2; k++) { |
| 434 | 442 | if (k == 1) |
| 435 | | right = -right; |
| | 443 | right = -right; /* Try a mirror reflection. */ |
| 436 | 444 | if (board[pos + right] != EMPTY || board[pos + up - right] != EMPTY) |
| 437 | 445 | continue; |
| 438 | | if (board[pos - right] == EMPTY |
| 439 | | && trymove(pos - right, other, "unconditional_life", pos)) |
| 440 | | locally_played_moves++; |
| 441 | | if (board[pos + up + right] == EMPTY |
| 442 | | && trymove(pos + up + right, other, "unconditional_life", pos)) |
| 443 | | locally_played_moves++; |
| | 446 | if (board[pos - right] == EMPTY) |
| | 447 | locally_played_moves += trymove(pos - right, other, |
| | 448 | "unconditional_life", pos); |
| | 449 | if (board[pos + up + right] == EMPTY) |
| | 450 | locally_played_moves += trymove(pos + up + right, other, |
| | 451 | "unconditional_life", pos); |
| 444 | 452 | if (board[pos - right] == other && board[pos + up + right] == other |
| 445 | 453 | && same_string(pos - right, pos + up + right)) { |
| 446 | 454 | /* This is a critical seki. Extend the string with one stone |
| … |
… |
|
| 450 | 458 | popgo(); |
| 451 | 459 | locally_played_moves--; |
| 452 | 460 | } |
| 453 | | trymove(pos - up, color, "unconditional_life", pos); |
| 454 | | moves_played++; |
| | 461 | moves_played += trymove(pos - up, color, "unconditional_life", pos); |
| 455 | 462 | break; |
| 456 | 463 | } |
| 457 | 464 | else { |
| … |
… |
|
| 472 | 479 | continue; |
| 473 | 480 | /* Play as many liberties as we can. */ |
| 474 | 481 | liberties = findlib(pos, MAXLIBS, libs); |
| 475 | | for (k = 0; k < liberties; k++) { |
| 476 | | if (trymove(libs[k], other, "unconditional_life", pos)) |
| 477 | | moves_played++; |
| 478 | | } |
| | 482 | for (k = 0; k < liberties; k++) |
| | 483 | moves_played += trymove(libs[k], other, "unconditional_life", pos); |
| 479 | 484 | } |
| 480 | 485 | |
| 481 | | |
| | 486 | /* All opponent strings liberties are now inside opponent territory |
| | 487 | (due to step 4.). If any string has 3 or more liberties, it is alive |
| | 488 | (2 eyes can be made). If a string has 1 liberty it must be in atari, so |
| | 489 | is dead (because we tried to extend strings in atari in step 5.). We |
| | 490 | only have to check strings, which have 2 liberties. This operations |
| | 491 | are made instead 9. and 10. step of the algorithm. */ |
| 482 | 492 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 483 | 493 | int apos; |
| 484 | 494 | int bpos; |
| … |
… |
|
| 493 | 503 | continue; |
| 494 | 504 | |
| 495 | 505 | /* Only two liberties and these are adjacent. Play one. We want |
| 496 | | * to maximize the number of open liberties. In this particular |
| 497 | | * situation we can count this with approxlib for the opposite |
| 498 | | * color. If the number of open liberties is the same, we |
| 499 | | * maximize the total number of obtained liberties. |
| 500 | | * Two relevant positions: |
| | 506 | * to maximize the number of neighboring liberties (to split an |
| | 507 | * eyespace). In this particular situation we can count this with |
| | 508 | * approxlib for the opposite color. If the number of neighboring |
| | 509 | * liberties is the same, we maximize the total number of obtained |
| | 510 | * liberties. Two relevant positions (we want to make 2 eyes for |
| | 511 | * these O groups): |
| 501 | 512 | * |
| 502 | 513 | * |XXX. |
| 503 | 514 | * |OOXX |XXXXXXX |
| … |
… |
|
| 510 | 521 | alib = approxlib(apos, other, 4, NULL); |
| 511 | 522 | blib = approxlib(bpos, other, 4, NULL); |
| 512 | 523 | |
| 513 | | if (aopen > bopen || (aopen == bopen && alib >= blib)) { |
| 514 | | trymove(apos, other, "unconditional_life", pos); |
| 515 | | moves_played++; |
| 516 | | } |
| 517 | | else { |
| 518 | | trymove(bpos, other, "unconditional_life", pos); |
| 519 | | moves_played++; |
| 520 | | } |
| | 524 | if (aopen > bopen || (aopen == bopen && alib >= blib)) |
| | 525 | moves_played += trymove(apos, other, "unconditional_life", pos); |
| | 526 | else |
| | 527 | moves_played += trymove(bpos, other, "unconditional_life", pos); |
| 521 | 528 | } |
| 522 | 529 | |
| 523 | 530 | /* Identify unconditionally alive stones and unconditional territory. */ |
| … |
… |
|
| 532 | 539 | } |
| 533 | 540 | else if (board[pos] == other && countlib(pos) == 1) { |
| 534 | 541 | unconditional_territory[pos] = 2; |
| 535 | | findlib(pos, 1, libs); |
| 536 | | unconditional_territory[libs[0]] = 2; |
| | 542 | if (find_origin(pos) == pos) { |
| | 543 | findlib(pos, 1, libs); |
| | 544 | unconditional_territory[libs[0]] = 2; |
| | 545 | } |
| 537 | 546 | } |
| 538 | 547 | } |
| 539 | 548 | |
diff -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
|
old
|
new
|
|
| 2 | 2 | * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * |
| 3 | 3 | * http://www.gnu.org/software/gnugo/ for more information. * |
| 4 | 4 | * * |
| 5 | | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006 * |
| | 5 | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 * |
| 6 | 6 | * by the Free Software Foundation. * |
| 7 | 7 | * * |
| 8 | 8 | * This program is free software; you can redistribute it and/or * |
| … |
… |
|
| 712 | 712 | |
| 713 | 713 | for (color = WHITE; color <= BLACK; color++) { |
| 714 | 714 | unconditional_life(unconditional_territory, color); |
| | 715 | gg_assert(stackp == 0); |
| 715 | 716 | |
| 716 | 717 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 717 | 718 | if (!ON_BOARD(pos) || !unconditional_territory[pos]) |
| … |
… |
|
| 732 | 733 | worm[pos].unconditional_status = DEAD; |
| 733 | 734 | } |
| 734 | 735 | } |
| 735 | | gg_assert(stackp == 0); |
| 736 | 736 | } |
| 737 | 737 | |
| 738 | 738 | /* |