[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] score.c
From: |
Arend Bayer |
Subject: |
[gnugo-devel] score.c |
Date: |
Thu, 6 Jan 2005 00:30:52 +0100 (CET) |
I suggest we stop using Bouzy's score algorithm in score.c. I have run it
in comparison with an influence-based score computations while running
my robot on KGS for a while; while the two are
often pretty close, the algorithm in score.c is sometimes completely
off-base in the fuseki, especially in handicap games. In other situations,
it fails to take into account a good estimate of potential territory.
The score estimate is now done automatically in examine_position(), and
it sets the new global variables black_score and white_score. I don't like
global variables either, but I think that's what they are, similar to
all the dragon_data or initial_black_influence etc.
To compute the score, the influence code is called with color EMPTY, but
with critical stones resolved in favor of either color to get a conservative
and a optimistic score estimate.
One more change: should_resign is now called with optimistic_score instead
of average_score, as this has caused sudden resignations when the opponent
was playing a threat against one of our groups.
Arend
Index: engine/Makefile.am
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/Makefile.am,v
retrieving revision 1.22
diff -u -p -r1.22 Makefile.am
--- engine/Makefile.am 15 May 2004 18:13:41 -0000 1.22
+++ engine/Makefile.am 5 Jan 2005 23:13:26 -0000
@@ -43,7 +43,6 @@ libengine_a_SOURCES = \
printutils.c \
readconnect.c \
reading.c \
- score.c \
semeai.c \
sgfdecide.c \
sgffile.c \
Index: engine/Makefile.in
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/Makefile.in,v
retrieving revision 1.48
diff -u -p -r1.48 Makefile.in
--- engine/Makefile.in 28 May 2004 03:09:13 -0000 1.48
+++ engine/Makefile.in 5 Jan 2005 23:13:26 -0000
@@ -123,7 +123,6 @@ libengine_a_SOURCES = \
printutils.c \
readconnect.c \
reading.c \
- score.c \
semeai.c \
sgfdecide.c \
sgffile.c \
Index: engine/aftermath.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/aftermath.c,v
retrieving revision 1.51
diff -u -p -r1.51 aftermath.c
--- engine/aftermath.c 18 Dec 2004 19:32:43 -0000 1.51
+++ engine/aftermath.c 5 Jan 2005 23:13:26 -0000
@@ -807,7 +807,6 @@ reduced_genmove(int color)
{
float value;
int save_verbose;
- float upper_bound, lower_bound;
float our_score;
int move;
@@ -821,29 +820,13 @@ reduced_genmove(int color)
/* Find out information about the worms and dragons. */
examine_position(EXAMINE_ALL);
- /* Make a score estimate. This can be used in later stages of the
- * move generation. If we are ahead, we can play safely and if
- * we are behind, we have to play more daringly.
- */
- estimate_score(&upper_bound, &lower_bound);
- if (verbose || showscore) {
- if (lower_bound == upper_bound)
- gprintf("\nScore estimate: %s %f\n",
- lower_bound > 0 ? "W " : "B ", gg_abs(lower_bound));
- else
- gprintf("\nScore estimate: %s %f to %s %f\n",
- lower_bound > 0 ? "W " : "B ", gg_abs(lower_bound),
- upper_bound > 0 ? "W " : "B ", gg_abs(upper_bound));
- fflush(stderr);
- }
-
/* The score will be used to determine when we are safely
* ahead. So we want the most conservative score.
*/
if (color == WHITE)
- our_score = lower_bound;
+ our_score = black_score;
else
- our_score = -upper_bound;
+ our_score = -white_score;
gg_assert(stackp == 0);
Index: engine/genmove.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/genmove.c,v
retrieving revision 1.103
diff -u -p -r1.103 genmove.c
--- engine/genmove.c 5 Jan 2005 16:43:03 -0000 1.103
+++ engine/genmove.c 5 Jan 2005 23:13:26 -0000
@@ -54,7 +54,8 @@ static int revise_thrashing_dragon(int c
static void break_mirror_go(int color);
static int find_mirror_move(int *move, int color);
-static int should_resign(int color, float our_score, int move);
+static int should_resign(int color, float optimistic_score, int move);
+static void compute_scores(void);
/* Reset some things in the engine.
@@ -148,6 +149,7 @@ examine_position(int how_much)
if (NEEDS_UPDATE(dragons_examined)) {
make_dragons(0);
+ compute_scores();
/* We have automatically done a partial dragon analysis as well. */
dragons_examined_without_owl = position_number;
}
@@ -161,6 +163,7 @@ examine_position(int how_much)
|| how_much == EXAMINE_DRAGONS
|| how_much == EXAMINE_ALL) {
initialize_dragon_data();
+ compute_scores();
verbose = save_verbose;
gg_assert(test_gray_border() < 0);
return;
@@ -292,8 +295,7 @@ static int
do_genmove(int color, float pure_threat_value,
int allowed_moves[BOARDMAX], float *value, int *resign)
{
- float upper_bound, lower_bound;
- float average_score, our_score;
+ float average_score, pessimistic_score, optimistic_score;
int save_verbose;
int save_depth;
int move;
@@ -345,27 +347,6 @@ do_genmove(int color, float pure_threat_
examine_position(EXAMINE_ALL);
time_report(1, "examine position", NO_MOVE, 1.0);
- /* Make a score estimate. This can be used in later stages of the
- * move generation. If we are ahead, we can play safely and if
- * we are behind, we have to play more daringly.
- */
- estimate_score(&upper_bound, &lower_bound);
- if (verbose || showscore) {
- if (lower_bound == upper_bound)
- gprintf("\nScore estimate: %s %f\n",
- lower_bound > 0 ? "W " : "B ", gg_abs(lower_bound));
- else
- gprintf("\nScore estimate: %s %f to %s %f\n",
- lower_bound > 0 ? "W " : "B ", gg_abs(lower_bound),
- upper_bound > 0 ? "W " : "B ", gg_abs(upper_bound));
- fflush(stderr);
- }
- time_report(1, "estimate score", NO_MOVE, 1.0);
- if (color == WHITE)
- average_score = (upper_bound + lower_bound)/2.0;
- else
- average_score = -(upper_bound + lower_bound)/2.0;
- choose_strategy(color, average_score, game_status(color));
/* The score will be used to determine when we are safely
* ahead. So we want the most conservative score.
@@ -373,17 +354,21 @@ do_genmove(int color, float pure_threat_
* We always want to have the score from our point of view. So
* negate it if we are black.
*/
+ if (color == WHITE) {
+ pessimistic_score = black_score;
+ optimistic_score = white_score;
+ }
+ else {
+ pessimistic_score = -white_score;
+ optimistic_score = -black_score;
+ }
+
if (color == WHITE)
- our_score = lower_bound;
+ average_score = (white_score + black_score)/2.0;
else
- our_score = -upper_bound;
+ average_score = -(white_score + black_score)/2.0;
+ choose_strategy(color, average_score, game_status(color));
- /*
- * Print some of the information if the user wants to.
- */
- if (printmoyo)
- print_moyo();
-
if (printboard) {
if (printboard == 1)
fprintf(stderr, "\n dragon_status display:\n\n");
@@ -427,7 +412,7 @@ do_genmove(int color, float pure_threat_
*/
if (!doing_scoring && !limit_search)
use_thrashing_dragon_heuristics
- = revise_thrashing_dragon(color, our_score, 5.0);
+ = revise_thrashing_dragon(color, pessimistic_score, 5.0);
/* The general pattern database. */
shapes(color);
@@ -441,7 +426,7 @@ do_genmove(int color, float pure_threat_
/* Review the move reasons and estimate move values. */
if (review_move_reasons(&move, value, color,
- pure_threat_value, our_score, allowed_moves,
+ pure_threat_value, pessimistic_score, allowed_moves,
use_thrashing_dragon_heuristics))
TRACE("Move generation likes %1m with value %f\n", move, *value);
gg_assert(stackp == 0);
@@ -453,8 +438,8 @@ do_genmove(int color, float pure_threat_
endgame_shapes(color);
endgame(color);
gg_assert(stackp == 0);
- if (review_move_reasons(&move, value, color, pure_threat_value, our_score,
- allowed_moves,
+ if (review_move_reasons(&move, value, color, pure_threat_value,
+ pessimistic_score, allowed_moves,
use_thrashing_dragon_heuristics))
TRACE("Move generation likes %1m with value %f\n", move, *value);
gg_assert(stackp == 0);
@@ -470,7 +455,7 @@ do_genmove(int color, float pure_threat_
shapes(color);
endgame_shapes(color);
if (review_move_reasons(&move, value, color, pure_threat_value,
- our_score, allowed_moves,
+ pessimistic_score, allowed_moves,
use_thrashing_dragon_heuristics)) {
TRACE("Upon reconsideration move generation likes %1m with value %f\n",
move, *value);
@@ -500,7 +485,7 @@ do_genmove(int color, float pure_threat_
if (move == PASS_MOVE && !doing_scoring) {
if (play_out_aftermath
|| capture_all_dead
- || (thrashing_dragon && our_score > 15.0))
+ || (thrashing_dragon && pessimistic_score > 15.0))
move = aftermath_genmove(color, 0, allowed_moves);
/* If we're instructed to capture all dead opponent stones, generate
@@ -530,7 +515,7 @@ do_genmove(int color, float pure_threat_
/* Maybe time to resign...
*/
if (resign && resign_allowed
- && *value < 10.0 && should_resign(color, our_score, move)) {
+ && *value < 10.0 && should_resign(color, optimistic_score, move)) {
TRACE("... though, genmove() thinks the position is hopeless\n");
*resign = 1;
}
@@ -709,6 +694,37 @@ find_mirror_move(int *move, int color)
return 0;
}
+/* Computer two territory estimates: for *upper, the status of all
+ * cricital stones gets resolved in White's favor; vice verso for
+ * black.
+ */
+static void
+compute_scores()
+{
+ char safe_stones[BOARDMAX];
+ float strength[BOARDMAX];
+
+ set_strength_data(WHITE, safe_stones, strength);
+ compute_influence(EMPTY, safe_stones, strength, &move_influence,
+ NO_MOVE, "White territory estimate");
+ white_score = influence_score(&move_influence);
+ set_strength_data(BLACK, safe_stones, strength);
+ compute_influence(EMPTY, safe_stones, strength, &move_influence,
+ NO_MOVE, "White territory estimate");
+ black_score = influence_score(&move_influence);
+
+ if (verbose || showscore) {
+ if (white_score == black_score)
+ gprintf("Score estimate: %s %f\n",
+ black_score > 0 ? "W " : "B ", gg_abs(black_score));
+ else
+ gprintf("Score estimate: %s %f to %s %f\n",
+ black_score > 0 ? "W " : "B ", gg_abs(black_score),
+ white_score > 0 ? "W " : "B ", gg_abs(white_score));
+ fflush(stderr);
+ }
+}
+
/* Detect if a white opponent has played mirror go for at least 10
* moves and if so play on tengen.
@@ -733,7 +749,7 @@ break_mirror_go(int color)
/* Helper to decide whether GG should resign a game
*/
static int
-should_resign(int color, float our_score, int move)
+should_resign(int color, float optimistic_score, int move)
{
float status;
int d;
@@ -750,7 +766,7 @@ should_resign(int color, float our_score
if (move == PASS_MOVE
|| board_size < 19
- || our_score > -45.0)
+ || optimistic_score > -45.0)
return 0;
/* Check dragon statuses. If a friendly dragon is critical, we are
* possibly not that much behind after we save it. If some hostile
Index: engine/globals.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/globals.c,v
retrieving revision 1.70
diff -u -p -r1.70 globals.c
--- engine/globals.c 7 Dec 2004 04:50:02 -0000 1.70
+++ engine/globals.c 5 Jan 2005 23:13:27 -0000
@@ -131,6 +131,8 @@ int gtp_version = 2; /* Use G
float best_move_values[10];
int best_moves[10];
+float white_score;
+float black_score;
int close_worms[BOARDMAX][4];
int number_close_worms[BOARDMAX];
Index: engine/gnugo.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v
retrieving revision 1.116
diff -u -p -r1.116 gnugo.h
--- engine/gnugo.h 13 Nov 2004 04:46:43 -0000 1.116
+++ engine/gnugo.h 5 Jan 2005 23:13:27 -0000
@@ -369,9 +369,6 @@ int crude_status(int pos);
int dragon_status(int pos);
int same_dragon(int dr1, int dr2);
-/* moyo functions */
-void print_moyo(void);
-
/* debugging functions */
void prepare_pattern_profiling(void);
void report_pattern_profiling(void);
Index: engine/influence.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/influence.c,v
retrieving revision 1.106
diff -u -p -r1.106 influence.c
--- engine/influence.c 12 Dec 2004 22:32:10 -0000 1.106
+++ engine/influence.c 5 Jan 2005 23:13:27 -0000
@@ -2105,11 +2105,8 @@ influence_delta_territory(const struct i
/* Estimate the score. A positive value means white is ahead. The
- * score is estimated from the initial_influence, which must have been
- * computed in advance. The score estimate does not include captured
- * stones (i.e., the ones having been removed from the board) or komi.
- * moyo_coeff and area_coeff are the relative weights to be used for
- * the moyo and area difference respectively.
+ * score is estimated influence data *q, which must have been
+ * computed in advance.
*/
float
influence_score(const struct influence_data *q)
@@ -2120,7 +2117,7 @@ influence_score(const struct influence_d
for (ii = BOARDMIN; ii < BOARDMAX; ii++)
if (ON_BOARD(ii))
score += q->territory_value[ii];
- score += black_captured - white_captured;
+ score += black_captured - white_captured + komi;
return score;
}
Index: engine/interface.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/interface.c,v
retrieving revision 1.50
diff -u -p -r1.50 interface.c
--- engine/interface.c 8 Nov 2004 04:10:02 -0000 1.50
+++ engine/interface.c 5 Jan 2005 23:13:28 -0000
@@ -353,7 +353,9 @@ float
gnugo_estimate_score(float *upper, float *lower)
{
silent_examine_position(EXAMINE_DRAGONS);
- return estimate_score(upper, lower);
+ *upper = white_score;
+ *lower = black_score;
+ return ((white_score + black_score)/2.0);
}
Index: engine/liberty.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/liberty.h,v
retrieving revision 1.233
diff -u -p -r1.233 liberty.h
--- engine/liberty.h 18 Dec 2004 19:32:43 -0000 1.233
+++ engine/liberty.h 5 Jan 2005 23:13:28 -0000
@@ -668,7 +668,6 @@ void break_territories(int color_to_move
void clear_break_in_list(void);
void break_in_move_reasons(int color);
-float estimate_score(float *upper, float *lower);
void choose_strategy(int color, float our_score, float game_status);
/* Eye space functions. */
@@ -949,6 +948,7 @@ struct dragon_data2 *dragon2_func(int po
#define DRAGON(d) dragon[dragon2[d].origin]
+extern float white_score, black_score;
/* Global variables to tune strategy. */
Index: engine/score.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/score.c,v
retrieving revision 1.27
diff -u -p -r1.27 score.c
--- engine/score.c 13 Nov 2004 04:46:45 -0000 1.27
+++ engine/score.c 5 Jan 2005 23:13:28 -0000
@@ -343,7 +343,7 @@ print_new_moyo(int dilations, int erosio
*/
float
-estimate_score(float *upper, float *lower)
+old_estimate_score(float *upper, float *lower)
{
int gb[BOARDMAX];
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.103
diff -u -p -r1.103 utils.c
--- engine/utils.c 7 Dec 2004 04:41:22 -0000 1.103
+++ engine/utils.c 5 Jan 2005 23:13:29 -0000
@@ -685,9 +685,6 @@ set_depth_values(int level, int report_l
/*
* Other policies depending on level:
- * aftermath.c: >= 8: call estimate_score().
- * dragon.c: >= 8: compute owl threats (currently disabled)
- * genmove.c: >= 8: call estimate_score().
* owl.c: >= 9: use vital attack pattern database
* >= 8: increase depth values in owl_substantial
* >= 8: don't turn off owl_phase in semeai reading
@@ -1467,7 +1464,7 @@ who_wins(int color, FILE *outfile)
}
#endif
- result = estimate_score(NULL, NULL);
+ result = (white_score + black_score)/2.0;
if (result == 0.0)
fprintf(outfile, "Result: jigo ");
else
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.141
diff -u -p -r1.141 value_moves.c
--- engine/value_moves.c 18 Dec 2004 19:32:43 -0000 1.141
+++ engine/value_moves.c 5 Jan 2005 23:13:30 -0000
@@ -3772,14 +3772,12 @@ choose_strategy(int color, float our_sco
void
prepare_move_influence_debugging(int pos, int color)
{
- float lower_bound, upper_bound;
float our_score;
- estimate_score(&upper_bound, &lower_bound);
if (color == WHITE)
- our_score = lower_bound;
+ our_score = black_score;
else
- our_score = -upper_bound;
+ our_score = -white_score;
estimate_territorial_value(pos, color, our_score, 1);
}
Index: interface/play_ascii.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_ascii.c,v
retrieving revision 1.51
diff -u -p -r1.51 play_ascii.c
--- interface/play_ascii.c 16 Dec 2004 19:09:10 -0000 1.51
+++ interface/play_ascii.c 5 Jan 2005 23:13:30 -0000
@@ -909,7 +909,6 @@ play_ascii(SGFTree *tree, Gameinfo *game
tmp = printmoyo;
printmoyo = PRINTMOYO_MOYO;
examine_position(EXAMINE_DRAGONS);
- print_moyo();
printmoyo = tmp;
break;
@@ -917,7 +916,6 @@ play_ascii(SGFTree *tree, Gameinfo *game
tmp = printmoyo;
printmoyo = PRINTMOYO_TERRITORY;
examine_position(EXAMINE_DRAGONS);
- print_moyo();
printmoyo = tmp;
break;
@@ -925,7 +923,6 @@ play_ascii(SGFTree *tree, Gameinfo *game
tmp = printmoyo;
printmoyo = PRINTMOYO_AREA;
examine_position(EXAMINE_DRAGONS);
- print_moyo();
printmoyo = tmp;
break;
@@ -1028,7 +1025,7 @@ ascii_endgame(Gameinfo *gameinfo, int re
gnugo_who_wins(gameinfo->computer_player, stdout);
printf("\nIf you disagree, we may count the game together.\n");
- sgftreeWriteResult(&sgftree, estimate_score(NULL, NULL), 1);
+ sgftreeWriteResult(&sgftree, (white_score + black_score)/2.0, 1);
}
else {
int color = OTHER_COLOR(gameinfo->to_move);
Index: interface/play_gtp.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/interface/play_gtp.c,v
retrieving revision 1.162
diff -u -p -r1.162 play_gtp.c
--- interface/play_gtp.c 7 Dec 2004 17:16:54 -0000 1.162
+++ interface/play_gtp.c 5 Jan 2005 23:13:32 -0000
@@ -3379,9 +3379,7 @@ gtp_estimate_score(char *s)
float upper_bound, lower_bound;
UNUSED(s);
- silent_examine_position(EXAMINE_DRAGONS);
-
- score = estimate_score(&upper_bound, &lower_bound);
+ score = gnugo_estimate_score(&upper_bound, &lower_bound);
gtp_start_response(GTP_SUCCESS);
/* Traditionally W wins jigo */
if (score >= 0.0)
@@ -3416,7 +3414,7 @@ gtp_experimental_score(char *s)
return gtp_failure("invalid color");
genmove_conservative(color, NULL);
- estimate_score(&upper_bound, &lower_bound);
+ gnugo_estimate_score(&upper_bound, &lower_bound);
if (debug & DEBUG_SCORING)
fprintf(stderr, "upper = %3.1f, lower = %3.1f, best = %3.1f\n",
- [gnugo-devel] score.c,
Arend Bayer <=