[Top][All Lists]
[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 *));
- [gnugo-devel] mixed patch,
Gunnar Farneback <=