RCS file: /sources/gnugo/gnugo/engine/influence.c,v
retrieving revision 1.118
diff -u -r1.118 influence.c
|
|
|
|
| 446 | 446 | memcpy(q->safe, safe_stones, BOARDMAX * sizeof(*safe_stones)); |
| 447 | 447 | q->captured = black_captured - white_captured; |
| 448 | 448 | |
| 449 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 450 | | if (ON_BOARD(ii)) { |
| | 449 | scan_board(ii, |
| 451 | 450 | /* Initialize. */ |
| 452 | 451 | q->white_influence[ii] = 0.0; |
| 453 | 452 | q->black_influence[ii] = 0.0; |
| … |
… |
|
| 490 | 489 | * in our private copy here. |
| 491 | 490 | */ |
| 492 | 491 | q->safe[ii] = 0; |
| 493 | | } |
| | 492 | ) |
| 494 | 493 | } |
| 495 | 494 | |
| 496 | 495 | |
| … |
… |
|
| 555 | 554 | reset_unblocked_blocks(struct influence_data *q) |
| 556 | 555 | { |
| 557 | 556 | int pos; |
| 558 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) |
| 559 | | if (ON_BOARD(pos)) { |
| | 557 | scan_board(pos, |
| 560 | 558 | if (!q->safe[pos] && q->white_strength[pos] > 0.0 |
| 561 | 559 | && q->white_permeability[pos] != 1.0) { |
| 562 | 560 | DEBUG(DEBUG_INFLUENCE, " black block removed from %1m\n", pos); |
| … |
… |
|
| 567 | 565 | DEBUG(DEBUG_INFLUENCE, " white block removed from %1m\n", pos); |
| 568 | 566 | q->black_permeability[pos] = 1.0; |
| 569 | 567 | } |
| 570 | | } |
| | 568 | ) |
| 571 | 569 | } |
| 572 | 570 | |
| 573 | 571 | |
| … |
… |
|
| 974 | 972 | /* Additionally, we introduce a weaker kind of barriers around living |
| 975 | 973 | * stones. |
| 976 | 974 | */ |
| 977 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 978 | | if (ON_BOARD(ii) && !q->safe[ii]) { |
| | 975 | scan_board(ii, |
| | 976 | if (!q->safe[ii]) { |
| 979 | 977 | int k; |
| 980 | 978 | float black_reduction = 1.0; |
| 981 | 979 | float white_reduction = 1.0; |
| … |
… |
|
| 1000 | 998 | q->black_permeability[ii] *= black_reduction; |
| 1001 | 999 | if (white_reduction > 0.0) |
| 1002 | 1000 | q->white_permeability[ii] *= white_reduction; |
| 1003 | | } |
| | 1001 | } |
| | 1002 | ) |
| 1004 | 1003 | |
| 1005 | 1004 | reset_unblocked_blocks(q); |
| 1006 | 1005 | } |
| … |
… |
|
| 1073 | 1072 | q->black_strength); |
| 1074 | 1073 | int double_blocks[MAX_DOUBLE_BLOCKS]; |
| 1075 | 1074 | int num_blocks = 0; |
| 1076 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| | 1075 | scan_board(ii, |
| 1077 | 1076 | if (board[ii] == EMPTY |
| 1078 | 1077 | && !(inhibited_sources && inhibited_sources[ii]) |
| 1079 | 1078 | && strength[ii] > 0.0) { |
| … |
… |
|
| 1083 | 1082 | if (num_blocks == MAX_DOUBLE_BLOCKS) |
| 1084 | 1083 | break; |
| 1085 | 1084 | } |
| 1086 | | } |
| | 1085 | } |
| | 1086 | ) |
| | 1087 | |
| 1087 | 1088 | { |
| 1088 | 1089 | int k; |
| 1089 | 1090 | float *permeability = ((q->color_to_move == BLACK) |
| … |
… |
|
| 1116 | 1117 | find_influence_patterns(q); |
| 1117 | 1118 | modify_depth_values(1 - stackp); |
| 1118 | 1119 | |
| 1119 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1120 | | if (ON_BOARD(ii) && !(inhibited_sources && inhibited_sources[ii])) { |
| | 1120 | scan_board(ii, |
| | 1121 | if (!(inhibited_sources && inhibited_sources[ii])) { |
| 1121 | 1122 | if (q->white_strength[ii] > 0.0) |
| 1122 | 1123 | accumulate_influence(q, ii, WHITE); |
| 1123 | 1124 | if (q->black_strength[ii] > 0.0) |
| 1124 | 1125 | accumulate_influence(q, ii, BLACK); |
| 1125 | | } |
| | 1126 | } |
| | 1127 | ) |
| 1126 | 1128 | |
| 1127 | 1129 | value_territory(q); |
| 1128 | 1130 | remove_double_blocks(q, inhibited_sources); |
| … |
… |
|
| 1299 | 1301 | memset(first_guess, 0, BOARDMAX*sizeof(float)); |
| 1300 | 1302 | memset(q->territory_value, 0, BOARDMAX*sizeof(float)); |
| 1301 | 1303 | /* First loop: guess territory directly from influence. */ |
| 1302 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1303 | | if (ON_BOARD(ii) |
| 1304 | | && !q->safe[ii]) { |
| | 1304 | scan_board(ii, |
| | 1305 | if (!q->safe[ii]) { |
| 1305 | 1306 | float diff = 0.0; |
| 1306 | 1307 | if (q->white_influence[ii] + q->black_influence[ii] > 0) |
| 1307 | 1308 | diff = (q->white_influence[ii] - q->black_influence[ii]) |
| … |
… |
|
| 1356 | 1357 | else if (board[ii] == WHITE) |
| 1357 | 1358 | first_guess[ii] = -1.0; |
| 1358 | 1359 | q->territory_value[ii] = first_guess[ii]; |
| 1359 | | } |
| | 1360 | } |
| | 1361 | ) |
| 1360 | 1362 | |
| 1361 | 1363 | /* Second loop: Correct according to neighbour vertices. Each territory |
| 1362 | 1364 | * value is degraded to the minimum value of its neighbors (unless this |
| 1363 | 1365 | * neighbor has reduced permeability for the opponent's influence). |
| 1364 | 1366 | */ |
| 1365 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1366 | | if (ON_BOARD(ii) |
| | 1367 | scan_board(ii, |
| | 1368 | if ( |
| 1367 | 1369 | /* Do not overrule dead stone territory above. |
| 1368 | 1370 | * FIXME: This does not do what it claims to do. Correcting it |
| 1369 | 1371 | * seems to break some tests, though. |
| 1370 | 1372 | */ |
| 1371 | | && !q->safe[ii]) { |
| | 1373 | !q->safe[ii]) { |
| 1372 | 1374 | /* Loop over all neighbors. */ |
| 1373 | 1375 | for (k = 0; k < 4; k++) { |
| 1374 | 1376 | if (!ON_BOARD(ii + delta[k])) |
| … |
… |
|
| 1398 | 1400 | } |
| 1399 | 1401 | } |
| 1400 | 1402 | } |
| 1401 | | } |
| | 1403 | } |
| | 1404 | ) |
| 1402 | 1405 | |
| 1403 | 1406 | /* Third loop: Nonterritory patterns, points for prisoners. */ |
| 1404 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1405 | | if (ON_BOARD(ii) |
| 1406 | | && !q->safe[ii]) { |
| | 1407 | scan_board(ii, |
| | 1408 | if (!q->safe[ii]) { |
| 1407 | 1409 | /* If marked as non-territory for the color currently owning |
| 1408 | 1410 | * it, reset the territory value. |
| 1409 | 1411 | */ |
| … |
… |
|
| 1420 | 1422 | q->territory_value[ii] += 1.0; |
| 1421 | 1423 | else if (board[ii] == WHITE) |
| 1422 | 1424 | q->territory_value[ii] -= 1.0; |
| 1423 | | } |
| | 1425 | } |
| | 1426 | ) |
| 1424 | 1427 | } |
| 1425 | 1428 | |
| 1426 | 1429 | |
| … |
… |
|
| 1440 | 1443 | regions->number = 0; |
| 1441 | 1444 | |
| 1442 | 1445 | /* Reset the markings. */ |
| 1443 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) { |
| | 1446 | scan_board(ii, |
| 1444 | 1447 | marked[ii] = 0; |
| 1445 | 1448 | regions->segmentation[ii] = 0; |
| 1446 | | } |
| | 1449 | ) |
| 1447 | 1450 | |
| 1448 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1449 | | if (ON_BOARD(ii) |
| 1450 | | && !marked[ii] |
| | 1451 | scan_board(ii, |
| | 1452 | if (!marked[ii] |
| 1451 | 1453 | && region_owner(q, ii) != EMPTY) { |
| 1452 | 1454 | /* Found an unlabelled intersection. Use flood filling to find |
| 1453 | 1455 | * the rest of the region. |
| … |
… |
|
| 1484 | 1486 | regions->size[regions->number] = size; |
| 1485 | 1487 | regions->territorial_value[regions->number] = terr_val; |
| 1486 | 1488 | regions->owner[regions->number] = color; |
| 1487 | | } |
| | 1489 | } |
| | 1490 | ) |
| 1488 | 1491 | } |
| 1489 | 1492 | |
| 1490 | 1493 | |
| … |
… |
|
| 1542 | 1545 | |
| 1543 | 1546 | /* We mark the saved stones and their neighbors in the goal array. |
| 1544 | 1547 | */ |
| 1545 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1546 | | if (ON_BOARD(ii)) { |
| | 1548 | scan_board(ii, |
| 1547 | 1549 | if (q->safe[ii] == INFLUENCE_SAVED_STONE) |
| 1548 | 1550 | goal[ii] = 1; |
| 1549 | 1551 | else |
| 1550 | 1552 | goal[ii] = 0; |
| 1551 | | } |
| | 1553 | ) |
| 1552 | 1554 | |
| 1553 | 1555 | |
| 1554 | 1556 | /* Turn off DEBUG_INFLUENCE for influence computations we are not |
| … |
… |
|
| 1573 | 1575 | reset_unblocked_blocks(q); |
| 1574 | 1576 | |
| 1575 | 1577 | /* Spread influence for new influence sources. */ |
| 1576 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1577 | | if (ON_BOARD(ii)) |
| | 1578 | scan_board(ii, |
| 1578 | 1579 | if ((color == BLACK |
| 1579 | 1580 | && q->black_strength[ii] > base->black_strength[ii]) |
| 1580 | 1581 | || (color == WHITE |
| 1581 | 1582 | && q->white_strength[ii] > base->white_strength[ii])) |
| 1582 | 1583 | accumulate_influence(q, ii, color); |
| | 1584 | ) |
| 1583 | 1585 | |
| 1584 | 1586 | value_territory(q); |
| 1585 | 1587 | |
| … |
… |
|
| 1623 | 1625 | /* Notice that we compare the out of board markers as well, in |
| 1624 | 1626 | * case the board size should have changed between calls. |
| 1625 | 1627 | */ |
| 1626 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) { |
| | 1628 | scan_board(ii, |
| 1627 | 1629 | if (cached_board[ii] != board[ii]) { |
| 1628 | 1630 | cached_board[ii] = board[ii]; |
| 1629 | 1631 | board_was_cached = 0; |
| 1630 | 1632 | } |
| 1631 | | } |
| | 1633 | ) |
| 1632 | 1634 | |
| 1633 | 1635 | if (!board_was_cached) |
| 1634 | 1636 | for (k = 0; k < 2; k++) |
| 1635 | 1637 | active_caches[k] = 0; |
| 1636 | 1638 | |
| 1637 | 1639 | if (active_caches[cache_number]) { |
| 1638 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1639 | | if (ON_BOARD(ii)) |
| 1640 | | escape_value[ii] = escape_values[ii][cache_number]; |
| | 1640 | scan_board(ii, |
| | 1641 | escape_value[ii] = escape_values[ii][cache_number]; |
| | 1642 | ) |
| 1641 | 1643 | |
| 1642 | 1644 | return; |
| 1643 | 1645 | } |
| … |
… |
|
| 1658 | 1660 | |
| 1659 | 1661 | debug = save_debug; |
| 1660 | 1662 | |
| 1661 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1662 | | if (ON_BOARD(ii)) { |
| | 1663 | scan_board(ii, |
| 1663 | 1664 | if (whose_moyo(&escape_influence, ii) == color) |
| 1664 | 1665 | escape_value[ii] = 4; |
| 1665 | 1666 | else if (whose_area(&escape_influence, ii) == color) |
| … |
… |
|
| 1690 | 1691 | } |
| 1691 | 1692 | else |
| 1692 | 1693 | escape_value[ii] = 0; |
| 1693 | | } |
| | 1694 | ) |
| 1694 | 1695 | |
| 1695 | 1696 | if (0 && (debug & DEBUG_ESCAPE) && verbose > 0) |
| 1696 | 1697 | print_influence(&escape_influence, "escape influence"); |
| 1697 | 1698 | |
| 1698 | 1699 | if (!goal) { |
| 1699 | 1700 | /* Save the computed values in the cache. */ |
| 1700 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1701 | | if (ON_BOARD(ii)) |
| 1702 | | escape_values[ii][cache_number] = escape_value[ii]; |
| | 1701 | scan_board(ii, |
| | 1702 | escape_values[ii][cache_number] = escape_value[ii]; |
| | 1703 | ) |
| | 1704 | |
| 1703 | 1705 | active_caches[cache_number] = 1; |
| 1704 | 1706 | } |
| 1705 | 1707 | } |
| … |
… |
|
| 1797 | 1799 | ASSERT_ON_BOARD1(move); |
| 1798 | 1800 | ASSERT1(IS_STONE(color), move); |
| 1799 | 1801 | |
| 1800 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1801 | | if (ON_BOARD(ii)) { |
| | 1802 | scan_board(ii, |
| 1802 | 1803 | float new_value = q->territory_value[ii]; |
| 1803 | 1804 | float old_value = base->territory_value[ii]; |
| 1804 | 1805 | this_delta = new_value - old_value; |
| … |
… |
|
| 1815 | 1816 | " %1m: - %1m territory change %f (%f -> %f)\n", |
| 1816 | 1817 | move, ii, this_delta, old_value, new_value); |
| 1817 | 1818 | total_delta += this_delta; |
| 1818 | | } |
| | 1819 | ) |
| 1819 | 1820 | |
| 1820 | 1821 | /* Finally, captured stones: */ |
| 1821 | 1822 | this_delta = q->captured - base->captured; |
| … |
… |
|
| 1841 | 1842 | float score = 0.0; |
| 1842 | 1843 | int ii; |
| 1843 | 1844 | |
| 1844 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1845 | | if (ON_BOARD(ii)) |
| 1846 | | score += q->territory_value[ii]; |
| | 1845 | scan_board(ii, |
| | 1846 | score += q->territory_value[ii]; |
| | 1847 | ) |
| 1847 | 1848 | |
| 1848 | 1849 | if (use_chinese_rules) |
| 1849 | 1850 | score += stones_on_board(WHITE) - stones_on_board(BLACK) + komi + handicap; |
| … |
… |
|
| 1866 | 1867 | int count = 0; |
| 1867 | 1868 | int ii; |
| 1868 | 1869 | |
| 1869 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 1870 | | if (ON_BOARD(ii)) { |
| | 1870 | scan_board(ii, |
| 1871 | 1871 | if (iq->safe[ii]) |
| 1872 | 1872 | count += WEIGHT_TERRITORY; |
| 1873 | 1873 | else if (whose_territory(iq, ii) != EMPTY |
| … |
… |
|
| 1877 | 1877 | count += WEIGHT_MOYO; |
| 1878 | 1878 | else if (whose_area(oq, ii) != EMPTY) |
| 1879 | 1879 | count += WEIGHT_AREA; |
| 1880 | | } |
| | 1880 | ) |
| 1881 | 1881 | |
| 1882 | 1882 | return (float) count / (WEIGHT_TERRITORY * board_size * board_size); |
| 1883 | 1883 | } |
| … |
… |
|
| 1912 | 1912 | { |
| 1913 | 1913 | int ii; |
| 1914 | 1914 | |
| 1915 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) { |
| | 1915 | scan_board(ii, |
| 1916 | 1916 | white_influence[ii] = q->white_influence[ii]; |
| 1917 | 1917 | black_influence[ii] = q->black_influence[ii]; |
| 1918 | 1918 | white_strength[ii] = q->white_strength[ii]; |
| … |
… |
|
| 1944 | 1944 | influence_regions[ii] = 4; |
| 1945 | 1945 | else if (board[ii] == BLACK) |
| 1946 | 1946 | influence_regions[ii] = -4; |
| 1947 | | } |
| | 1947 | ) |
| 1948 | 1948 | } |
| 1949 | 1949 | |
| 1950 | 1950 | |
| … |
… |
|
| 2071 | 2071 | { |
| 2072 | 2072 | int ii; |
| 2073 | 2073 | start_draw_board(); |
| 2074 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) |
| 2075 | | if (ON_BOARD(ii)) { |
| | 2074 | scan_board(ii, |
| 2076 | 2075 | int c = EMPTY; |
| 2077 | 2076 | int color = GG_COLOR_BLACK; |
| 2078 | 2077 | if (q->safe[ii]) { |
| … |
… |
|
| 2107 | 2106 | color = GG_COLOR_RED; |
| 2108 | 2107 | } |
| 2109 | 2108 | draw_color_char(I(ii), J(ii), c, color); |
| 2110 | | } |
| | 2109 | ) |
| 2111 | 2110 | end_draw_board(); |
| 2112 | 2111 | } |
| 2113 | 2112 | |