gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] Patch: ALL_MOVE


From: Inge Wallin
Subject: [gnugo-devel] Patch: ALL_MOVE
Date: Tue, 22 Jan 2002 01:21:03 +0100 (MET)

Here is a patch that adds a new move reason, ALL_MOVE. This is the
next step in the plan that I outlined some time ago.  

I have also changed all usage of DEFEND_BOTH_MOVEs into ALL_MOVEs with
DEFEND_STRING as parameter.

The next step will be to generalize EITHER_MOVEs and ALL_MOVEs into
more than two parameters.

        -Inge


diff -ur gnugo-iw/engine/liberty.h gnugo-iw2/engine/liberty.h
--- gnugo-iw/engine/liberty.h   Mon Jan 21 22:15:49 2002
+++ gnugo-iw2/engine/liberty.h  Mon Jan 21 22:24:58 2002
@@ -347,10 +347,13 @@
 void add_followup_value(int pos, float value);
 void add_reverse_followup_value(int pos, float value);
 
-/* Parameters to add_either_move */
+/* Parameters to add_either_move and add_all_move */
 #define ATTACK_STRING  1
+#define DEFEND_STRING  2
 void add_either_move(int pos, int reason1, int target1,
                     int reason2, int target2);
+void add_all_move(int pos, int reason1, int target1,
+                 int reason2, int target2);
 
 
 int get_attack_threats(int pos, int max_strings, int strings[]);
diff -ur gnugo-iw/engine/move_reasons.c gnugo-iw2/engine/move_reasons.c
--- gnugo-iw/engine/move_reasons.c      Mon Jan 21 22:15:14 2002
+++ gnugo-iw2/engine/move_reasons.c     Mon Jan 21 22:50:09 2002
@@ -56,9 +56,11 @@
 int worm_pair2[MAX_WORM_PAIRS];
 int next_worm_pair;
 
-/* Unordered pairs of threats */
-Either_data either_data[MAX_EITHER];
-int         next_either;
+/* Unordered sets (currently pairs) of move reasons / targets */
+Reason_set either_data[MAX_EITHER];
+int        next_either;
+Reason_set all_data[MAX_ALL];
+int        next_all;
 
 /* Eye shapes */
 int eyes[MAX_EYES];
@@ -98,6 +100,7 @@
   next_connection = 0;
   next_worm_pair = 0;
   next_either = 0;
+  next_all = 0;
   next_eye = 0;
   next_lunch = 0;
   
@@ -266,6 +269,35 @@
   return next_either - 1;
 }
 
+static int
+find_all_data(int reason1, int what1, int reason2, int what2)
+{
+  int k;
+  
+  /* Make sure the worms are ordered canonically. */
+  if (what1 > what2) {
+    int tmp = what1;
+    what1 = what2;
+    what2 = tmp;
+  }
+
+  for (k = 0; k < next_all; k++)
+    if (all_data[k].reason1    == reason1
+       && all_data[k].what1   == what1
+       && all_data[k].reason2 == reason2
+       && all_data[k].what2   == what2)
+      return k;
+  
+  /* Add a new entry. */
+  gg_assert(next_all < MAX_ALL);
+  all_data[next_all].reason1 = reason1;
+  all_data[next_all].what1   = what1;
+  all_data[next_all].reason2 = reason2;
+  all_data[next_all].what2   = what2;
+  next_all++;
+  return next_all - 1;
+}
+
 /*
  * Find the index of an eye space in the list of eye spaces.
  * If necessary, add a new entry.
@@ -330,6 +362,9 @@
   case EITHER_MOVE:
     /* FIXME: What should we return here? */
     return worms[either_data[what].what1];
+  case ALL_MOVE:
+    /* FIXME: What should we return here? */
+    return worms[all_data[what].what1];
   case CONNECT_MOVE:
   case CUT_MOVE:
     return dragons[conn_dragon1[what]];
@@ -609,6 +644,15 @@
              && attack_move_reason_known(pos, either_data[what].what2)));
 }
 
+static int
+all_move_redundant(int pos, int what)
+{
+  return ((all_data[what].reason1 == DEFEND_STRING
+          && defense_move_reason_known(pos, all_data[what].what1))
+         || (all_data[what].reason2 == DEFEND_STRING
+             && defense_move_reason_known(pos, all_data[what].what2)));
+}
+
 
 /* ---------------------------------------------------------------- */
 
@@ -854,8 +898,7 @@
  * one of two things: either (reason1) on (target1) or (reason2) on 
  * (target2).  
  *
- * At this time, (reason) can only be ATTACK_STRING, so this is, for the
- * time being, only a complicated version of ATTACK_EITHER_MOVE.
+ * At this time, (reason) can only be ATTACK_STRING.
  * However, more reasons will be implemented in the future.
  *
  * FIXME: Implement at least ATTACK_MOVE_GOOD_KO, ATTACK_MOVE_BAD_KO,
@@ -864,7 +907,8 @@
  *
  * FIXME: Generalize to more than 2 parameters.
  *        When that is done, this will be a good way to add 
- *        atari_atari moves.  */
+ *        atari_atari moves.
+ */
 void
 add_either_move(int pos, int reason1, int target1, int reason2, int target2)
 {
@@ -921,6 +965,61 @@
 
 
 /*
+ * Add to the reasons for the move at (pos) that it will accomplish
+ * both of two things: (reason1) on (target1) and (reason2) on 
+ * (target2).  
+ *
+ * At this time, (reason) can only be DEFEND_STRING.
+ * However, more reasons will be implemented in the future.
+ *
+ * FIXME: Implement at least ATTACK_MOVE_GOOD_KO, ATTACK_MOVE_BAD_KO,
+ *         DEFEND_MOVE and associates, CONNECT_MOVE, OWL_ATTACK_MOVE,
+ *         OWL_DEFEND_MOVE, and possibly more.
+ *
+ * FIXME: Generalize to more than 2 parameters.
+ *        When that is done, this will be a good way to add 
+ *        atari_atari moves.
+ */
+void
+add_all_move(int pos, int reason1, int target1, int reason2, int target2)
+{
+  int  what1 = 0;
+  int  what2 = 0;
+  int  index;
+
+  ASSERT_ON_BOARD1(target1);
+  ASSERT_ON_BOARD1(target2);
+  if (reason1 == reason2 && target1 == target2)
+    return;
+  
+  /* For now. */
+  gg_assert(reason1 == DEFEND_STRING);
+  gg_assert(reason2 == DEFEND_STRING);
+
+  switch (reason1) {
+  case DEFEND_STRING:
+    what1 = find_worm(worm[target1].origin);
+    break;
+
+  default:
+    break;
+  }
+
+  switch (reason2) {
+  case DEFEND_STRING:
+    what2 = find_worm(worm[target2].origin);
+    break;
+
+  default:
+    break;
+  }
+
+  index = find_all_data(reason1, what1, reason2, what2);
+  add_move_reason(pos, ALL_MOVE, index);
+}
+
+
+/*
  * Add to the reasons for the move at (pos) that it defends
  * both (str1) and (str2) (e.g. from a double atari). This move
  * reason is only used for defense of own stones.
@@ -1378,6 +1477,8 @@
   int n;
   int pos;
   int k;
+  int reason1;
+  int reason2;
   int aa = NO_MOVE;
   int bb = NO_MOVE;
   int dragon1 = -1;
@@ -1494,13 +1595,18 @@
          break;
                
        case EITHER_MOVE:
+       case ALL_MOVE:
          /* FIXME: Generalize this. */
-         worm1 = either_data[move_reasons[r].what].what1;
-         worm2 = either_data[move_reasons[r].what].what2;
+         reason1 = all_data[move_reasons[r].what].reason1;
+         reason2 = all_data[move_reasons[r].what].reason2;
+         worm1 = all_data[move_reasons[r].what].what1;
+         worm2 = all_data[move_reasons[r].what].what2;
          aa = worms[worm1];
          bb = worms[worm2];
-         gprintf("Move at %1m either attacks %1m or attacks %1m\n", 
-                 pos, aa, bb);
+         gprintf("Move at %1m %s %s %1m or %s %1m\n", 
+                 pos, move_reasons[r].type == EITHER_MOVE ? "either" : "both",
+                 reason1 == ATTACK_STRING ? "attacks" : "defends", aa, 
+                 reason2 == ATTACK_STRING ? "attacks" : "defends", bb);
          break;
 
        case OWL_ATTACK_MOVE:
@@ -1608,7 +1714,10 @@
   { { EITHER_MOVE, -1 },
     either_move_redundant, REDUNDANT,
     "  %1m: 0.0 - either move is redundant at %1m (direct att./def. as 
well)\n"},
-  /* FIXME: Add handling of EITHER_MOVE */
+  /* FIXME: Add handling of ALL_MOVE: All single attacks/defenses should
+   *        be removed when there is also a corresponding ALL_MOVE.
+   */
+  /* FIXME: Add handling of ALL and EITHER moves for inessential worms. */
   { { ATTACK_MOVE, ATTACK_MOVE_GOOD_KO,
       ATTACK_MOVE_BAD_KO, ATTACK_THREAT,
       DEFEND_MOVE, DEFEND_MOVE_GOOD_KO,
diff -ur gnugo-iw/engine/move_reasons.h gnugo-iw2/engine/move_reasons.h
--- gnugo-iw/engine/move_reasons.h      Mon Jan 21 22:23:16 2002
+++ gnugo-iw2/engine/move_reasons.h     Mon Jan 21 22:28:30 2002
@@ -65,8 +65,9 @@
 
 #define ANTISUJI_MOVE           70
 
-
 #define EITHER_MOVE             100
+#define ALL_MOVE                101
+
 
 /* Bitmap values for move_reason.status */
 #define ACTIVE                  0
@@ -135,6 +136,7 @@
 #define MAX_EYES          MAX_BOARD*MAX_BOARD/2
 #define MAX_LUNCHES       MAX_WORMS
 #define MAX_EITHER        100
+#define MAX_ALL           100
 
 
 float compute_shape_factor(int pos);
@@ -161,15 +163,17 @@
 extern int worm_pair2[MAX_WORM_PAIRS];
 extern int next_worm_pair;
 
-/* Unordered pairs of threats */
+/* Unordered sets (currently pairs) of move reasons / targets */
 typedef struct {
   int reason1;
   int what1;
   int reason2;
   int what2;
-} Either_data;
-extern Either_data either_data[MAX_EITHER];
-extern int         next_either;
+} Reason_set;
+extern Reason_set either_data[MAX_EITHER];
+extern int        next_either;
+extern Reason_set all_data[MAX_ALL];
+extern int        next_all;
 
 /* Eye shapes */
 extern int eyes[MAX_EYES];
diff -ur gnugo-iw/engine/value_moves.c gnugo-iw2/engine/value_moves.c
--- gnugo-iw/engine/value_moves.c       Mon Jan 21 22:14:44 2002
+++ gnugo-iw2/engine/value_moves.c      Mon Jan 21 22:49:38 2002
@@ -92,7 +92,7 @@
            || move_reasons[r].type == CUT_MOVE
            || move_reasons[r].type == DEFEND_BOTH_MOVE)
          break;
-       /* FIXME: Add code for EITHER_MOVE here. */
+       /* FIXME: Add code for EITHER_MOVE and ALL_MOVE here. */
       }
       
       if (k == MAX_REASONS || move[ii].reason[k] == -1)
@@ -577,6 +577,7 @@
        case OWL_DEFEND_MOVE_BAD_KO:
        case MY_ATARI_ATARI_MOVE:
        case EITHER_MOVE:         /* FIXME: More advanced handling? */
+       case ALL_MOVE:            /* FIXME: More advanced handling? */
          tactical_safety = 1;
          safety = 1;
          break;
@@ -1718,6 +1719,34 @@
        tot_value += this_value;
        break;
        
+      case ALL_MOVE:
+       /* FIXME: Generalize this to more types of threats. */
+       worm1 = all_data[move_reasons[r].what].what1;
+       worm2 = all_data[move_reasons[r].what].what2;
+       aa = worms[worm1];
+       bb = worms[worm2];
+
+       /* If both worms are dead, this move reason has no value. */
+       if (dragon[aa].matcher_status == DEAD 
+           && dragon[bb].matcher_status == DEAD)
+         break;
+
+       /* Also if there is a combination attack, we assume it covers
+        * the same thing.
+        */
+       if (move_reason_known(pos, YOUR_ATARI_ATARI_MOVE, -1))
+         break;
+
+       aa_value = 2 * worm[aa].effective_size;
+       bb_value = 2 * worm[bb].effective_size;
+       this_value = 2 * gg_min(aa_value, bb_value);
+
+       TRACE("  %1m: %f - both defends %1m (%f) and defends %1m (%f)\n",
+             pos, this_value, aa, aa_value, bb, bb_value);
+
+       tot_value += this_value;
+       break;
+       
       case DEFEND_BOTH_MOVE:
        /* This is complete nonsense, but still better than nothing.
         * FIXME: Do this in a reasonable way.
@@ -1735,8 +1764,7 @@
        /* Also if there is a combination attack, we assume it covers
          * the same thing.
         */
-       if (move_reasons[r].type == DEFEND_BOTH_MOVE
-           && move_reason_known(pos, YOUR_ATARI_ATARI_MOVE, -1))
+       if (move_reason_known(pos, YOUR_ATARI_ATARI_MOVE, -1))
          break;
 
        this_value = 2 * gg_min(worm[aa].effective_size, 
diff -ur gnugo-iw/patterns/mkpat.c gnugo-iw2/patterns/mkpat.c
--- gnugo-iw/patterns/mkpat.c   Mon Jan 21 10:08:35 2002
+++ gnugo-iw2/patterns/mkpat.c  Mon Jan 21 22:59:39 2002
@@ -236,7 +236,7 @@
   {"add_connect_move",2, "add_connection_move(move,%s,%s)"},
   {"add_cut_move",    2, "add_cut_move(move,%s,%s)"},
   
{"add_attack_either_move",2,"add_either_move(move,ATTACK_STRING,%s,ATTACK_STRING,%s)"},
-  {"add_defend_both_move",2, "add_defend_both_move(move,%s,%s)"},
+  {"add_defend_both_move",2, 
"add_all_move(move,DEFEND_STRING,%s,DEFEND_STRING,%s)"},
   {"same_dragon",     2, "is_same_dragon(%s,%s)"},
   {"same_string",     2, "same_string(%s,%s)"},
   {"dragonsize",      1, "dragon[%s].size"},



reply via email to

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