gnugo-devel
[Top][All Lists]
Advanced

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

[gnugo-devel] mixed patch


From: Gunnar Farneback
Subject: [gnugo-devel] mixed patch
Date: Mon, 25 Mar 2002 20:49:59 +0100
User-agent: EMH/1.14.1 SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.3 Emacs/20.7 (sparc-sun-solaris2.7) (with unibyte mode)

- simulation of ko threat + answer in sgf output reinstated in tryko()
- new function gg_normalize_float() in gg_utils.c
- platform dependency fixed in readconnect.c by using gg_normalize_float() 
- scoring tweaks and optimizations
- bugfix in gg_cputime()

The patch reverts a change Trevor made in the sgf output from tryko(),
for reasons explained as a new comment to the code (see patch below).

The changes in genmove.c, value_moves.c, endgame.db, and patterns.db
solves some scoring mistakes and speeds up the aftermath scoring.
3.1.28 fails 6 of 29 tests in score.tst. After this patch only one
test fails.

The bugfix in gg_cputime() is as proposed in an earlier message.

Finally, the change in readconnect.c together with the new
gg_normalize_float() function addresses and hopefully solves a
platform dependency problem with connection:72. See the comment above
gg_normalize_float() in the patch for an explanation.

/Gunnar

Index: engine/board.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/board.c,v
retrieving revision 1.44
diff -u -r1.44 board.c
--- engine/board.c      25 Mar 2002 07:39:18 -0000      1.44
+++ engine/board.c      25 Mar 2002 18:43:36 -0000
@@ -603,13 +603,20 @@
     else
       gg_snprintf(buf, 100, "tryko: %s (variation %d, %lx)", 
                  message, count_variations, hashdata.hashval[0]);
-    if (0) {
-      /* tm - I don't find these pass moves helpful in the tree. */
-      sgftreeAddPlayLast(sgf_dumptree, NULL, color, -1, -1);
-      sgftreeAddComment(sgf_dumptree, NULL, "tenuki (ko threat)");
-      sgftreeAddPlayLast(sgf_dumptree, NULL, OTHER_COLOR(color), -1, -1);
-      sgftreeAddComment(sgf_dumptree, NULL, "tenuki (answers ko threat)");
-    }
+
+    /* Add two pass moves to the SGF output to simulate the ko threat
+     * and the answer.
+     *
+     * The reason we add these is that certain SGF viewers, including
+     * Cgoban 1, won't properly display variations with illegal ko
+     * captures. SGF FF[4] compliant browsers should have no problem
+     * with this, though.
+     */
+    sgftreeAddPlayLast(sgf_dumptree, NULL, color, -1, -1);
+    sgftreeAddComment(sgf_dumptree, NULL, "tenuki (ko threat)");
+    sgftreeAddPlayLast(sgf_dumptree, NULL, OTHER_COLOR(color), -1, -1);
+    sgftreeAddComment(sgf_dumptree, NULL, "tenuki (answers ko threat)");
+
     sgftreeAddPlayLast(sgf_dumptree, NULL, color, I(pos), J(pos));
     sgftreeAddComment(sgf_dumptree, NULL, buf);
   }
Index: engine/genmove.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/genmove.c,v
retrieving revision 1.33
diff -u -r1.33 genmove.c
--- engine/genmove.c    25 Mar 2002 07:39:18 -0000      1.33
+++ engine/genmove.c    25 Mar 2002 18:43:36 -0000
@@ -449,10 +449,11 @@
    * dragon dangerous and change its status from DEAD to
    * UNKNOWN. This may generate a move.
    */
-  if (val < 10.0) {
+  if (val < 10.0 && !doing_scoring) {
     if (revise_thrashing_dragon(color, 15.0)) {
       shapes(color);
-      endgame_shapes(color);
+      if (!disable_endgame_patterns)
+       endgame_shapes(color);
       if (review_move_reasons(move, &val, color, pure_threat_value, score)) {
        TRACE("Upon reconsideration move generation likes %1m with value %f\n",
              *move, val); 
Index: engine/owl.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v
retrieving revision 1.75
diff -u -r1.75 owl.c
--- engine/owl.c        25 Mar 2002 07:39:18 -0000      1.75
+++ engine/owl.c        25 Mar 2002 18:43:40 -0000
@@ -4903,7 +4903,7 @@
   for (k = 0; k < persistent_owl_cache_size; k++) {
     struct owl_cache *entry = &(persistent_owl_cache[k]);
     float contribution = entry->tactical_nodes / (float) sum_tactical_nodes;
-    if (DEBUG_OWL_PERSISTENT_CACHE) {
+    if (debug & DEBUG_OWL_PERSISTENT_CACHE) {
       gprintf("Owl hotspots: %d %1m %f\n", entry->routine, entry->apos,
              contribution);
     }
Index: engine/readconnect.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.c,v
retrieving revision 1.29
diff -u -r1.29 readconnect.c
--- engine/readconnect.c        25 Mar 2002 07:39:18 -0000      1.29
+++ engine/readconnect.c        25 Mar 2002 18:43:43 -0000
@@ -28,6 +28,7 @@
 
 #include "liberty.h"
 #include "cache.h"
+#include "gg_utils.h"
 
 /* Size of array where candidate moves are stored. */
 #define MAX_MOVES 362
@@ -2257,6 +2258,13 @@
     }
     
   }
+
+  /* Normalize distance values. See comment to gg_normalize_float() in
+   * utils/gg_utils.c for an explanation of this operation. It is
+   * assumed that all distance values are integral multiples of 0.001.
+   */
+  for (i = 0; i < num_moves; i++)
+    distances[i] = gg_normalize_float(distances[i], 0.001);
   
   /* Now sort the moves.  We use selection sort since this array will
    * probably never be more than 10 moves long.  In this case, the
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.20
diff -u -r1.20 value_moves.c
--- engine/value_moves.c        25 Mar 2002 15:25:27 -0000      1.20
+++ engine/value_moves.c        25 Mar 2002 18:43:46 -0000
@@ -820,6 +820,10 @@
          || dragon_safety == TACTICALLY_DEAD))
     return 1.0;
 
+  /* When scoring, we don't want to reinforce ALIVE dragons. */
+  if (doing_scoring && dragon_safety == ALIVE)
+    return 1.0;
+  
   /* More detailed guesses for WEAK and WEAKLY_ALIVE dragons. */
   if (dragon_safety == WEAK || dragon_safety == WEAKLY_ALIVE) {
     int escape = DRAGON2(dr).escape_route;
@@ -948,20 +952,18 @@
   
 
   /* When scoring, we want to be restrictive with reinforcement moves
-   * inside own territory. Thus if both dragons are strongly alive or
-   * invincible, or if one is and the other is alive, no bonus is
-   * awarded.
+   * inside own territory. Thus if both dragons are alive, strongly
+   * alive, or invincible, no bonus is awarded.
    *
    * Notice that this requires that the territorial value is computed
    * before the strategical value.
    */
   if (doing_scoring && move[tt].territorial_value < 0.0) {
-    if (safety1 == ALIVE
-       && (safety2 == STRONGLY_ALIVE || safety2 == INVINCIBLE))
-      return 0.0;
-    
-    if ((safety1 == STRONGLY_ALIVE || safety1 == INVINCIBLE)
-       && (safety2 == ALIVE || safety2 == STRONGLY_ALIVE
+    if ((safety1 == ALIVE
+        || safety1 == STRONGLY_ALIVE
+        || safety1 == INVINCIBLE)
+       && (safety2 == ALIVE
+           || safety2 == STRONGLY_ALIVE
            || safety2 == INVINCIBLE))
       return 0.0;
   }
@@ -1773,7 +1775,7 @@
                    "  %1m:   %f - %1m attacked/defended\n",
                    pos, this_value, bb);
              dragon_value[d1] = this_value;
-         }
+           }
          }
 
        break;
Index: patterns/endgame.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/endgame.db,v
retrieving revision 1.30
diff -u -r1.30 endgame.db
--- patterns/endgame.db 21 Feb 2002 19:26:36 -0000      1.30
+++ patterns/endgame.db 25 Mar 2002 18:43:46 -0000
@@ -1172,12 +1172,13 @@
 # tm New Pattern (3.1.16)
 # tm modified (3.1.17)
 # tm modified (3.1.20)
+# gf Removed terri(1) value. (3.1.29)
 # FIXME: see endgame:218, trevord:1030, trevorc:430
 
 O.
 *O
 
-:8,O,terri(1),reverse_followup(3)
+:8,O,reverse_followup(3)
 
 ac
 *b
Index: patterns/patterns.db
===================================================================
RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.db,v
retrieving revision 1.59
diff -u -r1.59 patterns.db
--- patterns/patterns.db        25 Mar 2002 15:25:27 -0000      1.59
+++ patterns/patterns.db        25 Mar 2002 18:43:49 -0000
@@ -13629,6 +13629,7 @@
 
 Pattern LE15Y
 # tm decreased value (3.1.20) (see nngs:1150 move G4)
+# gf Don't bother with this inside own territory. (3.1.29)
 
 xxx            jump towards moyo
 x.x
@@ -13639,6 +13640,16 @@
 ?o?
 
 :|,OEY
+
+xxx
+x.x
+.*.
+...
+...
+OoO
+?o?
+
+;!oterri(*)
 
 
 Pattern LE16
Index: utils/gg_utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/utils/gg_utils.c,v
retrieving revision 1.23
diff -u -r1.23 gg_utils.c
--- utils/gg_utils.c    5 Mar 2002 03:24:04 -0000       1.23
+++ utils/gg_utils.c    25 Mar 2002 18:43:52 -0000
@@ -80,6 +80,9 @@
 
 /* for gg_cputime */
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #ifdef HAVE_SYS_TIMES_H
 #include <sys/times.h>
 #elif defined(WIN32)
@@ -275,11 +278,11 @@
 double
 gg_cputime(void)
 {
-#if HAVE_SYS_TIMES_H && HAVE_TIMES
+#if HAVE_SYS_TIMES_H && HAVE_TIMES && HAVE_UNISTD_H
     struct tms t;
     times(&t);
     return (t.tms_utime + t.tms_stime + t.tms_cutime + t.tms_cstime)
-            / ((double) CLOCKS_PER_SEC);
+            / ((double) sysconf(_SC_CLK_TCK));
 #elif defined(WIN32)
     FILETIME creationTime, exitTime, kernelTime, userTime;
     ULARGE_INTEGER uKernelTime, uUserTime, uElapsedTime;
@@ -302,6 +305,37 @@
     /* return wall clock seconds */
     return gg_gettimeofday();
 #endif
+}
+
+/* Before we sort floating point values (or just compare them) we
+ * may need to normalize them. This may sound cryptic but is
+ * required to avoid an obscure platform dependency.
+ *
+ * The underlying problem is that most fractional decimal numbers
+ * can't be represented exactly in a floating point number with base
+ * two. The error may be small but it is there. When such numbers
+ * are added or subtracted, the errors accumulate and even if the
+ * result (counting exactly) should be a number which can be
+ * represented exactly, this cannot be assumed to be the case.
+ *
+ * To give an example of this, the computation 0.3 + 0.05 - 0.35 may
+ * sum to 0, a small negative value, or a small positive value.
+ * Moreover, which case we encounter depends on the number of
+ * mantissa bits in the floating point type used and the exact
+ * details of the floating point arithmetic on the platform.
+ *
+ * In the context of sorting, assume that two values both should be
+ * 0.35, but one has been computed as 0.3 + 0.05 and the other
+ * directly assigned 0.35. Then it depends on the platform whether
+ * they compare as equal or one of them is larger than the other.
+ *
+ * This code normalizes the values to avoid this problem. It is
+ * assumed that all values encountered are integer multiples of a.
+ */
+float
+gg_normalize_float(float x, float a)
+{
+  return a * ((int) (0.5 + x / a));
 }
 
 /* A sorting algorithm, call-compatible with the libc qsort() function.
Index: utils/gg_utils.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/utils/gg_utils.h,v
retrieving revision 1.8
diff -u -r1.8 gg_utils.h
--- utils/gg_utils.h    4 Mar 2002 06:49:09 -0000       1.8
+++ utils/gg_utils.h    25 Mar 2002 18:43:52 -0000
@@ -62,6 +62,7 @@
 double gg_gettimeofday(void);
 double gg_cputime(void);
 
+float gg_normalize_float(float x, float a);
 void gg_sort(void *base, size_t nel, size_t width,
             int (*compar)(const void *, const void *));
 



reply via email to

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