[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] blunder_size() code reorganization
From: |
Gunnar Farneback |
Subject: |
[gnugo-devel] blunder_size() code reorganization |
Date: |
Mon, 16 Sep 2002 21:48:35 +0200 |
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) |
This patch reorganizes the blunder_size() function in utils.c,
splitting off two static functions detect_owl_blunder() and
detect_tactical_blunder(). It should have no effects at all on
the move generation.
- blunder_size() code reorganized
- new static functions detect_owl_blunder() and
detect_tactical_blunder() in utils.c
/Gunnar
Index: engine/utils.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/utils.c,v
retrieving revision 1.51
diff -u -r1.51 utils.c
--- engine/utils.c 2 Sep 2002 14:19:22 -0000 1.51
+++ engine/utils.c 16 Sep 2002 14:36:01 -0000
@@ -807,13 +807,27 @@
return liberties;
}
+/*******************
+ * Detect blunders *
+ *******************/
+
+static int detect_owl_blunder(int move, int color, int *defense_point,
+ char safe_stones[BOARDMAX], int liberties,
+ float *return_value, int save_verbose);
+
+static void detect_tactical_blunder(int move, int color, int *defense_point,
+ char safe_stones[BOARDMAX],
+ int liberties, int *libs,
+ float *return_value, int save_verbose);
+/* Check that the move at color doesn't involve any kind of blunder,
+ * regardless of size.
+ */
int
confirm_safety(int move, int color, int *defense_point,
char safe_stones[BOARDMAX])
{
- return (blunder_size(move, color, defense_point, safe_stones)
- == 0.0);
+ return (blunder_size(move, color, defense_point, safe_stones) == 0.0);
}
/* This function will detect some blunders. If the move reduces the
@@ -840,15 +854,12 @@
{
int libs[5];
int liberties = accurate_approxlib(move, color, 5, libs);
- int other = OTHER_COLOR(color);
- int pos;
int apos;
int trouble = 0;
- int k;
- int ii;
int save_verbose = verbose;
float return_value = 0.0;
-
+ int atari;
+
if (defense_point)
*defense_point = NO_MOVE;
@@ -857,12 +868,65 @@
if (verbose > 0)
verbose--;
- if (liberties > 4)
- goto atari_atari;
+ /* We start by checking whether we have accidentally killed an own
+ * dragon.
+ *
+ * FIXME: The liberties check isn't appropriate since the move may
+ * reduce own eyespace regardless of the number of outer liberties.
+ */
+ if (liberties <= 4)
+ trouble = detect_owl_blunder(move, color, defense_point,
+ safe_stones, liberties,
+ &return_value, save_verbose);
+
+
+ /* Next we see whether the move has caused tactical complications.
+ * The trouble variable is set if a string next to the move with few
+ * liberties has not gained liberties by the move.
+ */
+ if (trouble)
+ detect_tactical_blunder(move, color, defense_point, safe_stones,
+ liberties, libs, &return_value, save_verbose);
+
+ /* FIXME: We would also need a detect_semeai_blunder() to check
+ * against moves which make the outcome of a semeai worse, e.g. by
+ * letting the opponent live in seki.
+ */
- /* We start by looking whether we have killed a dragon. If this happens,
- * we mark its stones as no longer safe, and remember the dragon's size.
+
+ /* Finally we call the atari-atari code to see whether the move has
+ * set up some combination attack that didn't exist before. We do
+ * this last to avoid duplicate blunder reports.
*/
+ atari = atari_atari_blunder_size(color, move, &apos, safe_stones);
+ if (atari) {
+ ASSERT_ON_BOARD1(apos);
+ if (defense_point)
+ *defense_point = apos;
+ verbose = save_verbose;
+ TRACE("Combination attack appears at %1m.\n", apos);
+ return_value += (float) atari;
+ }
+
+ verbose = save_verbose;
+ return return_value;
+}
+
+/* Check whether we have accidentally killed an own dragon adjacent to
+ * move. If this happens, we mark its stones as no longer safe, and
+ * remember the dragon's size.
+ */
+
+static int
+detect_owl_blunder(int move, int color, int *defense_point,
+ char safe_stones[BOARDMAX], int liberties,
+ float *return_value, int save_verbose)
+{
+ int k;
+ int ii;
+ int trouble = 0;
+ int current_verbose = verbose;
+
for (k = 0; k < 4; k++) {
int bpos = move + delta[k];
if (board[bpos] == color
@@ -876,9 +940,8 @@
&& !owl_confirm_safety(move, bpos, defense_point)) {
verbose = save_verbose;
TRACE("Dragon at %1m becomes attackable.\n", bpos);
- if (verbose > 0)
- verbose--;
- return_value += 2.0 * dragon[bpos].effective_size;
+ verbose = current_verbose;
+ *return_value += 2.0 * dragon[bpos].effective_size;
if (safe_stones)
for (ii = BOARDMIN; ii < BOARDMAX; ii++)
if (ON_BOARD(ii) && dragon[ii].origin == dragon[bpos].origin)
@@ -887,105 +950,121 @@
}
}
- verbose = save_verbose;
+ return trouble;
+}
- if (!trouble)
- goto atari_atari;
+/* Check whether a move causes any unexpected and unwelcome changes in
+ * the tactical status of worms all over the board.
+ */
+static void
+detect_tactical_blunder(int move, int color, int *defense_point,
+ char safe_stones[BOARDMAX],
+ int liberties, int *libs,
+ float *return_value, int save_verbose)
+{
+ int other = OTHER_COLOR(color);
+ int pos;
+ int ii;
+ int current_verbose = save_verbose;
+ if (!trymove(move, color, NULL, NO_MOVE, EMPTY, NO_MOVE))
+ return;
+
/* Need to increase the depth values during this reading to avoid
* horizon effects.
*/
increase_depth_values();
- if (trymove(move, color, NULL, NO_MOVE, EMPTY, NO_MOVE)) {
- for (pos = BOARDMIN; pos < BOARDMAX; pos++)
- if (IS_STONE(board[pos])
- && worm[pos].origin == pos
- && pos != move) {
- /* First, we look for a new tactical attack. */
- if (board[pos] == color
- && ((safe_stones && safe_stones[pos])
- || (!safe_stones && worm[pos].attack_codes[0] == 0))
- && attack(pos, NULL)) {
- /* A safe worm of ours has become attackable. */
- if (defense_point)
- find_defense(pos, defense_point);
- TRACE("After %1m Worm at %1m becomes attackable.\n", move, pos);
- return_value += worm[pos].effective_size;
- if (safe_stones) /* Can't use mark_string. */
- for (ii = BOARDMIN; ii < BOARDMAX; ii++)
- if (worm[ii].origin == worm[pos].origin)
- safe_stones[ii] = 0;
- }
- else if (board[pos] == other
- && worm[pos].origin == pos
- && worm[pos].attack_codes[0] != 0
- && worm[pos].defend_codes[0] == 0
- && find_defense(pos, NULL)) {
- /* A dead opponent's worm has become defendable.
- * Also ask the owl code whether the string can live
- * strategically. To do this we need to temporarily undo
- * the trymove().
- */
- int owl_attacks;
-
- popgo();
- decrease_depth_values();
- owl_attacks = owl_does_attack(move, pos);
- if (owl_attacks != WIN) {
- return_value += worm[pos].effective_size;
- TRACE("After %1m worm at %1m becomes defendable.\n",
- move, pos);
- }
- trymove(move, color, NULL, NO_MOVE, EMPTY, NO_MOVE);
- increase_depth_values();
-
- if (owl_attacks != WIN && defense_point) {
- int dpos;
- if (attack(pos, &dpos))
- *defense_point = dpos;
- else
- TRACE("No attack found (unexpectedly) on %1m after move at
%1m.\n",
- pos, move);
- }
- }
- }
+ for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+ if (!IS_STONE(board[pos])
+ || worm[pos].origin != pos
+ || pos == move)
+ continue;
- if (liberties == 2) {
- float d_a_blunder_size;
- if (double_atari(libs[0], other, &d_a_blunder_size, safe_stones)) {
- if (defense_point && safe_move(libs[0], color) == WIN)
- *defense_point = libs[0];
- return_value += d_a_blunder_size;
- TRACE("Double threat appears at %1m.\n", libs[0]);
+ /* First, we look for a new tactical attack. */
+ if (board[pos] == color
+ && ((safe_stones && safe_stones[pos])
+ || (!safe_stones && worm[pos].attack_codes[0] == 0))
+ && attack(pos, NULL)) {
+ /* A safe worm of ours has become attackable. */
+ if (defense_point)
+ find_defense(pos, defense_point);
+ verbose = save_verbose;
+ TRACE("After %1m Worm at %1m becomes attackable.\n", move, pos);
+ verbose = current_verbose;
+ *return_value += worm[pos].effective_size;
+ if (safe_stones) /* Can't use mark_string. */
+ for (ii = BOARDMIN; ii < BOARDMAX; ii++)
+ if (worm[ii].origin == worm[pos].origin)
+ safe_stones[ii] = 0;
+ }
+ else if (board[pos] == other
+ && worm[pos].origin == pos
+ && worm[pos].attack_codes[0] != 0
+ && worm[pos].defend_codes[0] == 0
+ && find_defense(pos, NULL)) {
+ /* A dead opponent's worm has become defendable.
+ * Also ask the owl code whether the string can live
+ * strategically. To do this we need to temporarily undo
+ * the trymove().
+ */
+ int owl_attacks;
+
+ popgo();
+ decrease_depth_values();
+ owl_attacks = owl_does_attack(move, pos);
+ if (owl_attacks != WIN) {
+ *return_value += worm[pos].effective_size;
+ verbose = save_verbose;
+ TRACE("After %1m worm at %1m becomes defendable.\n", move, pos);
+ verbose = current_verbose;
}
- else if (double_atari(libs[1], other, &d_a_blunder_size, safe_stones)) {
- if (defense_point && safe_move(libs[1], color) == WIN)
- *defense_point = libs[1];
- return_value += d_a_blunder_size;
- TRACE("Double threat appears at %1m.\n", libs[1]);
+ trymove(move, color, NULL, NO_MOVE, EMPTY, NO_MOVE);
+ increase_depth_values();
+
+ if (owl_attacks != WIN && defense_point) {
+ int dpos;
+ if (attack(pos, &dpos))
+ *defense_point = dpos;
+ else {
+ verbose = save_verbose;
+ TRACE("No attack found (unexpectedly) on %1m after move at %1m.\n",
+ pos, move);
+ verbose = current_verbose;
+ }
}
}
- popgo();
}
-
- /* Reset the depth values. */
- decrease_depth_values();
- /* We call the atari-atari code last to avoid duplicate blunder reports. */
-atari_atari:
- {
- int atari = atari_atari_blunder_size(color, move, &apos, safe_stones);
- if (atari) {
- ASSERT_ON_BOARD1(apos);
- if (defense_point)
- *defense_point = apos;
- TRACE("Combination attack appears at %1m.\n", apos);
- return_value += (float) atari;
+ /* Look for double atari style complications of the move.
+ *
+ * FIXME: Since we have an atari_atari check in blunder_size(), do
+ * we still need to do this step?
+ */
+ if (liberties == 2) {
+ float d_a_blunder_size;
+ if (double_atari(libs[0], other, &d_a_blunder_size, safe_stones)) {
+ if (defense_point && safe_move(libs[0], color) == WIN)
+ *defense_point = libs[0];
+ *return_value += d_a_blunder_size;
+ verbose = save_verbose;
+ TRACE("Double threat appears at %1m.\n", libs[0]);
+ verbose = current_verbose;
+ }
+ else if (double_atari(libs[1], other, &d_a_blunder_size, safe_stones)) {
+ if (defense_point && safe_move(libs[1], color) == WIN)
+ *defense_point = libs[1];
+ *return_value += d_a_blunder_size;
+ verbose = save_verbose;
+ TRACE("Double threat appears at %1m.\n", libs[1]);
+ verbose = current_verbose;
}
}
+
+ /* Reset the depth values. */
+ decrease_depth_values();
- return return_value;
+ popgo();
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnugo-devel] blunder_size() code reorganization,
Gunnar Farneback <=