diff -N -r -u -X .ignore gnugo-copy/engine/reading.c gnugo/engine/reading.c
|
old
|
new
|
|
| 1036 | 1036 | int other; |
| 1037 | 1037 | int liberties; |
| 1038 | 1038 | int libs[MAXLIBS]; |
| 1039 | | int *cur_lib, *last_lib; |
| 1040 | 1039 | int adjs[MAXCHAIN]; |
| 1041 | 1040 | int *cur_adj, *last_adj; |
| 1042 | 1041 | int r; |
| 1043 | 1042 | int discard; |
| 1044 | | int aa, bb; |
| 1045 | | int acode; |
| 1046 | | const int *cur_delta; |
| | 1043 | int bb; |
| | 1044 | int dcode, acode; |
| 1047 | 1045 | |
| 1048 | 1046 | ASSERT1(IS_STONE(board[str]), str); |
| 1049 | 1047 | ASSERT1(!attack(str, NULL), str); |
| … |
… |
|
| 1058 | 1056 | * |
| 1059 | 1057 | * The test against 6 liberties is just an optimization. |
| 1060 | 1058 | */ |
| 1061 | | if (liberties == 1) |
| 1062 | | change_tactical_point(str, libs[0], WIN, moves, codes, |
| 1063 | | worm[str].discarded_att_threats); |
| | 1059 | if (liberties == 1) { |
| | 1060 | bb = libs[0]; |
| | 1061 | discard = 1; |
| | 1062 | |
| | 1063 | if (trymove(bb, other, "attack_threats-D", str)) { |
| | 1064 | dcode = find_defense(bb, NULL); |
| | 1065 | if (dcode) { |
| | 1066 | change_tactical_point(str, bb, dcode, moves, codes, |
| | 1067 | worm[str].discarded_att_threats); |
| | 1068 | discard = 0; |
| | 1069 | } |
| | 1070 | popgo(); |
| | 1071 | } |
| | 1072 | |
| | 1073 | if (discard) |
| | 1074 | movelist_change_discarded(bb, MAX_TACTICAL_POINTS, |
| | 1075 | worm[str].discarded_att_threats); |
| | 1076 | } |
| 1064 | 1077 | else if (liberties < 6) { |
| | 1078 | int aa; |
| | 1079 | int *cur_lib, *last_lib; |
| | 1080 | const int *cur_delta; |
| | 1081 | |
| 1065 | 1082 | cur_lib = libs; |
| 1066 | 1083 | last_lib = cur_lib + liberties; |
| 1067 | 1084 | |
| 1068 | 1085 | for (; cur_lib < last_lib; cur_lib++) { |
| 1069 | 1086 | aa = *cur_lib; |
| | 1087 | discard = 1; |
| 1070 | 1088 | |
| 1071 | 1089 | /* Try to threaten on the liberty. */ |
| 1072 | 1090 | if (trymove(aa, other, "attack_threats-A", str)) { |
| 1073 | 1091 | acode = attack(str, NULL); |
| 1074 | | if (acode) |
| | 1092 | if (acode) { |
| 1075 | 1093 | change_tactical_point(str, aa, acode, moves, codes, |
| 1076 | 1094 | worm[str].discarded_att_threats); |
| | 1095 | discard = 0; |
| | 1096 | } |
| 1077 | 1097 | popgo(); |
| 1078 | 1098 | } |
| 1079 | 1099 | |
| | 1100 | if (discard) |
| | 1101 | movelist_change_discarded(aa, MAX_TACTICAL_POINTS, |
| | 1102 | worm[str].discarded_att_threats); |
| | 1103 | |
| 1080 | 1104 | /* Try to threaten on second order liberties. */ |
| 1081 | 1105 | for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) { |
| 1082 | 1106 | bb = aa + *cur_delta; |
| … |
… |
|
| 1111 | 1135 | cur_adj = adjs; |
| 1112 | 1136 | last_adj = cur_adj + chainlinks(str, adjs); |
| 1113 | 1137 | for (; cur_adj < last_adj; cur_adj++) { |
| 1114 | | int dcode; |
| 1115 | | |
| 1116 | 1138 | if (!attack_and_defend(*cur_adj, &acode, NULL, &dcode, NULL)) |
| 1117 | 1139 | continue; |
| 1118 | 1140 | |
diff -N -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
|
old
|
new
|
|
| 461 | 461 | && worm[pos].origin == pos) { |
| 462 | 462 | |
| 463 | 463 | /* Find adjacent worms that can be easily captured, aka lunches. */ |
| 464 | | if (find_lunch(pos, &lunch) |
| 465 | | && ((acode = worm[lunch].attack_codes[0]) == WIN |
| 466 | | || acode == KO_A)) { |
| | 464 | if (find_lunch(pos, &lunch)) { |
| 467 | 465 | DEBUG(DEBUG_WORMS, "lunch found for %1m at %1m\n", pos, lunch); |
| 468 | 466 | worm[pos].lunch = lunch; |
| 469 | 467 | propagate_worm(pos); |
| 470 | 468 | } |
| 471 | 469 | else { |
| 472 | 470 | /* Identify INESSENTIAL strings. */ |
| 473 | | if (!worm[pos].genus |
| 474 | | && !worm[pos].liberties2 |
| | 471 | if (!worm[pos].liberties2 |
| | 472 | && !worm[pos].genus |
| 475 | 473 | && !worm[pos].cutstone) { |
| 476 | 474 | if (examine_cavity(pos, &edge) != GRAY && edge < 3) { |
| 477 | 475 | DEBUG(DEBUG_WORMS, "Worm %1m identified as inessential.\n", pos); |
| … |
… |
|
| 965 | 963 | find_lunch(int str, int *lunch) |
| 966 | 964 | { |
| 967 | 965 | int pos; |
| 968 | | int k; |
| | 966 | int apos; |
| | 967 | int lunch_pos = NO_MOVE; |
| | 968 | int other = OTHER_COLOR(board[str]); |
| | 969 | const int *cur_delta; |
| 969 | 970 | |
| 970 | 971 | ASSERT1(IS_STONE(board[str]), str); |
| 971 | 972 | ASSERT1(stackp == 0, str); |
| 972 | 973 | |
| 973 | | *lunch = NO_MOVE; |
| 974 | 974 | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 975 | | if (board[pos] != OTHER_COLOR(board[str])) |
| | 975 | if (board[pos] != other) |
| 976 | 976 | continue; |
| 977 | | for (k = 0; k < 8; k++) { |
| 978 | | int apos = pos + delta[k]; |
| | 977 | for (cur_delta = delta; cur_delta < last_delta_8; cur_delta++) { |
| | 978 | apos = pos + *cur_delta; |
| 979 | 979 | if (IS_STONE(board[apos]) && is_same_worm(apos, str)) { |
| 980 | | if (worm[pos].attack_codes[0] != 0 && !is_ko_point(pos)) { |
| | 980 | if (worm[pos].attack_codes[0] >= KO_A && !is_ko_point(pos)) { |
| 981 | 981 | /* |
| 982 | 982 | * If several adjacent lunches are found, we pick the |
| 983 | | * juiciest. First maximize cutstone, then minimize liberties. |
| | 983 | * juiciest. First maximize attack_code, then cutstone, |
| | 984 | * then minimize liberties, then maximize size. |
| 984 | 985 | * We can only do this if the worm data is available, |
| 985 | 986 | * i.e. if stackp==0. |
| 986 | 987 | */ |
| 987 | | if (*lunch == NO_MOVE |
| 988 | | || worm[pos].cutstone > worm[*lunch].cutstone |
| 989 | | || (worm[pos].cutstone == worm[*lunch].cutstone |
| 990 | | && worm[pos].liberties < worm[*lunch].liberties)) { |
| 991 | | *lunch = worm[pos].origin; |
| | 988 | if (lunch_pos) { |
| | 989 | if (worm[pos].attack_codes[0] |
| | 990 | < worm[lunch_pos].attack_codes[0]) |
| | 991 | break; |
| | 992 | else if (worm[pos].attack_codes[0] |
| | 993 | == worm[lunch_pos].attack_codes[0]) { |
| | 994 | if (worm[pos].cutstone < worm[lunch_pos].cutstone) |
| | 995 | break; |
| | 996 | else if (worm[pos].cutstone == worm[lunch_pos].cutstone) { |
| | 997 | if (worm[pos].liberties > worm[lunch_pos].liberties) |
| | 998 | break; |
| | 999 | else if (worm[pos].liberties == worm[lunch_pos].liberties) { |
| | 1000 | if (worm[pos].size <= worm[lunch_pos].size) |
| | 1001 | break; |
| | 1002 | } |
| | 1003 | } |
| | 1004 | } |
| 992 | 1005 | } |
| | 1006 | |
| | 1007 | lunch_pos = worm[pos].origin; |
| 993 | 1008 | } |
| 994 | 1009 | break; |
| 995 | 1010 | } |
| 996 | 1011 | } |
| 997 | 1012 | } |
| 998 | | |
| 999 | | if (*lunch != NO_MOVE) |
| 1000 | | return 1; |
| 1001 | 1013 | |
| 1002 | | return 0; |
| | 1014 | *lunch = lunch_pos; |
| | 1015 | return lunch_pos; |
| 1003 | 1016 | } |
| 1004 | 1017 | |
| 1005 | 1018 | |
| 1006 | 1019 | /* |
| 1007 | | * Test whether two worms are the same. Used by autohelpers. |
| | 1020 | * Test whether two worms are the same. |
| 1008 | 1021 | * Before this function can be called, build_worms must have been run. |
| 1009 | 1022 | */ |
| 1010 | 1023 | |
| … |
… |
|
| 1039 | 1052 | void |
| 1040 | 1053 | change_defense(int str, int move, int dcode) |
| 1041 | 1054 | { |
| | 1055 | DEBUG(DEBUG_WORMS, "change_defense: %1m %1m %d\n", str, move, dcode); |
| 1042 | 1056 | change_tactical_point(str, move, dcode, |
| 1043 | 1057 | worm[str].defense_points, worm[str].defense_codes, |
| 1044 | 1058 | worm[str].discarded_defenses); |
| … |
… |
|
| 1075 | 1089 | void |
| 1076 | 1090 | change_defense_threat(int str, int move, int dcode) |
| 1077 | 1091 | { |
| | 1092 | DEBUG(DEBUG_WORMS, "change_defense_threat: %1m %1m %d\n", str, |
| | 1093 | move, dcode); |
| 1078 | 1094 | change_tactical_point(str, move, dcode, |
| 1079 | 1095 | worm[str].defense_threat_points, |
| 1080 | 1096 | worm[str].defense_threat_codes, |
| … |
… |
|
| 1094 | 1110 | void |
| 1095 | 1111 | change_attack_threat(int str, int move, int acode) |
| 1096 | 1112 | { |
| | 1113 | DEBUG(DEBUG_WORMS, "change_attack_threat: %1m %1m %d\n", str, |
| | 1114 | move, acode); |
| 1097 | 1115 | change_tactical_point(str, move, acode, |
| 1098 | 1116 | worm[str].attack_threat_points, |
| 1099 | 1117 | worm[str].attack_threat_codes, |
| … |
… |
|
| 1226 | 1244 | if (!IS_STONE(board[pos]) || !is_worm_origin(pos, pos)) |
| 1227 | 1245 | continue; |
| 1228 | 1246 | |
| 1229 | | if (board[pos] == OTHER_COLOR(color)) { |
| 1230 | | for (k = 0; k < MAX_TACTICAL_POINTS; k++) { |
| 1231 | | if (worm[pos].attack_codes[k] != 0) |
| 1232 | | add_attack_move(worm[pos].attack_points[k], pos, |
| 1233 | | worm[pos].attack_codes[k]); |
| 1234 | | if (worm[pos].attack_threat_codes[k] != 0) |
| 1235 | | add_attack_threat_move(worm[pos].attack_threat_points[k], pos, |
| 1236 | | worm[pos].attack_threat_codes[k]); |
| 1237 | | } |
| 1238 | | } |
| 1239 | | |
| 1240 | 1247 | if (board[pos] == color) { |
| 1241 | 1248 | for (k = 0; k < MAX_TACTICAL_POINTS; k++) { |
| 1242 | | if (worm[pos].defense_codes[k] != 0) |
| | 1249 | if (worm[pos].defense_codes[k]) |
| 1243 | 1250 | add_defense_move(worm[pos].defense_points[k], pos, |
| 1244 | 1251 | worm[pos].defense_codes[k]); |
| | 1252 | else |
| | 1253 | break; |
| | 1254 | } |
| 1245 | 1255 | |
| 1246 | | if (worm[pos].defense_threat_codes[k] != 0) |
| | 1256 | for (k = 0; k < MAX_TACTICAL_POINTS; k++) { |
| | 1257 | if (worm[pos].defense_threat_codes[k]) |
| 1247 | 1258 | add_defense_threat_move(worm[pos].defense_threat_points[k], pos, |
| 1248 | 1259 | worm[pos].defense_threat_codes[k]); |
| | 1260 | else |
| | 1261 | break; |
| | 1262 | } |
| | 1263 | } |
| | 1264 | else { /* board[pos] == other */ |
| | 1265 | for (k = 0; k < MAX_TACTICAL_POINTS; k++) { |
| | 1266 | if (worm[pos].attack_codes[k]) |
| | 1267 | add_attack_move(worm[pos].attack_points[k], pos, |
| | 1268 | worm[pos].attack_codes[k]); |
| | 1269 | else |
| | 1270 | break; |
| | 1271 | } |
| | 1272 | |
| | 1273 | for (k = 0; k < MAX_TACTICAL_POINTS; k++) { |
| | 1274 | if (worm[pos].attack_threat_codes[k]) |
| | 1275 | add_attack_threat_move(worm[pos].attack_threat_points[k], pos, |
| | 1276 | worm[pos].attack_threat_codes[k]); |
| | 1277 | else |
| | 1278 | break; |
| 1249 | 1279 | } |
| 1250 | 1280 | } |
| 1251 | 1281 | } |