gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnugo-devel] saving lunch can split owl dragon


From: Arend Bayer
Subject: [gnugo-devel] saving lunch can split owl dragon
Date: Sun, 12 Sep 2004 17:13:41 +0200 (CEST)


- test for owl cuts after saving lunch

This time the breakage is not as clear, because 3 owl tests uncovered a
latent problem. Still I think it is an improvement overall.

Arend

owl:18          FAIL 1 B2 [1 A2]
This one currently works for a bad reason IMHO; the cut is right. See FIXME
in sniff_lunch().
owl:45          FAIL 1 A2 [1 (E3|F1)]
owl:47          FAIL 1 A2 [1 (E3|F1)]
(With current amalgamation, this is the same problem)
Right cut, but escape analysis gets funnily confused after the cut.
Needless to say, I hope to get this right with the new_escape patch...
owl:135         FAIL 1 N17 [0]
Bad split.
strategy2:55    PASS C12 [C12]
Random.
strategy3:124   PASS C5 [C5]
Owl reading better (thought semeai still misjudged.)
nngs4:350       PASS H10 [H10]
Owl reading much better.
nngs4:470       PASS R8 [R8]
Good.
strategy5:236   PASS R12 [R12]
Very good.


Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.220
diff -u -p -r1.220 owl.c
--- engine/owl.c        28 Aug 2004 20:54:43 -0000      1.220
+++ engine/owl.c        8 Sep 2004 15:30:21 -0000
@@ -186,7 +186,8 @@ static void owl_shapes_callback(int anch
                                int ll, void *data);
 static void owl_add_move(struct owl_move_data *moves, int move, int value,
                         const char *reason, int same_dragon, int lunch,
-                        int escape, int defense_pos, int max_moves);
+                        int cuts[MAX_CUTS], int escape,
+                        int defense_pos, int max_moves);
 static void owl_determine_life(struct local_owl_data *owl,
                               struct local_owl_data *second_owl,
                                int does_attack,
@@ -214,6 +215,8 @@ static void owl_mark_boundary(struct loc
 static void owl_update_goal(int pos, int same_dragon, int lunch,
                            struct local_owl_data *owl, int semeai_call);
 static void owl_test_cuts(char goal[BOARDMAX], int color, int cuts[MAX_CUTS]);
+static void generate_lunch_cut_list(int lunch, const char goal[BOARDMAX],
+                                   int cuts[MAX_CUTS]);
 static void componentdump(const char goal[BOARDMAX]);
 static void owl_update_boundary_marks(int pos, struct local_owl_data *owl);
 static void owl_find_lunches(struct local_owl_data *owl);
@@ -728,7 +731,7 @@ do_owl_analyze_semeai(int apos, int bpos
                 && find_defense(semeai_worms[sworm], NULL)) {
          critical_semeai_worms[sworm] = 1;
          owl_add_move(moves, upos, 95, "attack semeai worm", 1, NO_MOVE,
-                      0, NO_MOVE, MAX_SEMEAI_MOVES);
+                      NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
          TRACE("Added %1m %d (-1)\n", upos, 95);
        }
       }
@@ -747,7 +750,7 @@ do_owl_analyze_semeai(int apos, int bpos
            && find_defense(semeai_worms[sworm], &upos)) {
          critical_semeai_worms[sworm] = 1;
          owl_add_move(moves, upos, 85, "defend semeai worm", 1, NO_MOVE,
-                      0, NO_MOVE, MAX_SEMEAI_MOVES);
+                      NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
          TRACE("Added %1m %d (0)\n", upos, 85);
        }
       }
@@ -981,7 +984,7 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 50,
                                     critical_semeai_worms);
       owl_add_move(moves, outside_liberty.pos, move_value,
-                  "safe outside liberty", 0, NO_MOVE, 0, NO_MOVE,
+                  "safe outside liberty", 0, NO_MOVE, NULL, 0, NO_MOVE,
                   MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (5)\n", outside_liberty.pos, move_value);
     }
@@ -990,7 +993,7 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 50,
                                     critical_semeai_worms);
       owl_add_move(moves, backfill_outside_liberty.pos, move_value,
-                  "backfilling move", 0, NO_MOVE, 0,
+                  "backfilling move", 0, NO_MOVE, NULL, 0,
                   NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (6)\n", backfill_outside_liberty.pos, move_value);
     }
@@ -1000,7 +1003,7 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 10,
                                     critical_semeai_worms);
       owl_add_move(moves, common_liberty.pos, move_value,
-                  "safe common liberty", 1, NO_MOVE, 0,
+                  "safe common liberty", 1, NO_MOVE, NULL, 0,
                   NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (7)\n", common_liberty.pos, move_value);
     }
@@ -1009,7 +1012,7 @@ do_owl_analyze_semeai(int apos, int bpos
                                     owla, owlb, 10,
                                     critical_semeai_worms);
       owl_add_move(moves, backfill_common_liberty.pos, move_value,
-                  "backfilling move", 0, NO_MOVE, 0,
+                  "backfilling move", 0, NO_MOVE, NULL, 0,
                   NO_MOVE, MAX_SEMEAI_MOVES);
       TRACE("Added %1m %d (6)\n", backfill_common_liberty.pos, move_value);
     }
@@ -1024,7 +1027,7 @@ do_owl_analyze_semeai(int apos, int bpos
 
       if (move) {
        owl_add_move(moves, move, 70, "eyespace filling", 0, NO_MOVE,
-                    0, NO_MOVE, MAX_SEMEAI_MOVES);
+                    NULL, 0, NO_MOVE, MAX_SEMEAI_MOVES);
       }
     }
 
@@ -1394,7 +1397,7 @@ semeai_review_owl_moves(struct owl_move_
                                    critical_semeai_worms)
                  + value_bonus);
     owl_add_move(semeai_moves, move, move_value, owl_moves[k].name, 
-                same_dragon, NO_MOVE, owl_moves[k].escape,
+                same_dragon, NO_MOVE, NULL, owl_moves[k].escape,
                 NO_MOVE, MAX_SEMEAI_MOVES);
     TRACE("Added %1m %d\n", move, move_value);
   }
@@ -2893,7 +2896,7 @@ owl_estimate_life(struct local_owl_data 
      */
     owl_add_move(vital_moves, dummy_moves[0].defense_pos,
                 dummy_moves[0].value, dummy_moves[0].name, 2, NO_MOVE,
-                0, NO_MOVE, MAX_MOVES);
+                NULL, 0, NO_MOVE, MAX_MOVES);
   }
 
   return 0;
@@ -3107,7 +3110,7 @@ owl_determine_life(struct local_owl_data
 
          if (attack_point != NO_MOVE) {
            owl_add_move(moves, attack_point, value, reason, 1, NO_MOVE,
-                        0, NO_MOVE, MAX_MOVES);
+                        NULL, 0, NO_MOVE, MAX_MOVES);
            vital_values[attack_point] = value;
            eyes_attack_points[num_eyes] = attack_point;
          }
@@ -3162,7 +3165,7 @@ owl_determine_life(struct local_owl_data
 
          if (defense_point != NO_MOVE) {
            owl_add_move(moves, defense_point, value, reason, 1, NO_MOVE,
-                        0, NO_MOVE, MAX_MOVES);
+                        NULL, 0, NO_MOVE, MAX_MOVES);
            vital_values[defense_point] = value;
          }
        }
@@ -3207,6 +3210,7 @@ owl_determine_life(struct local_owl_data
          value -= 10;
 
        if (does_attack) {
+         int cuts[MAX_CUTS];
          defense_point = improve_lunch_defense(owl->lunch[lunch],
                                                
owl->lunch_defense_point[lunch]);
 
@@ -3235,8 +3239,9 @@ owl_determine_life(struct local_owl_data
          TRACE("save lunch at %1m with %1m, score %d, probable eye %d, max eye 
%d\n",
                owl->lunch[lunch], defense_point, value,
                lunch_probable, lunch_max);
+         generate_lunch_cut_list(owl->lunch[lunch], owl->goal, cuts);
          owl_add_move(moves, defense_point, value,
-                      "save lunch", 1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
+                      "save lunch", 1, NO_MOVE, cuts, 0, NO_MOVE, MAX_MOVES);
        }
        else {
          attack_point = improve_lunch_attack(owl->lunch[lunch],
@@ -3252,10 +3257,10 @@ owl_determine_life(struct local_owl_data
          if (owl->lunch_attack_code[lunch] ==  WIN
              || is_illegal_ko_capture(attack_point, owl->color))
            owl_add_move(moves, attack_point, value, "eat lunch",
-                        1, owl->lunch[lunch], 0, NO_MOVE, MAX_MOVES);
+                        1, owl->lunch[lunch], NULL, 0, NO_MOVE, MAX_MOVES);
          else
            owl_add_move(moves, attack_point, value, "eat lunch",
-                        1, NO_MOVE, 0, NO_MOVE, MAX_MOVES);
+                        1, NO_MOVE, NULL, 0, NO_MOVE, MAX_MOVES);
          num_lunches++;
          eyevalue_list[num_eyes++] = e;
        }
@@ -4005,6 +4010,31 @@ generate_cut_list(struct pattern *patter
            cuts[0], cuts[1]);
 }
 
+/* This function adds all direct neighbours of the lunch into the cut list.
+ * This is used both for attack and defense.
+ */
+static void
+generate_lunch_cut_list(int lunch, const char goal[BOARDMAX],
+                       int cuts[MAX_CUTS])
+{
+  int adjs[MAXCHAIN];
+  int adj, num_cuts, k;
+
+  adj = chainlinks(lunch, adjs);
+  num_cuts = 0;
+  for (k = 0; k < adj; k++) {
+    if (goal[adjs[k]])
+      cuts[num_cuts++] = adjs[k];
+    if (num_cuts == MAX_CUTS)
+      break;
+  }
+  if (num_cuts < MAX_CUTS)
+    cuts[num_cuts] = NO_MOVE;
+  if (num_cuts > 1)
+    DEBUG(DEBUG_SPLIT_OWL, "Adding %d cuts for lunch at %1m.\n",
+         num_cuts, lunch);
+}
+
 /* This function searches in the previously stored list of matched
  * patterns for the highest valued unused patterns that have a valid
  * constraint.  It returns the moves at the next empty positions in
@@ -4296,7 +4326,7 @@ owl_shapes_callback(int anchor, int colo
   }
   
   owl_add_move(moves, move, tval, pattern->name, same_dragon, NO_MOVE,
-              escape, defense_pos, MAX_MOVES);
+              NULL, escape, defense_pos, MAX_MOVES);
 }
 
 
@@ -4305,7 +4335,7 @@ owl_shapes_callback(int anchor, int colo
 static void
 owl_add_move(struct owl_move_data *moves, int move, int value,
             const char *reason, int same_dragon, int lunch,
-            int escape, int defense_pos, int max_moves)
+            int cuts[MAX_CUTS], int escape, int defense_pos, int max_moves)
 {
   int k;
 
@@ -4354,6 +4384,12 @@ owl_add_move(struct owl_move_data *moves
        moves[k].lunch = lunch;
        moves[k].escape = escape;
        moves[k].defense_pos = defense_pos;
+       if (cuts) {
+         memcpy(moves[k].cuts, cuts, MAX_CUTS * sizeof(cuts[0]));
+         /* gprintf("Added cuts for move at %1m.\n", moves[k].pos); */
+       }
+       else
+         moves[k].cuts[0] = NO_MOVE;
       }
       break;
     }
@@ -4661,7 +4697,6 @@ owl_test_cuts(char goal[BOARDMAX], int c
 {
   int k, j;
   char connected[MAX_CUTS][MAX_CUTS];
-  /* int connect_move[MAX_CUTS][MAX_CUTS]; */
   int num_cuts;
   int found_cut = 0;
   SGFTree *save_sgf_dumptree = sgf_dumptree;
@@ -4794,6 +4829,7 @@ owl_test_cuts(char goal[BOARDMAX], int c
       showboard(0);
       componentdump(component2);
     }
+    free(conn_data);
   }
   sgf_dumptree = save_sgf_dumptree;
   count_variations = save_count_variations;
@@ -6061,12 +6097,16 @@ sniff_lunch(int lunch, int *min, int *pr
     eat_lunch_escape_bonus(lunch, min, probable, max, owl);
 }
 
+
 void
 estimate_lunch_eye_value(int lunch, int *min, int *probable, int *max,
                         int appreciate_one_two_lunches)
 {
   int other = OTHER_COLOR(board[lunch]);
   int size = countstones(lunch);
+  /* FIXME: This function should take into account half eyes that become
+   * eyse due to capturing the lunch.
+   */
 
   if (size > 6) {
     *min = 2;
Index: engine/readconnect.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.c,v
retrieving revision 1.83
diff -u -p -r1.83 readconnect.c
--- engine/readconnect.c        24 Aug 2004 14:39:53 -0000      1.83
+++ engine/readconnect.c        8 Sep 2004 15:30:21 -0000
@@ -88,6 +88,7 @@ static void order_connection_moves(int *
                                   int color_to_move, const char *funcname);
 
 static int nodes_connect = 0;
+static int fast_connection_reading = 0;
 
 /* Used by alternate connections. */
 static char connection_shadow[BOARDMAX];
@@ -1389,12 +1390,14 @@ fast_disconnect(int str1, int str2, int 
 
   modify_depth_values(-3);
   connection_node_limit /= 4;
+  fast_connection_reading = 1;
 
   if (verbose > 0)
     verbose--;
   result = recursive_disconnect2(str1, str2, move, 0);
   verbose = save_verbose;
 
+  fast_connection_reading = 0;
   connection_node_limit = save_limit;
   modify_depth_values(3);
 
@@ -2145,7 +2148,10 @@ recursive_disconnect2(int str1, int str2
   str1 = find_origin(str1);
   str2 = find_origin(str2);
 
-  attack_code1 = attack(str1, &attack_pos1);
+  if (fast_connection_reading)
+    attack_code1 = ladder_capture(str1, &attack_pos1);
+  else
+    attack_code1 = attack(str1, &attack_pos1);
   if (attack_code1 == WIN) {
     sgf_dumptree = save_sgf_dumptree;
     count_variations = save_count_variations;
@@ -2157,7 +2163,10 @@ recursive_disconnect2(int str1, int str2
     return WIN;
   }
 
-  attack_code2 = attack(str2, &attack_pos2);
+  if (fast_connection_reading)
+    attack_code2 = ladder_capture(str2, &attack_pos2);
+  else
+    attack_code2 = attack(str2, &attack_pos2);
   if (attack_code2 == WIN) {
     sgf_dumptree = save_sgf_dumptree;
     count_variations = save_count_variations;
Index: regression/connection.tst
===================================================================
RCS file: /cvsroot/gnugo/gnugo/regression/connection.tst,v
retrieving revision 1.77
diff -u -p -r1.77 connection.tst
--- regression/connection.tst   4 Sep 2004 06:25:43 -0000       1.77
+++ regression/connection.tst   8 Sep 2004 15:30:22 -0000
@@ -411,6 +411,20 @@ trymove white C15
 #? [1 B15]
 popgo
 
+# See also trevorb:470
+loadsgf games/trevor/auto/b30.sgf 68
+trymove W L5
+trymove B L4
+trymove W M4
+trymove B L3
+115 disconnect M4 M6
+#? [0]
+popgo
+popgo
+popgo
+popgo
+
+
 # Report number of nodes visited by the tactical reading
 10000 get_reading_node_counter
 #? [0]&




reply via email to

[Prev in Thread] Current Thread [Next in Thread]