Ticket #163: draqo-semeai.diff
| File draqo-semeai.diff, 9.0 kB (added by arend, 15 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 * … … 670 670 struct eyevalue probable_eyes_a; 671 671 struct eyevalue probable_eyes_b; 672 672 struct eyevalue dummy_eyes; 673 int I_have_more_eyes; 673 674 674 675 SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos); 675 676 … … 804 805 if (!owl_phase) { 805 806 set_eyevalue(&probable_eyes_a, 0, 0, 0, 0); 806 807 set_eyevalue(&probable_eyes_b, 0, 0, 0, 0); 808 I_have_more_eyes = 0; 807 809 } 808 810 else { 809 811 /* First the vital moves. These include moves to attack or … … 893 895 shape_defensive_moves, 1, owla)) 894 896 break; 895 897 } 898 else 899 shape_defensive_moves[0].pos = 0; 900 896 901 if (!you_look_alive) { 897 902 owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, 898 903 owlb, &owl_attackpat_db); … … 901 906 shape_offensive_moves, 1, owlb)) 902 907 break; 903 908 } 909 else 910 shape_offensive_moves[0].pos = 0; 911 912 /* Filter out moves, which fills our eye (and not split it). */ 913 if (eyemax_a) { 914 int n; 915 struct owl_move_data *checked_moves; 916 917 for (n = 1; n <= 5; n++) { 918 switch (n) { 919 case 1: 920 checked_moves = moves; 921 break; 922 case 2: 923 checked_moves = vital_defensive_moves; 924 break; 925 case 3: 926 checked_moves = vital_offensive_moves; 927 break; 928 case 4: 929 checked_moves = shape_defensive_moves; 930 break; 931 case 5: 932 checked_moves = shape_offensive_moves; 933 break; 934 default: 935 checked_moves = NULL; 936 gg_assert(0); 937 } 938 939 for (k = 0; k < MAX_MOVES; k++) { 940 if (checked_moves[k].pos <= 0) 941 break; 942 else { 943 struct eye_data *eye = &owla->my_eye[checked_moves[k].pos]; 944 945 /* If esize==1 this eye must not be a real eye (at least one 946 * worm is capturable, otherwise this move would not be 947 * proposed). 948 */ 949 if (eye->color == color && eye->msize == 0 && eye->neighbors <= 1 950 && eye->esize != 1 951 && owla->half_eye[checked_moves[k].pos].type != HALF_EYE 952 && !has_neighbor(checked_moves[k].pos, OTHER_COLOR(color))) 953 checked_moves[k].value = 0; 954 } 955 } 956 } 957 } 904 958 905 959 /* Now we review the moves already considered, while collecting 906 960 * them into a single list. … … 956 1010 include_semeai_worms_in_eyespace = 0; 957 1011 } 958 1012 1013 if (eyemin_a == eyemax_a) 1014 /* We have stable number of eyes, so we can try to reduce 1015 * opponent eyes. */ 1016 I_have_more_eyes = (eyemin_a > min_eyes(&probable_eyes_b)); 1017 else { 1018 if (min_eyes(&probable_eyes_a) == max_eyes(&probable_eyes_a)) 1019 /* If we can't increase our number of eyes, we try to reduce 1020 * opponent eyes. */ 1021 I_have_more_eyes = (max_eyes(&probable_eyes_a) > min_eyes(&probable_eyes_b)); 1022 else 1023 /* If we can increase our number of eyes, we do it and let 1024 * opponent to increase his. */ 1025 I_have_more_eyes = (max_eyes(&probable_eyes_a) > max_eyes(&probable_eyes_b)); 1026 } 1027 959 1028 if (get_level() < 8) { 960 1029 /* If no owl moves were found on two consecutive moves, 961 1030 * turn off the owl phase. … … 979 1048 980 1049 /* Now we look for a move to fill a liberty. This is only 981 1050 * interesting if the opponent doesn't already have two eyes. 1051 * If we have more eyes, always check for a backfilling move. 982 1052 */ 983 1053 if (!you_look_alive 984 && !safe_outside_liberty_found && moves[0].value < 110) { 1054 && !safe_outside_liberty_found 1055 && (moves[0].value < 110 || I_have_more_eyes)) { 985 1056 int pos; 986 1057 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 987 1058 if (!ON_BOARD(pos)) 988 continue;1059 continue; 989 1060 990 1061 if (board[pos] == EMPTY && !mw[pos]) { 991 1062 if (liberty_of_goal(pos, owlb)) { … … 997 1068 break; 998 1069 } 999 1070 else if (backfill_outside_liberty.pos == NO_MOVE) 1000 backfill_outside_liberty.pos = find_semeai_backfilling_move(bpos,1001 pos);1071 backfill_outside_liberty.pos = 1072 find_semeai_backfilling_move(bpos, pos); 1002 1073 } 1003 1074 else { 1004 1075 /* common liberty */ … … 1007 1078 common_liberty.pos = pos; 1008 1079 } 1009 1080 else if (backfill_common_liberty.pos == NO_MOVE) 1010 backfill_common_liberty.pos = find_semeai_backfilling_move(bpos,1011 pos);1081 backfill_common_liberty.pos = 1082 find_semeai_backfilling_move(bpos, pos); 1012 1083 } 1013 1084 } 1014 1085 } … … 1095 1166 if (mpos == NO_MOVE) 1096 1167 break; 1097 1168 1169 if (moves[k].value == 0) 1170 continue; 1171 1098 1172 /* Do not try too many moves. */ 1099 1173 if (tested_moves > 2 1100 1174 || (stackp > semeai_branch_depth2 && tested_moves > 1) … … 1283 1357 gg_assert(this_resulta != NULL && this_resultb != NULL); 1284 1358 *this_resulta = 0; 1285 1359 *this_resultb = 0; 1286 if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) 1360 1361 if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) { 1362 int kpos; 1363 if (is_ko(move, color, &kpos)) { 1364 /* Move was not allowed because of komaster. We want to check, if this 1365 * situation is double ko and when it is, we won semeai. 1366 */ 1367 int libs[MAX_LIBERTIES]; 1368 int n; 1369 int nlib; 1370 int sworm; 1371 int worm_color; 1372 int other = OTHER_COLOR(color); 1373 1374 for (sworm = 0; sworm < s_worms; sworm++) { 1375 worm_color = board[semeai_worms[sworm]]; 1376 if (worm_color == color) { 1377 /* We only check up to MAX_LIBERTIES, due to performance reasons. When we 1378 * have more liberties we have some outside liberties to fill and these 1379 * moves will be tried later (and double ko situation will be found). 1380 */ 1381 nlib = findlib(semeai_worms[sworm], MAX_LIBERTIES, libs); 1382 if (nlib > MAX_LIBERTIES) 1383 return 0; 1384 1385 for (n = 0; n < nlib; n++) 1386 if (is_ko(libs[n], other, NULL)) { 1387 /* Check if situation is not a nested ko capture. */ 1388 if (DIAGONAL_NEIGHBORS(libs[n], kpos)) 1389 return 0; 1390 1391 /* Our dragon has double ko, but we have to check if opponent dragon 1392 * doesn't have outside liberties or double ko. 1393 */ 1394 *this_resulta = WIN; 1395 *this_resultb = WIN; 1396 } 1397 } 1398 else if (worm_color == other) { 1399 if (countlib(semeai_worms[sworm]) > 2) 1400 /* In double ko situation the opponent can have only 1401 * a single eye and a ko outside liberty to be sure that we 1402 * will always win double ko. */ 1403 return 0; 1404 } 1405 } 1406 if (*this_resulta == WIN) 1407 return 1; 1408 } 1409 1287 1410 return 0; 1411 } 1288 1412 1289 1413 semeai_add_sgf_comment(move_value, owl_phase); 1290 1414 TRACE("Trying %C %1m. Current stack: ", color, move); … … 1453 1577 if (move == NO_MOVE) 1454 1578 break; 1455 1579 1580 if (owl_moves[k].value == 0) 1581 continue; 1582 1456 1583 /* Does the move fill a liberty in the semeai? */ 1457 1584 if (liberty_of_goal(move, owlb) 1458 1585 && safe_move(move, color)) { … … 1578 1705 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 1579 1706 if (IS_STONE(board[pos]) 1580 1707 && pos == find_origin(pos)) { 1581 if (owla->goal[pos]) 1582 net -= 75*countlib(pos); 1583 if (owlb->goal[pos]) 1584 net += 100*countlib(pos); 1708 int count_lib = -1; 1709 if (owla->goal[pos]) { 1710 count_lib = countlib(pos); 1711 net -= 75 * count_lib; 1712 } 1713 if (owlb->goal[pos]) { 1714 if (count_lib < 0) 1715 count_lib = countlib(pos); 1716 net += 100 * count_lib; 1717 } 1585 1718 } 1586 1719 } 1587 1720 if (!trymove(move, color, NULL, 0)) { … … 1591 1724 for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 1592 1725 if (IS_STONE(board[pos]) 1593 1726 && pos == find_origin(pos)) { 1727 int count_lib = -1; 1594 1728 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); 1729 || (pos == move && liberty_of_goal(move, owla))) { 1730 count_lib = countlib(pos); 1731 net += 75 * count_lib; 1732 } 1733 if (owlb->goal[pos]) { 1734 if (count_lib < 0) 1735 count_lib = countlib(pos); 1736 net -= 100 * count_lib; 1737 } 1599 1738 } 1600 1739 } 1601 1740
