gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] Patch to 3.1.15


From: Inge Wallin
Subject: [gnugo-devel] Patch to 3.1.15
Date: Sun, 2 Dec 2001 20:35:12 +0100 (MET)

Here is a patch to 3.1.15

Summary:
 - new file: engine/movelist.c
 - generalized handling of move lists and moved from worm.c
 - attack_threats() enhanced
 - AA_THREAT_DEPTH set to 3
 - some general cleanup
 - find_worm_threats() uses attack_threats more

There seems to be at least one bug in there because atari_atari:1
FAILs. But I decided to send in the patch anyway and fix the bug
later.

        -Inge


================================================================

diff -ur gnugo-sync/engine/Makefile.am gnugo-iw/engine/Makefile.am
--- gnugo-sync/engine/Makefile.am       Sat Nov  3 19:11:25 2001
+++ gnugo-iw/engine/Makefile.am Sat Dec  1 16:42:50 2001
@@ -32,6 +32,7 @@
       life.c \
       matchpat.c \
       move_reasons.c \
+      movelist.c \
       optics.c \
       owl.c \
       printutils.c \
diff -ur gnugo-sync/engine/Makefile.in gnugo-iw/engine/Makefile.in
--- gnugo-sync/engine/Makefile.in       Thu Nov 29 20:02:17 2001
+++ gnugo-iw/engine/Makefile.in Sat Dec  1 16:43:45 2001
@@ -88,7 +88,7 @@
 # preconfigured settings for various configurations
 noinst_LIBRARIES = libengine.a libboard.a
 
-libengine_a_SOURCES =        aftermath.c       board.c       cache.c       
clock.c       combination.c       dragon.c       filllib.c       fuseki.c       
genmove.c       globals.c       hash.c       influence.c       interface.c      
 life.c       matchpat.c       move_reasons.c       optics.c       owl.c       
printutils.c       readconnect.c       reading.c       score.c       semeai.c   
    sgfdecide.c       sgffile.c       shapes.c       showbord.c       utils.c   
    worm.c
+libengine_a_SOURCES =        aftermath.c       board.c       cache.c       
clock.c       combination.c       dragon.c       filllib.c       fuseki.c       
genmove.c       globals.c       hash.c       influence.c       interface.c      
 life.c       matchpat.c       move_reasons.c       movelist.c       optics.c   
    owl.c       printutils.c       readconnect.c       reading.c       score.c  
     semeai.c       sgfdecide.c       sgffile.c       shapes.c       showbord.c 
      utils.c       worm.c
 
 
 libboard_a_SOURCES =        board.c       cache.c       globals.c       hash.c 
      printutils.c       sgffile.c       showbord.c
@@ -106,7 +106,7 @@
 libengine_a_LIBADD = 
 libengine_a_OBJECTS =  aftermath.o board.o cache.o clock.o combination.o \
 dragon.o filllib.o fuseki.o genmove.o globals.o hash.o influence.o \
-interface.o life.o matchpat.o move_reasons.o optics.o owl.o \
+interface.o life.o matchpat.o move_reasons.o movelist.o optics.o owl.o \
 printutils.o readconnect.o reading.o score.o semeai.o sgfdecide.o \
 sgffile.o shapes.o showbord.o utils.o worm.o
 libboard_a_LIBADD = 
@@ -130,7 +130,7 @@
 .deps/combination.P .deps/dragon.P .deps/filllib.P .deps/fuseki.P \
 .deps/genmove.P .deps/globals.P .deps/hash.P .deps/influence.P \
 .deps/interface.P .deps/life.P .deps/matchpat.P .deps/move_reasons.P \
-.deps/optics.P .deps/owl.P .deps/printutils.P .deps/readconnect.P \
+.deps/movelist.P .deps/optics.P .deps/owl.P .deps/printutils.P 
.deps/readconnect.P \
 .deps/reading.P .deps/score.P .deps/semeai.P .deps/sgfdecide.P \
 .deps/sgffile.P .deps/shapes.P .deps/showbord.P .deps/utils.P \
 .deps/worm.P
diff -ur gnugo-sync/engine/combination.c gnugo-iw/engine/combination.c
--- gnugo-sync/engine/combination.c     Mon Nov 26 19:51:43 2001
+++ gnugo-iw/engine/combination.c       Sun Dec  2 16:34:39 2001
@@ -35,6 +35,7 @@
 static void find_double_threats(int color);
 static int is_atari(int pos, int color);
 
+
 /* Generate move reasons for combination attacks and defenses against
  * them.
  *
@@ -523,7 +524,9 @@
        continue;
 
       if (stackp < aa_threat_depth) {
-       num_moves = attack_threats(pos, moves, codes);
+       memset(moves, 0, sizeof(moves));
+       memset(codes, 0, sizeof(codes));
+       num_moves = attack_threats(pos, MAX_THREAT_MOVES, moves, codes);
        if ((debug & DEBUG_ATARI_ATARI)
           && (num_moves > 0)) {
         int i;
@@ -541,7 +544,7 @@
 
       for (k = 0; k < num_moves; k++) {
        int apos = moves[k];
-       int bpos;
+       int bpos;
 
        if (forbidden[apos])
          continue;
diff -ur gnugo-sync/engine/liberty.h gnugo-iw/engine/liberty.h
--- gnugo-sync/engine/liberty.h Thu Nov 29 20:03:25 2001
+++ gnugo-iw/engine/liberty.h   Sun Dec  2 12:05:21 2001
@@ -104,20 +104,23 @@
                      
 #define BOARD(i, j)   board[POS(i, j)]
 
-/* board utility functions */
 
+/* board utility functions */
 int find_origin(int str);
 int chainlinks(int str, int adj[MAXCHAIN]);
 int chainlinks2(int str, int adj[MAXCHAIN], int lib);
 
+
 /* This is increased by one anytime a move is (permanently) played or
  * the board is cleared.
  */
 extern int position_number;
 
+
 /* Detect vertex on edge. */
 int is_edge_vertex(int pos);
 
+
 /* Count and/or find liberties at (pos). */
 int countlib(int str);
 int findlib(int str, int maxlib, int *libs);
@@ -126,10 +129,12 @@
 int find_common_libs(int str1, int str2, int maxlib, int *libs);
 int have_common_lib(int str1, int str2, int *lib);
 
+
 void start_timer(int n);
 double time_report(int n, const char *occupation, int i, int j, 
                   double mintime);
 
+
 /* Play at (pos) and then count the liberties. */
 int accurate_approxlib(int pos, int color, int maxlib, int *libs);
 
@@ -200,6 +205,7 @@
 struct pattern_db;
 struct fullboard_pattern;
 struct half_eye_data;
+struct movelist;
 
 /*
  * Try to match a pattern in the database to the board. Callback for
@@ -219,8 +225,6 @@
 
 void reading_cache_init(int bytes);
 void reading_cache_clear(void);
-/* FIXME: Remove it from here and put it back near worm.c */
-#define MAX_TACTICAL_POINTS 10
 
 /* reading.c */
 int attack(int str, int *move);
@@ -231,8 +235,7 @@
 int attack_either(int astr, int bstr);
 int defend_both(int astr, int bstr);
 int break_through(int apos, int bpos, int cpos);
-int attack_threats(int pos, int moves[MAX_TACTICAL_POINTS], 
-                  int codes[MAX_TACTICAL_POINTS]);
+int attack_threats(int pos, int max_points, int moves[], int codes[]);
 
 int restricted_defend1(int str, int *move, int komaster, int kom_pos,
                       int num_forbidden_moves, int *forbidden_moves);
@@ -293,14 +296,11 @@
 void find_connections(void);
 void modify_eye_spaces(void);
 
-/* FIXME: Move these from worm.c */
-int  tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
-                        int codes[MAX_TACTICAL_POINTS]);
-void change_tactical_point(int str, int move, int code,
-                          int points[MAX_TACTICAL_POINTS],
-                          int codes[MAX_TACTICAL_POINTS]);
-void sort_tactical_points(int points[MAX_TACTICAL_POINTS],
-                         int codes[MAX_TACTICAL_POINTS]);
+/* movelist.c */
+int  movelist_move_known(int move, int max_points, int points[], int codes[]);
+void movelist_change_point(int move, int code, int max_points, 
+                          int points[], int codes[]);
+void movelist_sort_points(int max_points, int points[], int codes[]);
 
 
 /* functions to add (or remove) move reasons */
@@ -573,11 +573,7 @@
  * data concerning a worm. A copy is kept at each vertex of the worm.
  */
 
-#if 0
-FIXME: Reinstate it here once the functions handling these arrays
-       are moved to their own file.
 #define MAX_TACTICAL_POINTS 10
-#endif
 
 struct worm_data {
   int color;         /* its color */
@@ -607,12 +603,12 @@
    */
   int attack_points[MAX_TACTICAL_POINTS];
   int attack_codes[MAX_TACTICAL_POINTS];
-  int defend_codes[MAX_TACTICAL_POINTS];
   int defense_points[MAX_TACTICAL_POINTS];
-  int attack_threat_codes[MAX_TACTICAL_POINTS];
+  int defend_codes[MAX_TACTICAL_POINTS];
   int attack_threat_points[MAX_TACTICAL_POINTS];
-  int defense_threat_codes[MAX_TACTICAL_POINTS];
+  int attack_threat_codes[MAX_TACTICAL_POINTS]; 
   int defense_threat_points[MAX_TACTICAL_POINTS];
+  int defense_threat_codes[MAX_TACTICAL_POINTS];
 };
 
 extern struct worm_data worm[BOARDMAX];
diff -ur gnugo-sync/engine/reading.c gnugo-iw/engine/reading.c
--- gnugo-sync/engine/reading.c Thu Nov 29 20:03:39 2001
+++ gnugo-iw/engine/reading.c   Sun Dec  2 16:46:34 2001
@@ -153,10 +153,10 @@
   int nodes;
   int score;
   int remaining_depth;
-  int routine; /* ATTACK or FIND_DEFENSE */
-  int str;  /* contested string (origin) */
+  int routine;                 /* ATTACK or FIND_DEFENSE */
+  int str;                     /* contested string (origin) */
   int result;
-  int move;    /* attack/defense point */
+  int move;                    /* attack/defense point */
   int stack[MAX_CACHE_DEPTH];
   int move_color[MAX_CACHE_DEPTH];
 };
@@ -771,20 +771,27 @@
  * If the string is directly attackable the number of threats
  * is reported to be 0.
  *
+ * NOTE:  You can call attack_threats with moves[] and codes[] 
+ *        already partly filled in. So if you want to get the
+ *        threats from scratch, you have to set them to 0
+ *        yourself.
+ *
  * FIXME: Shall we report upgrades, like we can capture in ko but
  *        have a threat to capture unconditionally.
  */
 
 int
-attack_threats(int pos, int moves[MAX_TACTICAL_POINTS],
-              int codes[MAX_TACTICAL_POINTS])
+attack_threats(int pos, int max_points, int moves[], int codes[])
 {
   int  other;
   int  num_threats;
   int  liberties;
   int  libs[MAXLIBS];
+  int  num_adj;
+  int  adjs[MAXCHAIN];
   int  k;
   int  l;
+  int  r;
 
   ASSERT1(IS_STONE(board[pos]), pos);
   other = OTHER_COLOR(board[pos]);
@@ -794,9 +801,7 @@
   if (attack(pos, NULL) != 0)
     return 0;
 
-  num_threats = 0;
-
-  /* This test would seem to be unnecessary since we only attack
+  /* This test would seem to be unnecessary since we only threaten
    * strings with attack_code == 0, but it turns out that single
    * stones with one liberty that can be captured, but come to
    * live again in a snap-back get attack_code == 0.
@@ -805,21 +810,16 @@
    */
   liberties = findlib(pos, MAXLIBS, libs);
   if (liberties > 1 && liberties < 6) {
-    for (k = 0; k < liberties && num_threats < MAX_TACTICAL_POINTS; k++) {
+    for (k = 0; k < liberties; k++) {
       int aa = libs[k];
 
       /* Try to threaten on the liberty. */
-      if (trymove(aa, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+      if (trymove(aa, other, "attack_threats-A", pos, EMPTY, NO_MOVE)) {
        int acode = attack(pos, NULL);
-       if (acode != 0 && !tactical_move_known(aa, moves, codes)) {
-         moves[num_threats] = aa;
-         codes[num_threats] = acode;
-         num_threats++;
-       }
+       if (acode != 0)
+        movelist_change_point(aa, acode, max_points, moves, codes);
        popgo();
       }
-      if (num_threats == MAX_TACTICAL_POINTS)
-       break;
 
       /* Try to threaten on second order liberties. */
       for (l = 0; l < 4; l++) {
@@ -830,23 +830,66 @@
            || liberty_of_string(bb, pos))
          continue;
 
-       if (trymove(bb, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
+       if (trymove(bb, other, "attack_threats-B", pos, EMPTY, NO_MOVE)) {
          int acode = attack(pos, NULL);
-         if (acode != 0 && !tactical_move_known(bb, moves, codes)) {
-           moves[num_threats] = bb;
-           codes[num_threats] = acode;
-           num_threats++;
-         }
+         if (acode != 0)
+          movelist_change_point(bb, acode, max_points, moves, codes);
          popgo();
        }
       }
     }
   }
 
+  /* Threaten to attack by saving weak neighbors. */
+  num_adj = chainlinks(pos, adjs);
+  for (k = 0; k < num_adj; k++) {
+    int bb;
+    int dd;  /* Defense point of weak neighbor. */
+
+    if (attack(adjs[k], NULL) != 0
+       && find_defense(adjs[k], &dd) != 0) {
+
+       for (r = -1; r < max_points; r++) {
+         /* -1 is used only when stackp > 0. */
+         if (stackp > 0) {
+           if (r == -1)
+             bb = dd;
+           else
+             break;
+         }
+         else {
+           if (worm[adjs[k]].defend_codes[r] == 0)
+             break;
+           bb = worm[adjs[k]].defense_points[r];
+         }
+
+         if (trymove(bb, other, "attack_threats-C", pos, EMPTY, NO_MOVE)) {
+           int acode;
+           if (board[pos] == EMPTY)
+             acode = WIN;
+           else
+             acode = attack(pos, NULL);
+           if (acode != 0)
+             movelist_change_point(bb, acode, max_points, moves, codes);
+           popgo();
+         }
+       }
+    }
+  }
+  movelist_sort_points(max_points, moves, codes);
+
 
   /* FIXME: Threaten to attack by saving weak neighbors.
-   *        Get it from worm.c. */
+   *        Get it from worm.c.
+   */
+
 
+  /* Return actual number of threats found regardless of attack code. */
+  if (codes[max_points - 1] > 0)
+    return max_points;
+  for (num_threats = 0; num_threats < max_points; num_threats++)
+    if (codes[num_threats] == 0)
+      break;
   return num_threats;
 }
 
diff -ur gnugo-sync/engine/utils.c gnugo-iw/engine/utils.c
--- gnugo-sync/engine/utils.c   Mon Nov 26 19:52:07 2001
+++ gnugo-iw/engine/utils.c     Thu Nov 29 22:25:15 2001
@@ -465,7 +465,7 @@
 #define KO_DEPTH              8
 
 #define AA_DEPTH              6
-#define AA_THREAT_DEPTH       1
+#define AA_THREAT_DEPTH       3
 
 /* Pattern based reading */
 #define OWL_DISTRUST_DEPTH    6
diff -ur gnugo-sync/engine/worm.c gnugo-iw/engine/worm.c
--- gnugo-sync/engine/worm.c    Mon Nov 26 19:52:08 2001
+++ gnugo-iw/engine/worm.c      Sun Dec  2 16:07:19 2001
@@ -32,23 +32,14 @@
 static void compute_unconditional_status(void);
 static void find_worm_attacks_and_defenses(void);
 static void find_worm_threats(void);
-static int find_lunch(int str, int *lunch);
-#if 0
-static int tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
-                              int codes[MAX_TACTICAL_POINTS]);
+static int  find_lunch(int str, int *lunch);
 static void change_tactical_point(int str, int move, int code,
                                  int points[MAX_TACTICAL_POINTS],
                                  int codes[MAX_TACTICAL_POINTS]);
-static void sort_tactical_points(int points[MAX_TACTICAL_POINTS],
-                                int codes[MAX_TACTICAL_POINTS]);
-#endif
-static void swap_points_and_codes(int points[MAX_TACTICAL_POINTS],
-                                 int codes[MAX_TACTICAL_POINTS],
-                                 int m, int n);
 static void propagate_worm2(int str);
-static int genus(int str);
+static int  genus(int str);
 static void markcomponent(int str, int pos, int mg[BOARDMAX]);
-static int examine_cavity(int pos, int *edge);
+static int  examine_cavity(int pos, int *edge);
 static void cavity_recurse(int pos, int mx[BOARDMAX], 
                           int *border_color, int *edge, int str);
 static void ping_cave(int str, int *result1,  int *result2,
@@ -56,7 +47,7 @@
 static void ping_recurse(int pos, int *counter, 
                         int mx[BOARDMAX], 
                         int mr[BOARDMAX], int color);
-static int touching(int pos, int color);
+static int  touching(int pos, int color);
 static void find_attack_patterns(void);
 static void attack_callback(int m, int n, int color,
                            struct pattern *pattern, int ll, void *data);
@@ -959,12 +950,9 @@
       int pos = POS(m, n);
       int liberties;
       static int libs[MAXLIBS];
-      int adj;
-      int adjs[MAXCHAIN];
 
       int k;
       int l;
-      int r;
       int color;
       int other;
 
@@ -978,54 +966,18 @@
       /* 1. Start with finding attack threats. */
       /* Only try those worms that have no attack. */
       if (worm[pos].attack_codes[0] == 0) {
-
-       liberties = findlib(pos, MAXLIBS, libs);
-
-       /* This test would seem to be unnecessary since we only attack
-        * strings with attack_code == 0, but it turns out that single
-        * stones with one liberty that can be captured, but come to
-        * live again in a snap-back get attack_code == 0. 
-        *
-        * The test against 6 liberties is just an optimization.
-        */
-       if (liberties > 1 && liberties < 6) {
-         for (k = 0; k < liberties; k++) {
-           int aa = libs[k];
-
-           /* Try to threaten on the liberty. */
-           if (trymove(aa, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
-             int acode = attack(pos, NULL);
-             if (acode != 0)
-               change_attack_threat(pos, aa, acode);
-             popgo();
-           }
-
-           /* Try to threaten on second order liberties. */
-           for (l = 0; l < 4; l++) {
-             int bb = libs[k] + delta[l];
-
-             if (!ON_BOARD(bb)
-                 || IS_STONE(board[bb])
-                 || liberty_of_string(bb, pos))
-               continue;
-
-             if (trymove(bb, other, "threaten attack", pos, EMPTY, NO_MOVE)) {
-               int acode = attack(pos, NULL);
-               if (acode != 0)
-                 change_attack_threat(pos, bb, acode);
-               popgo();
-             }
-           }
-         }
-       }
-
+       attack_threats(pos, MAX_TACTICAL_POINTS,
+                      worm[pos].attack_threat_points,
+                      worm[pos].attack_threat_codes);
+#if 0
        /* Threaten to attack by saving weak neighbors. */
-       adj = chainlinks(pos, adjs);
-       for (k = 0; k < adj; k++)
+       num_adj = chainlinks(pos, adjs);
+       for (k = 0; k < num_adj; k++) {
          if (worm[adjs[k]].attack_codes[0] != 0
              && worm[adjs[k]].defend_codes[0] != 0)
            for (r = 0; r < MAX_TACTICAL_POINTS; r++) {
              int bb;
+
              if (worm[adjs[k]].defend_codes[r] == 0)
                break;
              bb = worm[adjs[k]].defense_points[r];
@@ -1041,7 +993,8 @@
                popgo();
              }
            }
-       
+       }
+#endif
        /* FIXME: Try other moves also (patterns?). */
       }
 
@@ -1251,7 +1204,8 @@
  */
 int attack_move_known(int move, int str)
 {
-  return tactical_move_known(move, worm[str].attack_points,
+  return movelist_move_known(move, MAX_TACTICAL_POINTS,
+                            worm[str].attack_points,
                             worm[str].attack_codes);
 }
 
@@ -1260,7 +1214,8 @@
  */
 int defense_move_known(int move, int str)
 {
-  return tactical_move_known(move, worm[str].defense_points,
+  return movelist_move_known(move, MAX_TACTICAL_POINTS,
+                            worm[str].defense_points,
                             worm[str].defend_codes);
 }
 
@@ -1271,7 +1226,8 @@
 int
 attack_threat_move_known(int move, int str)
 {
-  return tactical_move_known(move, worm[str].attack_threat_points,
+  return movelist_move_known(move, MAX_TACTICAL_POINTS,
+                            worm[str].attack_threat_points,
                             worm[str].attack_threat_codes);
 }
 
@@ -1282,25 +1238,11 @@
 int
 defense_threat_move_known(int move, int str)
 {
-  return tactical_move_known(move, worm[str].defense_threat_points,
+  return movelist_move_known(move, MAX_TACTICAL_POINTS,
+                            worm[str].defense_threat_points,
                             worm[str].defense_threat_codes);
 }
 
-/* Do the real work for the functions above. */
-int
-tactical_move_known(int move, int points[MAX_TACTICAL_POINTS],
-                   int codes[MAX_TACTICAL_POINTS])
-{
-  int k;
-  for (k = 0; k < MAX_TACTICAL_POINTS; k++) {
-    if (codes[k] == 0)
-      return 0;
-    if (points[k] == move)
-      return codes[k];
-  }
-  return 0;
-}
-
 
 /*
  * This function does the real work for change_attack(),
@@ -1308,89 +1250,16 @@
  * change_defense_threat().
  */
 
-void
+static void
 change_tactical_point(int str, int move, int code,
                      int points[MAX_TACTICAL_POINTS],
                      int codes[MAX_TACTICAL_POINTS])
 {
-  int k;
-
   gg_assert(ON_BOARD(str));
   gg_assert(str == worm[str].origin);
   
-  /* First see if we already knew about this defense point. */
-  for (k = 0; k < MAX_TACTICAL_POINTS; k++)
-    if (points[k] == move)
-      break;
-
-  /* Yes, we did. */
-  if (k < MAX_TACTICAL_POINTS) {
-    if (codes[k] == code)
-      return; /* Old news. */
-
-    codes[k] = code;
-    sort_tactical_points(points, codes);
-    propagate_worm2(str);
-    return;
-  }
-
-  /* This defense point is news to us. */
-  if (code > codes[MAX_TACTICAL_POINTS-1]) {
-    points[MAX_TACTICAL_POINTS - 1] = move;
-    codes[MAX_TACTICAL_POINTS - 1] = code;
-    sort_tactical_points(points, codes);
-    propagate_worm2(str);
-  }
-}
-
-
-/* Sort the tactical points so we have it sorted in falling order on
- * the code values.
- *
- * We use shaker sort because we prefer a stable sort and in all use
- * cases we can expect it to suffice with one turn through the outer
- * loop.
- */
-
-void
-sort_tactical_points(int points[MAX_TACTICAL_POINTS],
-                    int codes[MAX_TACTICAL_POINTS])
-{
-  int start = 0;
-  int end = MAX_TACTICAL_POINTS - 1;
-  int new_start;
-  int new_end;
-  int k;
-  
-  while (start < end) {
-    new_start = end;
-    for (k = end; k > start; k--)
-      if (codes[k] > codes[k-1]) {
-       swap_points_and_codes(points, codes, k, k-1);
-       new_start = k;
-      }
-    start = new_start;
-    new_end = start;
-    for (k = start; k < end - 1; k++)
-      if (codes[k] < codes[k+1]) {
-       swap_points_and_codes(points, codes, k, k+1);
-       new_end = k;
-      }
-    end = new_end;
-  }
-}
-
-static void
-swap_points_and_codes(int points[MAX_TACTICAL_POINTS],
-                     int codes[MAX_TACTICAL_POINTS],
-                     int m, int n)
-{
-  int tmp = points[m];
-  points[m] = points[n];
-  points[n] = tmp;
-  tmp = codes[m];
-  codes[m] = codes[n];
-  codes[n] = tmp;
+  movelist_change_point(move, code, MAX_TACTICAL_POINTS, points, codes);
+  propagate_worm2(str);
 }
 
 



reply via email to

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