[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] defend both, attack either, worms[], dragons[]
From: |
Arend Bayer |
Subject: |
[gnugo-devel] defend both, attack either, worms[], dragons[] |
Date: |
Tue, 10 Dec 2002 09:57:59 +0100 (CET) |
My experiments with revising the influence interface revealed some problems
with "attack either" and "defend both" move reasons. I think the only way
we will ever get their valuations right is by strictly using the
following definition:
1. Both "attack either" and "defend both" must concern two tactically stable
worms.
2. "attack either" means opponent cannot defend both worms at a time but could
if we don't play.
3. "defend both" means opponent could play a move after which we cannot
defend both (but we could defend each of them, of course -- otherwise the
worms wouldn't be stable).
This patch enforces the first rule by a discard_rule in move_reasons.c.
It gives one PASS at nngs:820.
When writing the patch, I first caused a bug by forgetting for about
the zillionth time whether a "worm" variable was pointing to an entry
in worms[], or whether it had already been "dereferenced" to point to
a location on the board.
Hence I finally decided to kill both the worms[] and the dragons[] array,
together with find_worm() and find_dragon(). They seem to be a relict
from 2D-board times to me.
(Well I see that this also gives some consistency with regards to the
way connections, EITHER_MOVE data etc. is stored, but unless someone
can convince of a good reason why this consistency is necessary I would
really love to get rid of them.)
Arend
Index: engine/move_reasons.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.c,v
retrieving revision 1.103
diff -u -p -r1.103 move_reasons.c
--- engine/move_reasons.c 6 Dec 2002 17:35:41 -0000 1.103
+++ engine/move_reasons.c 10 Dec 2002 03:15:57 -0000
@@ -38,14 +38,6 @@ struct move_data move[BOARDMAX];
struct move_reason move_reasons[MAX_MOVE_REASONS];
int next_reason;
-/* Worms */
-int worms[MAX_WORMS];
-int next_worm;
-
-/* Dragons */
-int dragons[MAX_DRAGONS];
-int next_dragon;
-
/* Connections */
int conn_worm1[MAX_CONNECTIONS];
int conn_worm2[MAX_CONNECTIONS];
@@ -90,8 +82,6 @@ clear_move_reasons(void)
int ii;
int k;
next_reason = 0;
- next_worm = 0;
- next_dragon = 0;
next_connection = 0;
next_either = 0;
next_all = 0;
@@ -137,46 +127,6 @@ clear_move_reasons(void)
}
}
-/*
- * Find the index of a worm in the list of worms. If necessary,
- * add a new entry. (str) must point to the origin of the worm.
- */
-int
-find_worm(int str)
-{
- int k;
-
- ASSERT_ON_BOARD1(str);
- for (k = 0; k < next_worm; k++)
- if (worms[k] == str)
- return k;
-
- /* Add a new entry. */
- gg_assert(next_worm < MAX_WORMS);
- worms[next_worm] = str;
- next_worm++;
- return next_worm - 1;
-}
-
-/*
- * Find the index of a dragon in the list of dragons. If necessary,
- * add a new entry. (str) must point to the origin of the dragon.
- */
-int
-find_dragon(int str)
-{
- int k;
- ASSERT_ON_BOARD1(str);
- for (k = 0; k < next_dragon; k++)
- if (dragons[k] == str)
- return k;
-
- /* Add a new entry. */
- gg_assert(next_dragon < MAX_DRAGONS);
- dragons[next_dragon] = str;
- next_dragon++;
- return next_dragon - 1;
-}
/*
* Find the index of a connection in the list of connections.
@@ -324,7 +274,8 @@ get_pos(int reason, int what)
case ATTACK_MOVE_BAD_KO:
case DEFEND_MOVE_GOOD_KO:
case DEFEND_MOVE_BAD_KO:
- return worms[what];
+ return what;
+
case SEMEAI_MOVE:
case SEMEAI_THREAT:
case VITAL_EYE_MOVE:
@@ -341,16 +292,20 @@ get_pos(int reason, int what)
case OWL_ATTACK_MOVE_BAD_KO:
case OWL_DEFEND_MOVE_GOOD_KO:
case OWL_DEFEND_MOVE_BAD_KO:
- return dragons[what];
+ return what;
+
case EITHER_MOVE:
/* FIXME: What should we return here? */
- return worms[either_data[what].what1];
+ return either_data[what].what1;
+
case ALL_MOVE:
/* FIXME: What should we return here? */
- return worms[all_data[what].what1];
+ return all_data[what].what1;
+
case CONNECT_MOVE:
case CUT_MOVE:
- return dragons[conn_worm1[what]];
+ return conn_worm1[what];
+
case ANTISUJI_MOVE:
case EXPAND_TERRITORY_MOVE:
case EXPAND_MOYO_MOVE:
@@ -358,14 +313,17 @@ get_pos(int reason, int what)
case MY_ATARI_ATARI_MOVE:
case YOUR_ATARI_ATARI_MOVE:
return NO_MOVE;
+
case OWL_ATTACK_MOVE_GAIN:
case OWL_DEFEND_MOVE_LOSS:
/* FIXME: What should we return here? */
- return dragons[either_data[what].what1];
+ return either_data[what].what1;
+
+ default:
+ /* We should never get here: */
+ gg_assert(0);
+ return 0; /* To keep gcc happy. */
}
- /* We should never get here: */
- gg_assert(1>2);
- return 0; /* To keep gcc happy. */
}
/*
@@ -377,8 +335,8 @@ void
add_lunch(int eater, int food)
{
int k;
- int dragon1 = find_dragon(dragon[eater].origin);
- int worm1 = find_worm(worm[food].origin);
+ int dragon1 = dragon[eater].origin;
+ int worm1 = worm[food].origin;
ASSERT_ON_BOARD1(eater);
ASSERT_ON_BOARD1(food);
@@ -402,8 +360,8 @@ void
remove_lunch(int eater, int food)
{
int k;
- int dragon1 = find_dragon(dragon[eater].origin);
- int worm1 = find_worm(worm[food].origin);
+ int dragon1 = dragon[eater].origin;
+ int worm1 = worm[food].origin;
ASSERT_ON_BOARD1(eater);
ASSERT_ON_BOARD1(food);
@@ -531,6 +489,8 @@ move_reason_known(int pos, int type, int
int
attack_move_reason_known(int pos, int what)
{
+ ASSERT1(IS_STONE(board[what]), what);
+ what = worm[what].origin;
if (move_reason_known(pos, ATTACK_MOVE, what))
return WIN;
if (move_reason_known(pos, ATTACK_MOVE_GOOD_KO, what))
@@ -547,6 +507,8 @@ attack_move_reason_known(int pos, int wh
int
defense_move_reason_known(int pos, int what)
{
+ ASSERT1(IS_STONE(board[what]), what);
+ what = worm[what].origin;
if (move_reason_known(pos, DEFEND_MOVE, what))
return WIN;
if (move_reason_known(pos, DEFEND_MOVE_GOOD_KO, what))
@@ -562,10 +524,9 @@ defense_move_reason_known(int pos, int w
static int
tactical_move_vs_whole_dragon_known(int pos, int what)
{
- int aa = dragons[what];
- return ((worm[aa].size == dragon[aa].size)
- && (attack_move_reason_known(pos, find_worm(aa))
- || defense_move_reason_known(pos, find_worm(aa))));
+ return ((worm[what].size == dragon[what].size)
+ && (attack_move_reason_known(pos, what)
+ || defense_move_reason_known(pos, what)));
}
/*
@@ -618,24 +579,24 @@ owl_move_reason_known(int pos, int what)
static int
owl_move_vs_worm_known(int pos, int what)
{
- return owl_move_reason_known(pos, find_dragon(dragon[worms[what]].origin));
+ return owl_move_reason_known(pos, dragon[what].origin);
}
-/* Check whether a worm listed in worms[] is inessential */
+/* Check whether a worm is inessential */
static int
concerns_inessential_worm(int pos, int what)
{
UNUSED(pos);
- return DRAGON2(worms[what]).safety == INESSENTIAL
- || worm[worms[what]].inessential;
+ return DRAGON2(what).safety == INESSENTIAL
+ || worm[what].inessential;
}
-/* Check whether a dragon listed in dragons[] is inessential */
+/* Check whether a dragon is inessential */
static int
concerns_inessential_dragon(int pos, int what)
{
UNUSED(pos);
- return DRAGON2(dragons[what]).safety == INESSENTIAL;
+ return DRAGON2(what).safety == INESSENTIAL;
}
static int
@@ -645,27 +606,35 @@ move_is_marked_unsafe(int pos, int what)
return !move[pos].move_safety;
}
+
+/* (what) points to two worms listed in either_data. Returns true if
+ * this is a "attack either" move reason, and one of the worms attackable.
+ * FIXME: Ko?
+ */
static int
-either_move_redundant(int pos, int what)
+either_worm_attackable(int pos, int what)
{
- return ((either_data[what].reason1 == ATTACK_STRING
- && attack_move_reason_known(pos, either_data[what].what1))
- || (either_data[what].reason2 == ATTACK_STRING
- && attack_move_reason_known(pos, either_data[what].what2)));
+ UNUSED(pos);
+ return (either_data[what].reason1 == ATTACK_STRING
+ && either_data[what].reason2 == ATTACK_STRING
+ && (worm[either_data[what].what1].attack_codes[0] != 0
+ || worm[either_data[what].what2].attack_codes[0] != 0));
}
-#if 0
-
+/* (what) points to two worms via all_data. Returns true if this is
+ * a "defend both" move reason, and one of the worms is attackable.
+ * FIXME: Ko?
+ */
static int
-all_move_redundant(int pos, int what)
+one_of_both_attackable(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)));
+ UNUSED(pos);
+ return (either_data[what].reason1 == DEFEND_STRING
+ && either_data[what].reason2 == DEFEND_STRING
+ && (worm[all_data[what].what1].attack_codes[0] != 0
+ || worm[all_data[what].what2].attack_codes[0] != 0));
}
-#endif
/* ---------------------------------------------------------------- */
@@ -677,15 +646,15 @@ all_move_redundant(int pos, int what)
void
add_attack_move(int pos, int ww, int code)
{
- int worm_number = find_worm(worm[ww].origin);
+ ww = worm[ww].origin;
ASSERT_ON_BOARD1(ww);
if (code == WIN)
- add_move_reason(pos, ATTACK_MOVE, worm_number);
+ add_move_reason(pos, ATTACK_MOVE, ww);
else if (code == KO_A)
- add_move_reason(pos, ATTACK_MOVE_GOOD_KO, worm_number);
+ add_move_reason(pos, ATTACK_MOVE_GOOD_KO, ww);
else if (code == KO_B)
- add_move_reason(pos, ATTACK_MOVE_BAD_KO, worm_number);
+ add_move_reason(pos, ATTACK_MOVE_BAD_KO, ww);
}
/*
@@ -695,15 +664,15 @@ add_attack_move(int pos, int ww, int cod
void
add_defense_move(int pos, int ww, int code)
{
- int worm_number = find_worm(worm[ww].origin);
+ ww = worm[ww].origin;
ASSERT_ON_BOARD1(ww);
if (code == WIN)
- add_move_reason(pos, DEFEND_MOVE, worm_number);
+ add_move_reason(pos, DEFEND_MOVE, ww);
else if (code == KO_A)
- add_move_reason(pos, DEFEND_MOVE_GOOD_KO, worm_number);
+ add_move_reason(pos, DEFEND_MOVE_GOOD_KO, ww);
else if (code == KO_B)
- add_move_reason(pos, DEFEND_MOVE_BAD_KO, worm_number);
+ add_move_reason(pos, DEFEND_MOVE_BAD_KO, ww);
}
/*
@@ -713,11 +682,10 @@ add_defense_move(int pos, int ww, int co
void
add_attack_threat_move(int pos, int ww, int code)
{
- int worm_number = find_worm(worm[ww].origin);
UNUSED(code);
ASSERT_ON_BOARD1(ww);
- add_move_reason(pos, ATTACK_THREAT, worm_number);
+ add_move_reason(pos, ATTACK_THREAT, worm[ww].origin);
}
/* Remove an attack threat move reason. */
@@ -725,10 +693,8 @@ add_attack_threat_move(int pos, int ww,
void
remove_attack_threat_move(int pos, int ww)
{
- int worm_number = find_worm(worm[ww].origin);
-
ASSERT_ON_BOARD1(ww);
- remove_move_reason(pos, ATTACK_THREAT, worm_number);
+ remove_move_reason(pos, ATTACK_THREAT, worm[ww].origin);
}
/*
@@ -738,11 +704,10 @@ remove_attack_threat_move(int pos, int w
void
add_defense_threat_move(int pos, int ww, int code)
{
- int worm_number = find_worm(worm[ww].origin);
UNUSED(code);
ASSERT_ON_BOARD1(ww);
- add_move_reason(pos, DEFEND_THREAT, worm_number);
+ add_move_reason(pos, DEFEND_THREAT, worm[ww].origin);
}
@@ -762,7 +727,7 @@ get_attack_threats(int pos, int max_stri
break;
if (move_reasons[r].type == ATTACK_THREAT)
- strings[num_strings++] = worms[move_reasons[r].what];
+ strings[num_strings++] = move_reasons[r].what;
if (num_strings == max_strings)
break;
@@ -787,7 +752,7 @@ get_defense_threats(int pos, int max_str
break;
if (move_reasons[r].type == DEFEND_THREAT)
- strings[num_strings++] = worms[move_reasons[r].what];
+ strings[num_strings++] = move_reasons[r].what;
if (num_strings == max_strings)
break;
@@ -820,10 +785,9 @@ get_biggest_owl_target(int pos)
case OWL_DEFEND_MOVE_BAD_KO:
case OWL_DEFEND_THREAT:
case OWL_PREVENT_THREAT:
- if (dragon[dragons[move_reasons[r].what]].effective_size
- > target_size) {
+ if (dragon[move_reasons[r].what].effective_size > target_size) {
biggest_target = move_reasons[r].what;
- target_size = dragon[dragons[move_reasons[r].what]].effective_size;
+ target_size = dragon[move_reasons[r].what].effective_size;
}
break;
}
@@ -839,24 +803,16 @@ get_biggest_owl_target(int pos)
void
add_connection_move(int pos, int w1, int w2)
{
- int worm1 = find_worm(worm[w1].origin);
- int worm2 = find_worm(worm[w2].origin);
int connection;
ASSERT_ON_BOARD1(w1);
ASSERT_ON_BOARD1(w2);
gg_assert(worm[w1].color == worm[w2].color);
- if (worm1 == worm2)
+ if (worm[w1].origin == worm[w2].origin)
return;
- connection = find_connection(worm1, worm2);
+ connection = find_connection(worm[w1].origin, worm[w2].origin);
add_move_reason(pos, CONNECT_MOVE, connection);
-
- /* We do this only for the side effect of being sure that the
- * corresponding dragon gets into the list of dragons.
- */
- (void) find_dragon(dragon[w1].origin);
- (void) find_dragon(dragon[w2].origin);
}
/*
@@ -867,16 +823,14 @@ add_connection_move(int pos, int w1, int
void
add_cut_move(int pos, int w1, int w2)
{
- int worm1 = find_worm(worm[w1].origin);
- int worm2 = find_worm(worm[w2].origin);
int connection;
ASSERT_ON_BOARD1(w1);
ASSERT_ON_BOARD1(w2);
gg_assert(worm[w1].color == worm[w2].color);
- if (worm1 == worm2)
+ if (worm[w1].origin == worm[w2].origin)
return;
- connection = find_connection(worm1, worm2);
+ connection = find_connection(worm[w1].origin, worm[w2].origin);
/*
* Ignore the cut or connection if either (w1) or (w2)
@@ -888,11 +842,6 @@ add_cut_move(int pos, int w1, int w2)
add_move_reason(pos, CUT_MOVE, connection);
- /* We do this only for the side effect of being sure that the
- * corresponding dragon gets into the list of dragons.
- */
- (void) find_dragon(dragon[w1].origin);
- (void) find_dragon(dragon[w2].origin);
}
/*
@@ -917,10 +866,9 @@ add_antisuji_move(int pos)
void
add_semeai_move(int pos, int dr)
{
- int the_dragon = find_dragon(dragon[dr].origin);
-
+
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, SEMEAI_MOVE, the_dragon);
+ add_move_reason(pos, SEMEAI_MOVE, dragon[dr].origin);
}
/*
@@ -933,10 +881,8 @@ add_semeai_move(int pos, int dr)
void
add_semeai_threat(int pos, int dr)
{
- int the_dragon = find_dragon(dragon[dr].origin);
-
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, SEMEAI_THREAT, the_dragon);
+ add_move_reason(pos, SEMEAI_THREAT, dragon[dr].origin);
}
/*
@@ -991,7 +937,7 @@ add_either_move(int pos, int reason1, in
switch (reason1) {
case ATTACK_STRING:
{
- what1 = find_worm(worm[target1].origin);
+ what1 = worm[target1].origin;
/* If this string is already attacked, and with no defense, then
* there is no additional value of this move reason. */
@@ -1008,7 +954,7 @@ add_either_move(int pos, int reason1, in
switch (reason2) {
case ATTACK_STRING:
{
- what2 = find_worm(worm[target2].origin);
+ what2 = worm[target2].origin;
/* If this string is already attacked, and with no defense, then
* there is no additional value of this move reason. */
@@ -1061,7 +1007,7 @@ add_all_move(int pos, int reason1, int t
switch (reason1) {
case DEFEND_STRING:
- what1 = find_worm(worm[target1].origin);
+ what1 = worm[target1].origin;
break;
default:
@@ -1070,7 +1016,7 @@ add_all_move(int pos, int reason1, int t
switch (reason2) {
case DEFEND_STRING:
- what2 = find_worm(worm[target2].origin);
+ what2 = worm[target2].origin;
break;
default:
@@ -1085,8 +1031,8 @@ add_all_move(int pos, int reason1, int t
void
add_gain_move(int pos, int target1, int target2)
{
- int what1 = find_dragon(dragon[target1].origin);
- int what2 = find_worm(worm[target2].origin);
+ int what1 = dragon[target1].origin;
+ int what2 = worm[target2].origin;
int index = find_pair_data(what1, what2);
ASSERT1(target2 != NO_MOVE, pos);
add_move_reason(pos, OWL_ATTACK_MOVE_GAIN, index);
@@ -1095,8 +1041,8 @@ add_gain_move(int pos, int target1, int
void
add_loss_move(int pos, int target1, int target2)
{
- int what1 = find_dragon(dragon[target1].origin);
- int what2 = find_worm(worm[target2].origin);
+ int what1 = dragon[target1].origin;
+ int what2 = worm[target2].origin;
int index = find_pair_data(what1, what2);
ASSERT1(target2 != NO_MOVE, pos);
add_move_reason(pos, OWL_DEFEND_MOVE_LOSS, index);
@@ -1173,10 +1119,9 @@ add_worthwhile_threat_move(int pos)
void
add_strategical_attack_move(int pos, int dr)
{
- int dragon1 = find_dragon(dragon[dr].origin);
-
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, STRATEGIC_ATTACK_MOVE, dragon1);
+ add_move_reason(pos, STRATEGIC_ATTACK_MOVE, dr);
}
/*
@@ -1186,10 +1131,9 @@ add_strategical_attack_move(int pos, int
void
add_strategical_defense_move(int pos, int dr)
{
- int dragon1 = find_dragon(dragon[dr].origin);
-
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, STRATEGIC_DEFEND_MOVE, dragon1);
+ add_move_reason(pos, STRATEGIC_DEFEND_MOVE, dr);
}
/*
@@ -1199,15 +1143,15 @@ add_strategical_defense_move(int pos, in
void
add_owl_attack_move(int pos, int dr, int code)
{
- int dragon1 = find_dragon(dragon[dr].origin);
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
if (code == WIN)
- add_move_reason(pos, OWL_ATTACK_MOVE, dragon1);
+ add_move_reason(pos, OWL_ATTACK_MOVE, dr);
else if (code == KO_A)
- add_move_reason(pos, OWL_ATTACK_MOVE_GOOD_KO, dragon1);
+ add_move_reason(pos, OWL_ATTACK_MOVE_GOOD_KO, dr);
else if (code == KO_B)
- add_move_reason(pos, OWL_ATTACK_MOVE_BAD_KO, dragon1);
+ add_move_reason(pos, OWL_ATTACK_MOVE_BAD_KO, dr);
}
/*
@@ -1217,15 +1161,15 @@ add_owl_attack_move(int pos, int dr, int
void
add_owl_defense_move(int pos, int dr, int code)
{
- int dragon1 = find_dragon(dragon[dr].origin);
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
if (code == WIN)
- add_move_reason(pos, OWL_DEFEND_MOVE, dragon1);
+ add_move_reason(pos, OWL_DEFEND_MOVE, dr);
else if (code == KO_A)
- add_move_reason(pos, OWL_DEFEND_MOVE_GOOD_KO, dragon1);
+ add_move_reason(pos, OWL_DEFEND_MOVE_GOOD_KO, dr);
else if (code == KO_B)
- add_move_reason(pos, OWL_DEFEND_MOVE_BAD_KO, dragon1);
+ add_move_reason(pos, OWL_DEFEND_MOVE_BAD_KO, dr);
}
/*
@@ -1237,11 +1181,11 @@ add_owl_defense_move(int pos, int dr, in
void
add_owl_attack_threat_move(int pos, int dr, int code)
{
- int dragon1 = find_dragon(dragon[dr].origin);
UNUSED(code);
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, OWL_ATTACK_THREAT, dragon1);
+ add_move_reason(pos, OWL_ATTACK_THREAT, dragon[dr].origin);
add_worthwhile_threat_move(pos);
}
@@ -1252,10 +1196,9 @@ add_owl_attack_threat_move(int pos, int
void
add_owl_uncertain_defense_move(int pos, int dr)
{
- int dragon1 = find_dragon(dragon[dr].origin);
-
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, UNCERTAIN_OWL_DEFENSE, dragon1);
+ add_move_reason(pos, UNCERTAIN_OWL_DEFENSE, dragon[dr].origin);
}
/* The owl code found the opponent dragon alive, or the friendly
@@ -1265,10 +1208,9 @@ add_owl_uncertain_defense_move(int pos,
void
add_owl_uncertain_attack_move(int pos, int dr)
{
- int dragon1 = find_dragon(dragon[dr].origin);
-
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, UNCERTAIN_OWL_ATTACK, dragon1);
+ add_move_reason(pos, UNCERTAIN_OWL_ATTACK, dragon[dr].origin);
}
/*
@@ -1280,11 +1222,11 @@ add_owl_uncertain_attack_move(int pos, i
void
add_owl_defense_threat_move(int pos, int dr, int code)
{
- int dragon1 = find_dragon(dragon[dr].origin);
UNUSED(code);
+ dr = dragon[dr].origin;
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, OWL_DEFEND_THREAT, dragon1);
+ add_move_reason(pos, OWL_DEFEND_THREAT, dragon[dr].origin);
add_worthwhile_threat_move(pos);
}
@@ -1320,10 +1262,8 @@ add_your_atari_atari_move(int pos, int s
void
add_owl_prevent_threat_move(int pos, int dr)
{
- int dragon1 = find_dragon(dragon[dr].origin);
-
ASSERT_ON_BOARD1(dr);
- add_move_reason(pos, OWL_PREVENT_THREAT, dragon1);
+ add_move_reason(pos, OWL_PREVENT_THREAT, dragon[dr].origin);
}
/*
@@ -1472,10 +1412,10 @@ get_saved_worms(int pos, char saved[BOAR
* move is unsafe.
*/
if (move_reasons[r].type == DEFEND_MOVE)
- mark_string(worm[worms[what]].origin, saved, 1);
+ mark_string(worm[what].origin, saved, 1);
else if (move_reasons[r].type == OWL_DEFEND_MOVE_LOSS) {
- int origin = dragon[worms[what]].origin;
- int kworm = worm[worms[what]].origin;
+ int origin = dragon[what].origin;
+ int kworm = worm[what].origin;
int ii;
for (ii = BOARDMIN; ii < BOARDMAX; ii++)
if (IS_STONE(board[ii]) && dragon[ii].origin == origin
@@ -1560,7 +1500,7 @@ mark_changed_dragon(int pos, int color,
else {
int worm_is_safe = 0;
if (worm[ii].attack_codes[0] == NO_MOVE
- || defense_move_reason_known(pos, find_worm(ii)))
+ || defense_move_reason_known(pos, ii))
worm_is_safe = 1;
else if (trymove(pos, color, "mark-changed-dragon", ii,
EMPTY, NO_MOVE)) {
@@ -1605,11 +1545,10 @@ get_saved_dragons(int pos, char saved[BO
* move is unsafe.
*/
if (move_reasons[r].type == OWL_DEFEND_MOVE) {
- int origin = dragon[dragons[what]].origin;
int ii;
- for (ii = BOARDMIN; ii < BOARDMAX; ii++)
- if (IS_STONE(board[ii]) && dragon[ii].origin == origin)
- saved[ii] = 1;
+ for (ii = first_worm_in_dragon(what); ii != NO_MOVE;
+ ii = next_worm_in_dragon(ii))
+ mark_string(ii, saved, 1);
}
}
}
@@ -1686,37 +1625,37 @@ list_move_reasons(int color)
switch (move_reasons[r].type) {
case ATTACK_MOVE:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m attacks %1m%s\n", pos, aa,
(worm[aa].defense_codes[0] == 0) ? " (defenseless)" : "");
break;
case ATTACK_MOVE_GOOD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m attacks %1m%s with good ko\n", pos, aa,
(worm[aa].defense_codes[0] == 0) ? " (defenseless)" : "");
break;
case ATTACK_MOVE_BAD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m attacks %1m%s with bad ko\n", pos, aa,
(worm[aa].defense_codes[0] == 0) ? " (defenseless)" : "");
break;
case DEFEND_MOVE:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m defends %1m\n", pos, aa);
break;
case DEFEND_MOVE_GOOD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m defends %1m with good ko\n", pos, aa);
break;
case DEFEND_MOVE_BAD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m defends %1m with bad ko\n", pos, aa);
break;
case ATTACK_THREAT:
case DEFEND_THREAT:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
if (move_reasons[r].type == ATTACK_THREAT)
gprintf("Move at %1m threatens to attack %1m\n", pos, aa);
@@ -1725,7 +1664,7 @@ list_move_reasons(int color)
break;
case UNCERTAIN_OWL_DEFENSE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
if (board[aa] == color)
gprintf("%1m found alive but not certainly, %1m defends it again\n",
aa, pos);
@@ -1738,12 +1677,10 @@ list_move_reasons(int color)
case CUT_MOVE:
worm1 = conn_worm1[move_reasons[r].what];
worm2 = conn_worm2[move_reasons[r].what];
- aa = worms[worm1];
- bb = worms[worm2];
if (move_reasons[r].type == CONNECT_MOVE)
- gprintf("Move at %1m connects %1m and %1m\n", pos, aa, bb);
+ gprintf("Move at %1m connects %1m and %1m\n", pos, worm1, worm2);
else
- gprintf("Move at %1m cuts %1m and %1m\n", pos, aa, bb);
+ gprintf("Move at %1m cuts %1m and %1m\n", pos, worm1, worm2);
break;
case ANTISUJI_MOVE:
@@ -1751,12 +1688,12 @@ list_move_reasons(int color)
break;
case SEMEAI_MOVE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m wins semeai for %1m\n", pos, aa);
break;
case SEMEAI_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m threatens to win semeai for %1m\n", pos, aa);
break;
@@ -1774,11 +1711,9 @@ list_move_reasons(int color)
reason2 = either_data[move_reasons[r].what].reason2;
worm1 = either_data[move_reasons[r].what].what1;
worm2 = either_data[move_reasons[r].what].what2;
- aa = worms[worm1];
- bb = worms[worm2];
gprintf("Move at %1m either %s %1m or %s %1m\n", pos,
- reason1 == ATTACK_STRING ? "attacks" : "defends", aa,
- reason2 == ATTACK_STRING ? "attacks" : "defends", bb);
+ reason1 == ATTACK_STRING ? "attacks" : "defends", worm1,
+ reason2 == ATTACK_STRING ? "attacks" : "defends", worm2);
break;
case ALL_MOVE:
@@ -1786,61 +1721,59 @@ list_move_reasons(int color)
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 both %s %1m and %s %1m\n", pos,
- reason1 == ATTACK_STRING ? "attacks" : "defends", aa,
- reason2 == ATTACK_STRING ? "attacks" : "defends", bb);
+ reason1 == ATTACK_STRING ? "attacks" : "defends", worm1,
+ reason2 == ATTACK_STRING ? "attacks" : "defends", worm2);
break;
case OWL_ATTACK_MOVE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-attacks %1m\n", pos, aa);
break;
case OWL_ATTACK_MOVE_GOOD_KO:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-attacks %1m with good ko\n", pos, aa);
break;
case OWL_ATTACK_MOVE_BAD_KO:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-attacks %1m with bad ko\n", pos, aa);
break;
case OWL_ATTACK_MOVE_GAIN:
- aa = dragons[either_data[move_reasons[r].what].what1];
- bb = worms[either_data[move_reasons[r].what].what2];
+ aa = either_data[move_reasons[r].what].what1;
+ bb = either_data[move_reasons[r].what].what2;
gprintf("Move at %1m owl-attacks %1m (captures %1m)\n", pos, aa, bb);
break;
case OWL_DEFEND_MOVE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-defends %1m\n", pos, aa);
break;
case OWL_DEFEND_MOVE_GOOD_KO:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-defends %1m with good ko\n", pos, aa);
break;
case OWL_DEFEND_MOVE_BAD_KO:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-defends %1m with bad ko\n", pos, aa);
break;
case OWL_DEFEND_MOVE_LOSS:
- aa = dragons[either_data[move_reasons[r].what].what1];
- bb = worms[either_data[move_reasons[r].what].what2];
+ aa = either_data[move_reasons[r].what].what1;
+ bb = either_data[move_reasons[r].what].what2;
gprintf("Move at %1m owl-defends %1m (loses %1m)\n", pos, aa, bb);
break;
case OWL_ATTACK_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-threatens to attack %1m\n", pos, aa);
break;
case OWL_DEFEND_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-threatens to defend %1m\n", pos, aa);
break;
case OWL_PREVENT_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
gprintf("Move at %1m owl-prevents a threat to attack or defend %1m\n",
pos, aa);
break;
@@ -1859,7 +1792,7 @@ list_move_reasons(int color)
case STRATEGIC_ATTACK_MOVE:
case STRATEGIC_DEFEND_MOVE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
if (move_reasons[r].type == STRATEGIC_ATTACK_MOVE)
gprintf("Move at %1m strategically attacks %1m\n", pos, aa);
@@ -1889,6 +1822,8 @@ list_move_reasons(int color)
* flags to be set, trace message }
* The condition must be of type discard_condition_fn_ptr, that is a pointer
* to a function with parameters (pos, what).
+ *
+ * FIXME: Add handling of ALL and EITHER moves for inessential worms.
*/
static struct discard_rule discard_rules[] =
@@ -1906,12 +1841,11 @@ static struct discard_rule discard_rules
tactical_move_vs_whole_dragon_known, REDUNDANT,
" %1m: 0.0 - (threat to) win semai involving %1m (tactical move as
well)\n"},
{ { 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 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. */
+ either_worm_attackable, REDUNDANT,
+ " %1m: 0.0 - 'attack either' is redundant at %1m (direct att./def. as
well)\n"},
+ { { ALL_MOVE, -1 },
+ one_of_both_attackable, REDUNDANT,
+ " %1m: 0.0 - 'defend both' is redundant at %1m (direct att./def. as
well)\n"},
{ { ATTACK_MOVE, ATTACK_MOVE_GOOD_KO,
ATTACK_MOVE_BAD_KO, ATTACK_THREAT,
DEFEND_MOVE, DEFEND_MOVE_GOOD_KO,
Index: engine/move_reasons.h
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/move_reasons.h,v
retrieving revision 1.28
diff -u -p -r1.28 move_reasons.h
--- engine/move_reasons.h 6 Dec 2002 17:35:42 -0000 1.28
+++ engine/move_reasons.h 10 Dec 2002 03:15:58 -0000
@@ -145,14 +145,6 @@ extern struct move_data move[BOARDMAX];
extern struct move_reason move_reasons[MAX_MOVE_REASONS];
extern int next_reason;
-/* Worms */
-extern int worms[MAX_WORMS];
-extern int next_worm;
-
-/* Dragons */
-extern int dragons[MAX_DRAGONS];
-extern int next_dragon;
-
/* Connections */
extern int conn_worm1[MAX_CONNECTIONS];
extern int conn_worm2[MAX_CONNECTIONS];
Index: engine/value_moves.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.70
diff -u -p -r1.70 value_moves.c
--- engine/value_moves.c 6 Dec 2002 18:28:38 -0000 1.70
+++ engine/value_moves.c 10 Dec 2002 03:16:10 -0000
@@ -143,7 +143,7 @@ find_more_attack_and_defense_moves(int c
&& worm[ii].origin == ii
&& worm[ii].attack_codes[0] != 0
&& worm[ii].defense_codes[0] != 0) {
- unstable_worms[N] = find_worm(ii);
+ unstable_worms[N] = ii;
N++;
}
}
@@ -183,7 +183,7 @@ find_more_attack_and_defense_moves(int c
if (trymove(ii, color, "find_more_attack_and_defense_moves",
NO_MOVE, EMPTY, NO_MOVE)) {
for (k = 0; k < N; k++) {
- int aa = worms[unstable_worms[k]];
+ int aa = unstable_worms[k];
/* string of our color, see if there still is an attack,
* unless we already know the move works as defense move.
@@ -303,17 +303,17 @@ find_more_owl_attack_and_defense_moves(i
what = move_reasons[r].what;
if (move_reasons[r].type == STRATEGIC_ATTACK_MOVE
|| move_reasons[r].type == STRATEGIC_DEFEND_MOVE)
- dd1 = dragons[what];
+ dd1 = what;
else if (move_reasons[r].type == ATTACK_MOVE
|| move_reasons[r].type == ATTACK_MOVE_GOOD_KO
|| move_reasons[r].type == ATTACK_MOVE_BAD_KO
|| move_reasons[r].type == DEFEND_MOVE
|| move_reasons[r].type == DEFEND_MOVE_GOOD_KO
|| move_reasons[r].type == DEFEND_MOVE_BAD_KO)
- dd1 = worms[what];
+ dd1 = what;
else if (move_reasons[r].type == VITAL_EYE_MOVE) {
- int ee = eyes[move_reasons[r].what];
- int ecolor = eyecolor[move_reasons[r].what];
+ int ee = eyes[what];
+ int ecolor = eyecolor[what];
if (ecolor == WHITE)
find_eye_dragons(ee, white_eye, WHITE, &dd1, 1);
@@ -324,10 +324,10 @@ find_more_owl_attack_and_defense_moves(i
continue;
}
else if (move_reasons[r].type == CONNECT_MOVE) {
- int worm1 = conn_worm1[move_reasons[r].what];
- int worm2 = conn_worm2[move_reasons[r].what];
- dd1 = dragon[worms[worm1]].origin;
- dd2 = dragon[worms[worm2]].origin;
+ int worm1 = conn_worm1[what];
+ int worm2 = conn_worm2[what];
+ dd1 = dragon[worm1].origin;
+ dd2 = dragon[worm2].origin;
if (dd1 == dd2)
dd2 = NO_MOVE;
}
@@ -356,7 +356,7 @@ find_more_owl_attack_and_defense_moves(i
|| move_reasons[r].type == ATTACK_MOVE_BAD_KO
|| (move_reasons[r].type == VITAL_EYE_MOVE
&& board[dd] == OTHER_COLOR(color)))
- && !owl_attack_move_reason_known(pos, find_dragon(dd))) {
+ && !owl_attack_move_reason_known(pos, dd)) {
int kworm = NO_MOVE;
int acode = owl_does_attack(pos, dd, &kworm);
if (acode >= dragon[dd].owl_attack_code) {
@@ -375,7 +375,7 @@ find_more_owl_attack_and_defense_moves(i
|| move_reasons[r].type == DEFEND_MOVE_BAD_KO
|| (move_reasons[r].type == VITAL_EYE_MOVE
&& board[dd] == color))
- && !owl_defense_move_reason_known(pos, find_dragon(dd))) {
+ && !owl_defense_move_reason_known(pos, dd)) {
int kworm = NO_MOVE;
/* FIXME: Better use owl_connection_defend() for CONNECT_MOVE ? */
int dcode = owl_does_defend(pos, dd, &kworm);
@@ -413,7 +413,7 @@ find_more_owl_attack_and_defense_moves(i
|| move_reasons[r].type == OWL_DEFEND_MOVE
|| move_reasons[r].type == OWL_DEFEND_MOVE_GOOD_KO
|| move_reasons[r].type == OWL_DEFEND_MOVE_BAD_KO) {
- dd = dragons[move_reasons[r].what];
+ dd = move_reasons[r].what;
if (are_neighbor_dragons(dd, pos)) {
worth_trying = 1;
break;
@@ -426,7 +426,7 @@ find_more_owl_attack_and_defense_moves(i
if (worth_trying) {
if (board[pos] == color
- && !owl_defense_move_reason_known(pos2, find_dragon(pos))) {
+ && !owl_defense_move_reason_known(pos2, pos)) {
int kworm = NO_MOVE;
int dcode = owl_does_defend(pos2, pos, &kworm);
if (dcode >= dragon[pos].owl_defense_code) {
@@ -438,7 +438,7 @@ find_more_owl_attack_and_defense_moves(i
}
else if (board[pos] != color
- && !owl_attack_move_reason_known(pos2, find_dragon(pos))) {
+ && !owl_attack_move_reason_known(pos2, pos)) {
int kworm = NO_MOVE;
int acode = owl_does_attack(pos2, pos, &kworm);
if (acode >= dragon[pos].owl_attack_code) {
@@ -508,7 +508,7 @@ induce_secondary_move_reasons(int color)
int color_to_move;
int num_adj, adjs[MAXCHAIN];
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
if (move_reasons[r].type == ATTACK_MOVE) {
attack_move = 1;
@@ -596,7 +596,7 @@ induce_secondary_move_reasons(int color)
}
}
else if (move_reasons[r].type == OWL_ATTACK_MOVE) {
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
for (i = 0; i < DRAGON2(aa).neighbors; i++) {
int bb = dragon2[DRAGON2(aa).adjacent[i]].origin;
if (dragon[bb].color == color && worm[bb].attack_codes[0] == 0)
@@ -605,8 +605,8 @@ induce_secondary_move_reasons(int color)
}
else if (move_reasons[r].type == CONNECT_MOVE
&& cut_possible(pos, OTHER_COLOR(color))) {
- int worm1 = worms[conn_worm1[move_reasons[r].what]];
- int worm2 = worms[conn_worm2[move_reasons[r].what]];
+ int worm1 = conn_worm1[move_reasons[r].what];
+ int worm2 = conn_worm2[move_reasons[r].what];
int pos2;
for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++)
if (ON_BOARD(pos2) && board[pos2] == EMPTY
@@ -705,15 +705,15 @@ examine_move_safety(int color)
if (type == ATTACK_MOVE
|| type == ATTACK_MOVE_GOOD_KO
|| type == ATTACK_MOVE_BAD_KO) {
- aa = worms[what];
+ aa = what;
size = worm[aa].effective_size;
}
else if (type == OWL_ATTACK_MOVE_GAIN) {
- aa = worms[either_data[what].what2];
+ aa = either_data[what].what2;
size = worm[aa].effective_size;
}
else {
- aa = dragons[what];
+ aa = what;
size = dragon[aa].effective_size;
}
@@ -834,7 +834,7 @@ examine_move_safety(int color)
case DEFEND_MOVE_GOOD_KO:
case DEFEND_MOVE_BAD_KO:
{
- int aa = worms[what];
+ int aa = what;
if (dragon[aa].status == ALIVE)
/* It would be better if this never happened, but it does
@@ -855,8 +855,8 @@ examine_move_safety(int color)
{
int worm1 = conn_worm1[move_reasons[r].what];
int worm2 = conn_worm2[move_reasons[r].what];
- int aa = dragon[worms[worm1]].origin;
- int bb = dragon[worms[worm2]].origin;
+ int aa = dragon[worm1].origin;
+ int bb = dragon[worm2].origin;
if (aa == bb)
continue;
@@ -999,12 +999,10 @@ connection_value(int dragona, int dragon
* FIXME: Shouldn't it be sufficient to check this for dragon a?
*/
if (doing_scoring && terr_val < 0.0) {
- if ((safetya == WEAKLY_ALIVE
- || safetya == ALIVE
+ if ((safetya == ALIVE
|| safetya == STRONGLY_ALIVE
|| safetya == INVINCIBLE)
- && (safetyb == WEAKLY_ALIVE
- || safetyb == ALIVE
+ && (safetyb == ALIVE
|| safetyb == STRONGLY_ALIVE
|| safetyb == INVINCIBLE))
return 0.0;
@@ -1187,7 +1185,7 @@ strategic_penalty(int pos, int color)
for (k = 0; k < MAX_REASONS; k++) {
int r = move[pos].reason[k];
- if (r == -1)
+ if (r < 0)
break;
/* We assume that invasion moves can only have the move reasons listed
* below.
@@ -1209,7 +1207,7 @@ strategic_penalty(int pos, int color)
*/
case DEFEND_MOVE:
{
- int target = worms[move_reasons[r].what];
+ int target = move_reasons[r].what;
if (dragon[target].size > 1)
return 0.0;
continue;
@@ -1220,7 +1218,7 @@ strategic_penalty(int pos, int color)
*/
case OWL_DEFEND_MOVE:
{
- int target = dragons[move_reasons[r].what];
+ int target = move_reasons[r].what;
int has_strong_neighbor = 0;
int has_weak_neighbor = 0;
int i;
@@ -1252,7 +1250,9 @@ strategic_penalty(int pos, int color)
has_strong_neighbor = 1;
break;
case ALIVE:
- continue;
+ if (DRAGON2(target + delta[i]).weakness > 0.4)
+ has_weak_neighbor = 1;
+ break;
default:
has_weak_neighbor = 1;
}
@@ -1332,7 +1332,7 @@ estimate_territorial_value(int pos, int
case ATTACK_MOVE:
case ATTACK_MOVE_GOOD_KO:
case ATTACK_MOVE_BAD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gg_assert(board[aa] != color);
@@ -1385,7 +1385,7 @@ estimate_territorial_value(int pos, int
case DEFEND_MOVE:
case DEFEND_MOVE_GOOD_KO:
case DEFEND_MOVE_BAD_KO:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
gg_assert(board[aa] == color);
@@ -1433,8 +1433,8 @@ estimate_territorial_value(int pos, int
* combination with bad ko it still has a positive net impact.
*/
if (dragon[aa].owl_status == CRITICAL
- && (owl_defense_move_reason_known(pos, find_dragon(aa))
- < defense_move_reason_known(pos, find_worm(aa)))) {
+ && (owl_defense_move_reason_known(pos, aa)
+ < defense_move_reason_known(pos, aa))) {
this_value = 0.45 * (2 * worm[aa].effective_size);
TRACE(" %1m: -%f - suspected ineffective defense of worm %1m\n",
pos, this_value, aa);
@@ -1445,7 +1445,7 @@ estimate_territorial_value(int pos, int
break;
case ATTACK_THREAT:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
/* Make sure this is a threat to attack opponent stones. */
ASSERT1(board[aa] == other, aa);
@@ -1569,7 +1569,7 @@ estimate_territorial_value(int pos, int
break;
case DEFEND_THREAT:
- aa = worms[move_reasons[r].what];
+ aa = move_reasons[r].what;
/* Make sure this is a threat to defend our stones. */
ASSERT1(board[aa] == color, aa);
@@ -1624,7 +1624,7 @@ estimate_territorial_value(int pos, int
break;
case SEMEAI_MOVE:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
this_value = 2 * dragon[aa].effective_size;
TRACE(" %1m: %f - semeai involving %1m\n", pos, this_value, aa);
@@ -1632,7 +1632,7 @@ estimate_territorial_value(int pos, int
break;
case SEMEAI_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
/* threaten to win the semeai as a ko threat */
add_followup_value(pos, 2 * dragon[aa].effective_size);
@@ -1658,11 +1658,11 @@ estimate_territorial_value(int pos, int
if (move_reasons[r].type == OWL_ATTACK_MOVE_GAIN
|| move_reasons[r].type == OWL_DEFEND_MOVE_LOSS) {
- aa = dragons[either_data[move_reasons[r].what].what1];
- bb = worms[either_data[move_reasons[r].what].what2];
+ aa = either_data[move_reasons[r].what].what1;
+ bb = either_data[move_reasons[r].what].what2;
}
else {
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
bb = NO_MOVE;
}
@@ -1726,7 +1726,7 @@ estimate_territorial_value(int pos, int
|| move_reasons[r].type == OWL_ATTACK_MOVE_BAD_KO)
&& dragon[aa].size == worm[aa].size
&& worm[aa].attack_codes[0] == WIN
- && attack_move_reason_known(pos, find_worm(aa)) != WIN) {
+ && attack_move_reason_known(pos, aa) != WIN) {
this_value = 0.05 * (2 * worm[aa].effective_size);
TRACE(" %1m: -%f - suspected ineffective owl attack of worm %1m\n",
pos, this_value, aa);
@@ -1737,7 +1737,7 @@ estimate_territorial_value(int pos, int
break;
case OWL_ATTACK_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
if (dragon[aa].status == DEAD) {
DEBUG(DEBUG_MOVE_REASONS,
@@ -1766,7 +1766,7 @@ estimate_territorial_value(int pos, int
if (dragon[adj].color == color
&& dragon[adj].status == CRITICAL
&& dragon2[d].safety != INESSENTIAL
- && !owl_defense_move_reason_known(pos, find_dragon(adj)))
+ && !owl_defense_move_reason_known(pos, adj))
value = 0.0;
}
@@ -1779,7 +1779,7 @@ estimate_territorial_value(int pos, int
break;
case OWL_DEFEND_THREAT:
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
add_followup_value(pos, 2 * dragon[aa].effective_size);
TRACE(" %1m: %f (followup) - threatens to owl defend %1m\n",
@@ -1789,7 +1789,7 @@ estimate_territorial_value(int pos, int
case OWL_PREVENT_THREAT:
/* A move attacking a dragon whose defense can be threatened.
*/
- aa = dragons[move_reasons[r].what];
+ aa = move_reasons[r].what;
/* If the opponent just added a stone to a dead dragon, then
* attack it. If we are ahead, add a safety move here, at most
@@ -1912,25 +1912,19 @@ estimate_strategical_value(int pos, int
int l;
int aa = NO_MOVE;
int bb = NO_MOVE;
+ int a_id;
+ int b_id;
float aa_value = 0.0;
float bb_value = 0.0;
- int d1 = -1;
- int d2 = -1;
- int worm1 = -1;
- int worm2 = -1;
float this_value = 0.0;
float tot_value = 0.0;
/* Strategical value of connecting or cutting dragons. */
- static float dragon_value[MAX_DRAGONS];
+ float *dragon_value = malloc(sizeof(float) * number_of_dragons);
+ gg_assert(dragon_value);
- /* This loop used to be up to next_dragon, but that is not safe
- * because while doing the computations below, next_dragon might
- * increase (through calls to find_dragon()). Thus we could then
- * reference improperly initialized memory.
- */
- for (k = 0; k < MAX_DRAGONS; k++)
+ for (k = 0; k < number_of_dragons; k++)
dragon_value[k] = 0.0;
for (k = 0; k < MAX_REASONS; k++) {
@@ -1948,8 +1942,7 @@ estimate_strategical_value(int pos, int
case DEFEND_MOVE:
case DEFEND_MOVE_GOOD_KO:
case DEFEND_MOVE_BAD_KO:
- worm1 = move_reasons[r].what;
- aa = worms[worm1];
+ aa = move_reasons[r].what;
/* Defenseless stone */
if (worm[aa].defense_codes[0] == 0)
@@ -1989,9 +1982,9 @@ estimate_strategical_value(int pos, int
/* Can't use k in this loop too. */
for (l = 0; l < next_lunch; l++)
- if (lunch_worm[l] == worm1) {
- d1 = lunch_dragon[l];
- bb = dragons[d1];
+ if (lunch_worm[l] == aa) {
+ bb = lunch_dragon[l];
+ b_id = dragon[bb].id;
/* FIXME: This value cannot be computed without some measurement
* of how the actual move affects the dragon. The dragon safety
@@ -2008,8 +2001,8 @@ estimate_strategical_value(int pos, int
*/
if (dragon[bb].status != DEAD
&& dragon[bb].size == worm[bb].size
- && (attack_move_reason_known(pos, find_worm(bb))
- || defense_move_reason_known(pos, find_worm(bb))))
+ && (attack_move_reason_known(pos, bb)
+ || defense_move_reason_known(pos, bb)))
this_value = 0.0;
/* If this dragon can be tactically attacked and the move
@@ -2026,17 +2019,16 @@ estimate_strategical_value(int pos, int
*/
if (doing_scoring
&& move[pos].territorial_value < 0.0
- && (DRAGON2(bb).safety == WEAKLY_ALIVE
- || DRAGON2(bb).safety == ALIVE
+ && (DRAGON2(bb).safety == ALIVE
|| DRAGON2(bb).safety == STRONGLY_ALIVE
|| DRAGON2(bb).safety == INVINCIBLE))
this_value = 0.0;
- if (this_value > dragon_value[d1]) {
+ if (this_value > dragon_value[b_id]) {
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - %1m attacked/defended\n",
pos, this_value, bb);
- dragon_value[d1] = this_value;
+ dragon_value[b_id] = this_value;
}
}
@@ -2051,10 +2043,8 @@ estimate_strategical_value(int pos, int
/* FIXME: We need a policy if a move has several EITHER_MOVE
* reasons. Most likely not all of them can be achieved.
*/
- worm1 = either_data[move_reasons[r].what].what1;
- worm2 = either_data[move_reasons[r].what].what2;
- aa = worms[worm1];
- bb = worms[worm2];
+ aa = either_data[move_reasons[r].what].what1;
+ bb = either_data[move_reasons[r].what].what2;
/* If both worms are dead, this move reason has no value. */
if (dragon[aa].status == DEAD
@@ -2081,10 +2071,8 @@ estimate_strategical_value(int pos, int
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];
+ aa = all_data[move_reasons[r].what].what1;
+ bb = all_data[move_reasons[r].what].what2;
/* If both worms are dead, this move reason has no value. */
if (dragon[aa].status == DEAD
@@ -2122,10 +2110,8 @@ estimate_strategical_value(int pos, int
if (!doing_scoring) {
int cc;
- worm1 = conn_worm1[move_reasons[r].what];
- worm2 = conn_worm2[move_reasons[r].what];
- aa = dragon[worms[worm1]].origin;
- bb = dragon[worms[worm2]].origin;
+ aa = dragon[conn_worm1[move_reasons[r].what]].origin;
+ bb = dragon[conn_worm2[move_reasons[r].what]].origin;
cc = get_last_opponent_move(color);
if (cc != NO_MOVE
@@ -2140,9 +2126,8 @@ estimate_strategical_value(int pos, int
else
this_value = 1.7 * dragon[cc].effective_size;
- d1 = find_dragon(cc);
- if (this_value > dragon_value[d1]) {
- dragon_value[d1] = this_value;
+ if (this_value > dragon_value[dragon[cc].id]) {
+ dragon_value[dragon[cc].id] = this_value;
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - connect %1m and %1m to attack thrashing
dragon %1m\n",
pos, this_value, aa, bb, cc);
@@ -2157,16 +2142,14 @@ estimate_strategical_value(int pos, int
if (doing_scoring && !move[pos].move_safety)
break;
- worm1 = conn_worm1[move_reasons[r].what];
- worm2 = conn_worm2[move_reasons[r].what];
- aa = dragon[worms[worm1]].origin;
- bb = dragon[worms[worm2]].origin;
+ aa = dragon[conn_worm1[move_reasons[r].what]].origin;
+ bb = dragon[conn_worm2[move_reasons[r].what]].origin;
if (aa == bb)
continue;
- d1 = find_dragon(aa);
- d2 = find_dragon(bb);
+ a_id = dragon[aa].id;
+ b_id = dragon[bb].id;
/* If we are ahead by more than 20, value connections more strongly */
if ((color == WHITE && score > 20.0)
@@ -2174,8 +2157,8 @@ estimate_strategical_value(int pos, int
this_value = connection_value(aa, bb, pos, gg_abs(score));
else
this_value = connection_value(aa, bb, pos, 0);
- if (this_value > dragon_value[d1]) {
- dragon_value[d1] = this_value;
+ if (this_value > dragon_value[a_id]) {
+ dragon_value[a_id] = this_value;
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - %1m cut/connect strategic value\n",
pos, this_value, aa);
@@ -2187,8 +2170,8 @@ estimate_strategical_value(int pos, int
this_value = connection_value(bb, aa, pos, gg_abs(score));
else
this_value = connection_value(bb, aa, pos, 0);
- if (this_value > dragon_value[d2]) {
- dragon_value[d2] = this_value;
+ if (this_value > dragon_value[b_id]) {
+ dragon_value[b_id] = this_value;
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - %1m cut/connect strategic value\n",
pos, this_value, bb);
@@ -2231,8 +2214,8 @@ estimate_strategical_value(int pos, int
* we don't care about it, since otherwise we would count the
* points twice.
*/
- if (owl_defense_move_reason_known(pos, find_dragon(bb))
- || owl_attack_move_reason_known(pos, find_dragon(bb))) {
+ if (owl_defense_move_reason_known(pos, bb)
+ || owl_attack_move_reason_known(pos, bb)) {
DEBUG(DEBUG_MOVE_REASONS,
" %1m: 0.0 - vital for %1m: owl attack/defense as well\n",
pos, bb);
@@ -2260,8 +2243,8 @@ estimate_strategical_value(int pos, int
*
* FIXME: Improve the implementation.
*/
- d1 = move_reasons[r].what;
- aa = dragons[d1];
+ aa = move_reasons[r].what;
+ a_id = dragon[aa].id;
/* FIXME: This value cannot be computed without some
* measurement of how the actual move affects the dragon. The
@@ -2291,13 +2274,13 @@ estimate_strategical_value(int pos, int
if (dragon[adj].color == color
&& dragon[adj].status == CRITICAL
&& dragon2[d].safety != INESSENTIAL
- && !owl_defense_move_reason_known(pos, find_dragon(adj)))
+ && !owl_defense_move_reason_known(pos, adj))
this_value = 0.0;
}
}
- if (this_value > dragon_value[d1]) {
- dragon_value[d1] = this_value;
+ if (this_value > dragon_value[a_id]) {
+ dragon_value[a_id] = this_value;
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - %1m strategic attack/defend\n",
pos, this_value, aa);
@@ -2306,8 +2289,8 @@ estimate_strategical_value(int pos, int
break;
case UNCERTAIN_OWL_DEFENSE:
- d1 = move_reasons[r].what;
- aa = dragons[d1];
+ aa = move_reasons[r].what;
+ a_id = dragon[aa].id;
/* If there is an adjacent dragon which is critical we should
* skip this type of move reason, since attacking or defending
@@ -2333,8 +2316,8 @@ estimate_strategical_value(int pos, int
else
this_value = gg_min(2*dragon[aa].effective_size, gg_abs(0.65*score));
- if (this_value > dragon_value[d1]) {
- dragon_value[d1] = this_value;
+ if (this_value > dragon_value[a_id]) {
+ dragon_value[a_id] = this_value;
DEBUG(DEBUG_MOVE_REASONS,
" %1m: %f - %1m uncertain owl defense bonus\n",
pos, this_value, aa);
@@ -2344,17 +2327,17 @@ estimate_strategical_value(int pos, int
}
}
- for (k = 0; k < next_dragon; k++) {
+ for (k = 0; k < number_of_dragons; k++) {
if (dragon_value[k] == 0.0)
continue;
- aa = dragons[k];
+ aa = dragon2[k].origin;
/* If this dragon is critical but not attacked/defended by this
* move, we ignore the strategic effect.
*/
if (dragon[aa].status == CRITICAL
- && !owl_move_reason_known(pos, k)) {
+ && !owl_move_reason_known(pos, aa)) {
DEBUG(DEBUG_MOVE_REASONS, " %1m: 0.0 - disregarding strategic effect on
%1m (critical dragon)\n",
pos, aa);
continue;
@@ -2367,8 +2350,8 @@ estimate_strategical_value(int pos, int
*/
if (dragon[aa].status != DEAD
&& dragon[aa].size == worm[aa].size
- && (attack_move_reason_known(pos, find_worm(aa))
- || defense_move_reason_known(pos, find_worm(aa)))) {
+ && (attack_move_reason_known(pos, aa)
+ || defense_move_reason_known(pos, aa))) {
TRACE(" %1m: %f - %1m strategic value already counted - A.\n",
pos, dragon_value[k], aa);
continue;
@@ -2377,18 +2360,17 @@ estimate_strategical_value(int pos, int
* in a semeai, we have likewise already counted the points as
* territorial value.
*/
- if (owl_attack_move_reason_known(pos, k)
- || owl_defense_move_reason_known(pos, k)
- || move_reason_known(pos, SEMEAI_MOVE, k)) {
+ if (owl_attack_move_reason_known(pos, aa)
+ || owl_defense_move_reason_known(pos, aa)
+ || move_reason_known(pos, SEMEAI_MOVE, aa)) {
/* But if the strategical value was larger than the territorial
* value (e.g. because connecting to strong dragon) we award the
* excess value as a bonus.
*/
float excess_value = (dragon_value[k] -
- 2 * dragon[dragons[k]].effective_size);
+ 2 * dragon[aa].effective_size);
if (excess_value > 0.0) {
- TRACE(" %1m: %f - strategic bonus for %1m\n",
- pos, excess_value, dragons[k]);
+ TRACE(" %1m: %f - strategic bonus for %1m\n", pos, excess_value, aa);
tot_value += excess_value;
}
else {
@@ -2400,9 +2382,11 @@ estimate_strategical_value(int pos, int
}
TRACE(" %1m: %f - strategic effect on %1m\n",
- pos, dragon_value[k], dragons[k]);
+ pos, dragon_value[k], aa);
tot_value += dragon_value[k];
}
+
+ free(dragon_value);
/* Finally, subtract penalty for invasion type moves. */
this_value = strategic_penalty(pos, color);
@@ -2810,9 +2794,9 @@ reevaluate_ko_threats(int ko_move, int c
switch (move_reasons[r].type) {
case ATTACK_THREAT:
case DEFEND_THREAT:
- if (worm[worms[move_reasons[r].what]].effective_size
+ if (worm[move_reasons[r].what].effective_size
> threat_size) {
- threat_size = worm[worms[move_reasons[r].what]].effective_size;
+ threat_size = worm[move_reasons[r].what].effective_size;
type = move_reasons[r].type;
what = move_reasons[r].what;
}
@@ -2820,9 +2804,9 @@ reevaluate_ko_threats(int ko_move, int c
case OWL_ATTACK_THREAT:
case OWL_DEFEND_THREAT:
case SEMEAI_THREAT:
- if (dragon[dragons[move_reasons[r].what]].effective_size
+ if (dragon[move_reasons[r].what].effective_size
> threat_size) {
- threat_size = dragon[dragons[move_reasons[r].what]]\
+ threat_size = dragon[move_reasons[r].what]\
.effective_size;
type = move_reasons[r].type;
what = move_reasons[r].what;
@@ -2853,11 +2837,11 @@ reevaluate_ko_threats(int ko_move, int c
"reevaluate_ko_threats", ko_move, EMPTY, NO_MOVE)) {
switch (type) {
case ATTACK_THREAT:
- threat_does_work = attack(worms[what], NULL);
+ threat_does_work = attack(what, NULL);
break;
case DEFEND_THREAT:
- threat_does_work = (board[worms[what]] != EMPTY
- && find_defense(worms[what], NULL));
+ threat_does_work = (board[what] != EMPTY
+ && find_defense(what, NULL));
break;
case OWL_ATTACK_THREAT:
case OWL_DEFEND_THREAT:
- [gnugo-devel] defend both, attack either, worms[], dragons[],
Arend Bayer <=
- Re: [gnugo-devel] defend both, attack either, worms[], dragons[], Gunnar Farneback, 2002/12/10
- Re: [gnugo-devel] defend both, attack either, worms[], dragons[], Gunnar Farneback, 2002/12/11
- Re: [gnugo-devel] defend both, attack either, worms[], dragons[], Arend Bayer, 2002/12/11
- Re: [gnugo-devel] defend both, attack either, worms[], dragons[], Gunnar Farneback, 2002/12/11
- Re: [gnugo-devel] defend both, attack either, worms[], dragons[], Arend Bayer, 2002/12/12