Ticket #163: draqo-semeai_b.diff
| File draqo-semeai_b.diff, 8.9 kB (added by arend, 16 months ago) |
|---|
-
engine/owl.c
RCS file: /home/arend/Go/gnugo-rsync/gnugo/engine/owl.c,v retrieving revision 1.253 diff -u -p -r1.253 owl.c
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 * … … 284 284 struct local_owl_data *owlb, int raw_value, 285 285 int *critical_semeai_worms); 286 286 static int semeai_is_riskless_move(int move, struct local_owl_data *owla); 287 static void remove_eye_filling_moves(struct local_owl_data *our_owl, 288 struct owl_move_data *moves); 287 289 static int find_semeai_backfilling_move(int worm, int liberty); 288 290 static int liberty_of_goal(int pos, struct local_owl_data *owl); 289 291 static int second_liberty_of_goal(int pos, struct local_owl_data *owl); … … 670 672 struct eyevalue probable_eyes_a; 671 673 struct eyevalue probable_eyes_b; 672 674 struct eyevalue dummy_eyes; 675 int I_have_more_eyes; 673 676 674 677 SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos); 675 678 … … 804 807 if (!owl_phase) { 805 808 set_eyevalue(&probable_eyes_a, 0, 0, 0, 0); 806 809 set_eyevalue(&probable_eyes_b, 0, 0, 0, 0); 810 I_have_more_eyes = 0; 807 811 } 808 812 else { 809 813 /* First the vital moves. These include moves to attack or … … 893 897 shape_defensive_moves, 1, owla)) 894 898 break; 895 899 } 900 else 901 shape_defensive_moves[0].pos = 0; 902 896 903 if (!you_look_alive) { 897 904 owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, 898 905 owlb, &owl_attackpat_db); … … 901 908 shape_offensive_moves, 1, owlb)) 902 909 break; 903 910 } 911 else 912 shape_offensive_moves[0].pos = 0; 913 914 /* Filter out moves, which fills our eye (and not split it). */ 915 if (eyemax_a) { 916 remove_eye_filling_moves(owla, vital_defensive_moves); 917 remove_eye_filling_moves(owla, vital_offensive_moves); 918 remove_eye_filling_moves(owla, shape_defensive_moves); 919 remove_eye_filling_moves(owla, shape_offensive_moves); 920 } 904 921 905 922 /* Now we review the moves already considered, while collecting 906 923 * them into a single list. … … 956 973 include_semeai_worms_in_eyespace = 0; 957 974 } 958 975 976 if (eyemin_a == eyemax_a) 977 /* We have stable number of eyes, so we can try to reduce 978 * opponent eyes. */ 979 I_have_more_eyes = (eyemin_a > min_eyes(&probable_eyes_b)); 980 else { 981 if (min_eyes(&probable_eyes_a) == max_eyes(&probable_eyes_a)) 982 /* If we can't increase our number of eyes, we try to reduce 983 * opponent eyes. */ 984 I_have_more_eyes = (max_eyes(&probable_eyes_a) > min_eyes(&probable_eyes_b)); 985 else 986 /* If we can increase our number of eyes, we do it and let 987 * opponent to increase his. */ 988 I_have_more_eyes = (max_eyes(&probable_eyes_a) > max_eyes(&probable_eyes_b)); 989 } 990 959 991 if (get_level() < 8) { 960 992 /* If no owl moves were found on two consecutive moves, 961 993 * turn off the owl phase. … … 979 1011 980 1012 /* Now we look for a move to fill a liberty. This is only 981 1013 * interesting if the opponent doesn't already have two eyes. 1014 * If we have more eyes, always check for a backfilling move. 982 1015 */ 983 1016 if (!you_look_alive 984 && !safe_outside_liberty_found && moves[0].value < 110) { 1017 && !safe_outside_liberty_found 1018 && (moves[0].value < 110 || I_have_more_eyes)) { 985 1019 int pos; 986 1020 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 987 1021 if (!ON_BOARD(pos)) 988 continue;1022 continue; 989 1023 990 1024 if (board[pos] == EMPTY && !mw[pos]) { 991 1025 if (liberty_of_goal(pos, owlb)) { … … 1095 1129 if (mpos == NO_MOVE) 1096 1130 break; 1097 1131 1132 if (moves[k].value == 0) 1133 continue; 1134 1098 1135 /* Do not try too many moves. */ 1099 1136 if (tested_moves > 2 1100 1137 || (stackp > semeai_branch_depth2 && tested_moves > 1) … … 1283 1320 gg_assert(this_resulta != NULL && this_resultb != NULL); 1284 1321 *this_resulta = 0; 1285 1322 *this_resultb = 0; 1286 if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) 1323 1324 if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) { 1325 int kpos; 1326 if (is_ko(move, color, &kpos)) { 1327 /* Move was not allowed because of komaster. We want to check, if this 1328 * situation is double ko and when it is, we won semeai. 1329 */ 1330 int libs[MAX_LIBERTIES]; 1331 int n; 1332 int nlib; 1333 int sworm; 1334 int worm_color; 1335 int other = OTHER_COLOR(color); 1336 1337 for (sworm = 0; sworm < s_worms; sworm++) { 1338 worm_color = board[semeai_worms[sworm]]; 1339 if (worm_color == color) { 1340 /* We only check up to MAX_LIBERTIES, due to performance reasons. When we 1341 * have more liberties we have some outside liberties to fill and these 1342 * moves will be tried later (and double ko situation will be found). 1343 */ 1344 nlib = findlib(semeai_worms[sworm], MAX_LIBERTIES, libs); 1345 if (nlib > MAX_LIBERTIES) 1346 return 0; 1347 1348 for (n = 0; n < nlib; n++) 1349 if (is_ko(libs[n], other, NULL)) { 1350 /* Check if situation is not a nested ko capture. */ 1351 if (DIAGONAL_NEIGHBORS(libs[n], kpos)) 1352 return 0; 1353 1354 /* Our dragon has double ko, but we have to check if opponent dragon 1355 * doesn't have outside liberties or double ko. 1356 */ 1357 *this_resulta = WIN; 1358 *this_resultb = WIN; 1359 } 1360 } 1361 else if (worm_color == other) { 1362 if (countlib(semeai_worms[sworm]) > 2) 1363 /* In double ko situation the opponent can have only 1364 * a single eye and a ko outside liberty to be sure that we 1365 * will always win double ko. */ 1366 return 0; 1367 } 1368 } 1369 if (*this_resulta == WIN) 1370 return 1; 1371 } 1372 1287 1373 return 0; 1374 } 1288 1375 1289 1376 semeai_add_sgf_comment(move_value, owl_phase); 1290 1377 TRACE("Trying %C %1m. Current stack: ", color, move); … … 1453 1540 if (move == NO_MOVE) 1454 1541 break; 1455 1542 1543 if (owl_moves[k].value == 0) 1544 continue; 1545 1456 1546 /* Does the move fill a liberty in the semeai? */ 1457 1547 if (liberty_of_goal(move, owlb) 1458 1548 && safe_move(move, color)) { … … 1578 1668 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 1579 1669 if (IS_STONE(board[pos]) 1580 1670 && pos == find_origin(pos)) { 1581 if (owla->goal[pos]) 1582 net -= 75*countlib(pos); 1583 if (owlb->goal[pos]) 1584 net += 100*countlib(pos); 1671 int count_lib = -1; 1672 if (owla->goal[pos]) { 1673 count_lib = countlib(pos); 1674 net -= 75 * count_lib; 1675 } 1676 if (owlb->goal[pos]) { 1677 if (count_lib < 0) 1678 count_lib = countlib(pos); 1679 net += 100 * count_lib; 1680 } 1585 1681 } 1586 1682 } 1587 1683 if (!trymove(move, color, NULL, 0)) { … … 1591 1687 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 1592 1688 if (IS_STONE(board[pos]) 1593 1689 && pos == find_origin(pos)) { 1690 int count_lib = -1; 1594 1691 if (owla->goal[pos] 1595 || (pos == move && liberty_of_goal(move, owla))) 1596 net += 75*countlib(pos); 1597 if (owlb->goal[pos]) 1598 net -= 100*countlib(pos); 1692 || (pos == move && liberty_of_goal(move, owla))) { 1693 count_lib = countlib(pos); 1694 net += 75 * count_lib; 1695 } 1696 if (owlb->goal[pos]) { 1697 if (count_lib < 0) 1698 count_lib = countlib(pos); 1699 net -= 100 * count_lib; 1700 } 1599 1701 } 1600 1702 } 1601 1703 … … 1627 1729 } 1628 1730 1629 1731 1732 /* Remove all moves from the list that would fill our own eye. */ 1733 static void 1734 remove_eye_filling_moves(struct local_owl_data *our_owl, 1735 struct owl_move_data *moves) 1736 { 1737 int k; 1738 int color = our_owl->color; 1739 1740 for (k = 0; k < MAX_MOVES; k++) { 1741 if (moves[k].pos <= 0) 1742 break; 1743 else { 1744 struct eye_data *eye = &our_owl->my_eye[moves[k].pos]; 1745 1746 /* If esize==1 this eye must not be a real eye (at least one 1747 * worm is capturable, otherwise this move would not be 1748 * proposed). 1749 */ 1750 if (eye->color == color && eye->msize == 0 && eye->neighbors <= 1 1751 && eye->esize != 1 1752 && our_owl->half_eye[moves[k].pos].type != HALF_EYE 1753 && !has_neighbor(moves[k].pos, OTHER_COLOR(color))) 1754 moves[k].value = 0; 1755 } 1756 } 1757 } 1630 1758 1631 1759 /* Is the vertex at pos adjacent to an element of the owl goal? */ 1632 1760 static int
