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.56 diff -u -r1.56 semeai.c --- semeai.c 4 Jun 2003 19:16:46 -0000 1.56 +++ semeai.c 6 Jul 2003 03:30:56 -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); @@ -251,18 +255,64 @@ && (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); - DEBUG(DEBUG_SEMEAI, "Adding semeai defense move for %1m at %1m\n", + 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 out side liberties of the target, + then all the out side liberties of the target are the supposed moves + if this is a ko or snap-back, then things are different */ + int liberties; + int libs[MAXLIBS]; + int r; + liberties = findlib(dragon2[d].semeai_target, MAXLIBS, libs); + + /* get all out side liberties */ + for (r = 0; r < liberties; r++) + if (!liberty_of_dragon(libs[r], dragon2[d].origin) + && !is_self_atari(libs[r], color)) { + 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 { + 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); + } } 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)) { - 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].semeai_target) + && !liberty_of_dragon(dragon2[d].semeai_attack_point, dragon2[d].origin) + && !is_self_atari(dragon2[d].semeai_attack_point, color)) { + + /* if this is a move to fill the out side liberties of the target, + then all the out side liberties of the target are the supposed moves + if this is a ko or snap-back, then things are different */ + int liberties; + int libs[MAXLIBS]; + int r; + liberties = findlib(dragon2[d].semeai_target, MAXLIBS, libs); + + /* get all out side liberties */ + for (r = 0; r < liberties; r++) + if (!liberty_of_dragon(libs[r], dragon2[d].origin) + && !is_self_atari(libs[r], color)) { + 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]); + } + } + else { + 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); + } } } } 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