[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [gnugo-devel] reading patch
From: |
Gunnar Farneback |
Subject: |
Re: [gnugo-devel] reading patch |
Date: |
Mon, 07 Oct 2002 22:08:12 +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) |
I wrote:
> Most notably reading:140 doesn't pass with this variant. It occurs to
> me that we should probably use the same type of moves that are
> generated by break_chain2_efficient_moves(), and in fact the same
> code. This would most likely solve reading:140 but possibly cause
> fewer failures in the rest of the test suite.
Implemented in the appended patch, which obviously conflicts with
Paul's patch. The regression delta is five PASSes.
reading:37 PASS
reading:140 PASS
reading:170 PASS
owl:237 PASS
nngs2:70 PASS
- new static function do_find_break_chain2_efficient_moves() split off
from break_chain2_efficient_moves()
- superstring_breakchain() revised
/Gunnar
Index: engine/reading.c
===================================================================
RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v
retrieving revision 1.78
diff -u -r1.78 reading.c
--- engine/reading.c 28 Sep 2002 14:15:26 -0000 1.78
+++ engine/reading.c 7 Oct 2002 19:56:41 -0000
@@ -176,6 +176,8 @@
static void break_chain_moves(int str, struct reading_moves *moves);
static void break_chain2_efficient_moves(int str,
struct reading_moves *moves);
+static void do_find_break_chain2_efficient_moves(int str, int adj,
+ struct reading_moves *moves);
static void break_chain2_moves(int str, struct reading_moves *moves,
int require_safe);
static void break_chain2_defense_moves(int str, struct reading_moves *moves);
@@ -4391,81 +4393,91 @@
static void
break_chain2_efficient_moves(int str, struct reading_moves *moves)
{
+ int r;
+ int adj, adjs[MAXCHAIN];
+
+ /* Find links with 2 liberties. */
+ adj = chainlinks2(str, adjs, 2);
+
+ for (r = 0; r < adj; r++)
+ do_find_break_chain2_efficient_moves(str, adjs[r], moves);
+}
+
+
+/* Helper function for break_chain2_efficient_moves(). */
+static void
+do_find_break_chain2_efficient_moves(int str, int adj,
+ struct reading_moves *moves)
+{
int color = board[str];
int other = OTHER_COLOR(color);
- int r;
int k;
- int adj, adjs[MAXCHAIN];
int adj2, adjs2[MAXCHAIN];
int libs[2];
int ai, aj;
int bi, bj;
int ci, cj;
+ ASSERT1(countlib(adj) == 2, adj);
- /* Find links with 2 liberties. */
- adj = chainlinks2(str, adjs, 2);
+ adj2 = chainlinks2(adj, adjs2, 1);
+ if (adj2 == 1 && countlib(str) > 2) {
+ int apos;
+ findlib(adjs2[0], 1, &apos);
+ if (!is_self_atari(apos, color))
+ ADD_CANDIDATE_MOVE(apos, 0, *moves);
+ return;
+ }
- for (r = 0; r < adj; r++) {
- adj2 = chainlinks2(adjs[r], adjs2, 1);
- if (adj2 == 1 && countlib(str) > 2) {
- int apos;
- findlib(adjs2[0], 1, &apos);
- if (!is_self_atari(apos, color))
- ADD_CANDIDATE_MOVE(apos, 0, *moves);
- continue;
- }
-
- if (adj2 > 1)
- continue;
+ if (adj2 > 1)
+ return;
- findlib(adjs[r], 2, libs);
- for (k = 0; k < 2; k++)
- if (approxlib(libs[k], other, 3, NULL) <= 2
- && !is_self_atari(libs[1 - k], color))
- ADD_CANDIDATE_MOVE(libs[1 - k], 0, *moves);
-
- /* A common special case is this kind of edge position
- *
- * ..XXX.
- * X.XOO.
- * XOOX*.
- * ......
- * ------
- *
- * where a move at * is most effective for saving the two stones
- * to the left.
- *
- * The code below tries to identify this case. We use the crude
- * heuristic that the two liberties of the X stone we want to
- * capture should be placed diagonally and that one liberty should
- * be on the edge. Then we propose to play the other liberty.
- * Notice that both moves may be proposed when attacking a stone
- * on 2-2.
- *
- * Update: This was too crude. Also require that the X stone is on
- * the second line and that the proposed move is not a self-atari.
- */
- ai = I(libs[0]);
- aj = J(libs[0]);
- bi = I(libs[1]);
- bj = J(libs[1]);
- ci = I(adjs[r]);
- cj = J(adjs[r]);
- if (gg_abs(ai - bi) == 1
- && gg_abs(aj - bj) == 1
- && (ci == 1 || ci == board_size - 2
- || cj == 1 || cj == board_size - 2)) {
-
- if ((ai == 0 || ai == board_size - 1
- || aj == 0 || aj == board_size - 1)
- && !is_self_atari(libs[1], board[str]))
- ADD_CANDIDATE_MOVE(libs[1], 0, *moves);
-
- if ((bi == 0 || bi == board_size - 1
- || bj == 0 || bj == board_size - 1)
- && !is_self_atari(libs[0], board[str]))
- ADD_CANDIDATE_MOVE(libs[0], 0, *moves);
- }
+ findlib(adj, 2, libs);
+ for (k = 0; k < 2; k++)
+ if (approxlib(libs[k], other, 3, NULL) <= 2
+ && !is_self_atari(libs[1 - k], color))
+ ADD_CANDIDATE_MOVE(libs[1 - k], 0, *moves);
+
+ /* A common special case is this kind of edge position
+ *
+ * ..XXX.
+ * X.XOO.
+ * XOOX*.
+ * ......
+ * ------
+ *
+ * where a move at * is most effective for saving the two stones
+ * to the left.
+ *
+ * The code below tries to identify this case. We use the crude
+ * heuristic that the two liberties of the X stone we want to
+ * capture should be placed diagonally and that one liberty should
+ * be on the edge. Then we propose to play the other liberty.
+ * Notice that both moves may be proposed when attacking a stone
+ * on 2-2.
+ *
+ * Update: This was too crude. Also require that the X stone is on
+ * the second line and that the proposed move is not a self-atari.
+ */
+ ai = I(libs[0]);
+ aj = J(libs[0]);
+ bi = I(libs[1]);
+ bj = J(libs[1]);
+ ci = I(adj);
+ cj = J(adj);
+ if (gg_abs(ai - bi) == 1
+ && gg_abs(aj - bj) == 1
+ && (ci == 1 || ci == board_size - 2
+ || cj == 1 || cj == board_size - 2)) {
+
+ if ((ai == 0 || ai == board_size - 1
+ || aj == 0 || aj == board_size - 1)
+ && !is_self_atari(libs[1], board[str]))
+ ADD_CANDIDATE_MOVE(libs[1], 0, *moves);
+
+ if ((bi == 0 || bi == board_size - 1
+ || bj == 0 || bj == board_size - 1)
+ && !is_self_atari(libs[0], board[str]))
+ ADD_CANDIDATE_MOVE(libs[0], 0, *moves);
}
}
@@ -4701,20 +4713,32 @@
int adjs[MAXCHAIN];
int k;
int apos;
+ struct reading_moves moves;
int savemove = 0;
int savecode = 0;
SETUP_TRACE_INFO("superstring_breakchain", str);
+ moves.num = 0;
+
proper_superstring_chainlinks(str, &adj, adjs, liberty_cap);
for (k = 0; k < adj; k++) {
+ int liberties = countlib(adjs[k]);
+ if (liberties == 1) {
+ findlib(adjs[k], 1, &apos);
+ ADD_CANDIDATE_MOVE(apos, 0, moves);
+ }
+ else if (liberties == 2)
+ do_find_break_chain2_efficient_moves(str, adjs[k], &moves);
+ }
+
+ order_moves(str, &moves, color, read_function_name, 0);
+
+ for (k = 0; k < moves.num; k++) {
int new_komaster, new_kom_pos;
int ko_move;
- if (countlib(adjs[k]) > 1)
- continue;
- findlib(adjs[k], 1, &apos);
-
+ apos = moves.pos[k];
if (komaster_trymove(apos, color, "superstring_break_chain", str,
komaster, kom_pos, &new_komaster, &new_kom_pos,
&ko_move, savecode == 0 && stackp <= ko_depth)) {