Index: liberty.h =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v retrieving revision 1.184 diff -u -r1.184 liberty.h --- liberty.h 26 Jun 2003 20:24:03 -0000 1.184 +++ liberty.h 6 Jul 2003 01:53:44 -0000 @@ -1009,6 +1009,7 @@ int semeai_defense_certain; int semeai_attack_point; /* Move found by semeai code to kill dragon */ int semeai_attack_certain; + int semeai_target; /* The opponent dragon involved in the semeai */ int owl_threat_status; /* CAN_THREATEN_ATTACK or CAN_THREATEN_DEFENSE */ int owl_status; /* (ALIVE, DEAD, UNKNOWN, CRITICAL, UNCHECKED) */ int owl_attack_point; /* vital point for attack */ Index: semeai.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/semeai.c,v retrieving revision 1.57 diff -u -r1.57 semeai.c --- semeai.c 18 Jul 2003 18:59:21 -0000 1.57 +++ semeai.c 4 Aug 2003 22:30:02 -0000 @@ -194,6 +194,7 @@ int attack_move = PASS_MOVE; int defense_certain = 0; int attack_certain = 0; + int semeai_target = 0; for (d2 = 0; d2 < num_dragons; d2++) { if (semeai_results_first[d1][d2] == -1) @@ -207,6 +208,7 @@ best_defense = semeai_results_first[d1][d2]; defense_move = semeai_move[d1][d2]; defense_certain = semeai_certain[d1][d2]; + semeai_target = dragon2[d2].origin; } if (best_attack < semeai_results_second[d2][d1] || (best_attack == semeai_results_second[d2][d1] @@ -214,6 +216,7 @@ best_attack = semeai_results_second[d2][d1]; attack_move = semeai_move[d2][d1]; attack_certain = semeai_certain[d2][d1]; + semeai_target = dragon2[d2].origin; } } @@ -225,6 +228,7 @@ dragon2[d1].semeai_defense_certain = defense_certain; dragon2[d1].semeai_attack_point = attack_move; dragon2[d1].semeai_attack_certain = attack_certain; + dragon2[d1].semeai_target = semeai_target; } else if (best_attack == 0 && attack_certain) update_status(DRAGON(d1).origin, ALIVE, ALIVE); @@ -243,6 +247,10 @@ { int other = OTHER_COLOR(color); int d; + int liberties; + int libs[MAXLIBS]; + int r; + int resulta, resultb, semeai_move, s_result_certain; for (d = 0; d < number_of_dragons; d++) if (dragon2[d].semeai && DRAGON(d).status == CRITICAL) { @@ -251,18 +259,66 @@ && (dragon2[d].owl_defense_point == NO_MOVE || dragon2[d].semeai_defense_certain >= dragon2[d].owl_defense_certain)) { - add_semeai_move(dragon2[d].semeai_defense_point, dragon2[d].origin); + /* My dragon can be defended */ + add_semeai_move(dragon2[d].semeai_defense_point, dragon2[d].origin); DEBUG(DEBUG_SEMEAI, "Adding semeai defense move for %1m at %1m\n", - DRAGON(d).origin, dragon2[d].semeai_defense_point); + DRAGON(d).origin, dragon2[d].semeai_defense_point); + if (liberty_of_dragon(dragon2[d].semeai_defense_point, dragon2[d].semeai_target) + && !liberty_of_dragon(dragon2[d].semeai_defense_point, dragon2[d].origin) + && !is_self_atari(dragon2[d].semeai_defense_point, color)) { + + /* if this is a move to fill the non-common liberties of the target, + and is not a ko or snap-back, then we try all non-common liberties + of the target and put all winning moves to the move list */ + + liberties = findlib(dragon2[d].semeai_target, MAXLIBS, libs); + + for (r = 0; r < liberties; r++) + if (!liberty_of_dragon(libs[r], dragon2[d].origin) + && !is_self_atari(libs[r], color) + && libs[r] != dragon2[d].semeai_defense_point) { + + owl_analyze_semeai_after_move(libs[r], color, dragon2[d].semeai_target, + dragon2[d].origin, &resulta, &resultb, &semeai_move, + 1, &s_result_certain); + if (resulta == 0 && resultb == 0) { + add_semeai_move(libs[r], dragon2[d].origin); + DEBUG(DEBUG_SEMEAI, "Adding semeai defense move for %1m at %1m\n", + DRAGON(d).origin, libs[r]); + } + } + } } else if (DRAGON(d).color == other && dragon2[d].semeai_attack_point && (dragon2[d].owl_attack_point == NO_MOVE || dragon2[d].semeai_attack_certain >= dragon2[d].owl_attack_certain)) { + /* Your dragon can be attacked */ add_semeai_move(dragon2[d].semeai_attack_point, dragon2[d].origin); DEBUG(DEBUG_SEMEAI, "Adding semeai attack move for %1m at %1m\n", DRAGON(d).origin, dragon2[d].semeai_attack_point); + if (liberty_of_dragon(dragon2[d].semeai_attack_point, dragon2[d].origin) + && !liberty_of_dragon(dragon2[d].semeai_attack_point, dragon2[d].semeai_target) + && !is_self_atari(dragon2[d].semeai_attack_point, color)) { + + liberties = findlib(dragon2[d].origin, MAXLIBS, libs); + + for (r = 0; r < liberties; r++) + if (!liberty_of_dragon(libs[r], dragon2[d].semeai_target) + && !is_self_atari(libs[r], color) + && libs[r] != dragon2[d].semeai_attack_point) { + + owl_analyze_semeai_after_move(libs[r], color, dragon2[d].origin, + dragon2[d].semeai_target, &resulta, &resultb, &semeai_move, + 1, &s_result_certain); + if (resulta == 0 && resultb == 0) { + add_semeai_move(libs[r], dragon2[d].origin); + DEBUG(DEBUG_SEMEAI, "Adding semeai attack move for %1m at %1m\n", + DRAGON(d).origin, libs[r]); + } + } + } } } } Index: strategy.tst =================================================================== RCS file: /cvsroot/gnugo/gnugo/regression/strategy.tst,v retrieving revision 1.51 diff -u -r1.51 strategy.tst --- strategy.tst 22 Jun 2003 17:12:12 -0000 1.51 +++ strategy.tst 6 Jul 2003 01:07:03 -0000 @@ -286,9 +286,10 @@ #? [G2]* # G17/G18 and C1 are both huge. +# H1 is absolutely better than C1 /spl loadsgf games/strategy11.sgf 127 45 gg_genmove black -#? [G17|G18|C1] +#? [G17|G18|H1] loadsgf games/strategy11.sgf 245 46 gg_genmove black