[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnugo-devel] Patch: semeai.c and filllib.c now 1-dimensional
From: |
Inge Wallin |
Subject: |
[gnugo-devel] Patch: semeai.c and filllib.c now 1-dimensional |
Date: |
Tue, 16 Oct 2001 22:16:25 +0200 (MET DST) |
Here is a patch that makes filllib.c and semeai.c 1-dimensional.
Summary:
- filllib.c and semeai.c made 1-dimensional.
All clear? :-)
-Inge
Only in gnugo-3.1.10p1iw1: Makefile
Only in gnugo-3.1.10p1iw1: config.h
Only in gnugo-3.1.10p1iw1: config.log
diff -ur gnugo-3.1.10p1/engine/filllib.c gnugo-3.1.10p1iw1/engine/filllib.c
--- gnugo-3.1.10p1/engine/filllib.c Fri Oct 12 17:06:46 2001
+++ gnugo-3.1.10p1iw1/engine/filllib.c Tue Oct 16 22:16:47 2001
@@ -29,7 +29,8 @@
#include "liberty.h"
static int find_backfilling_move(int move, int color, int *backfill_move);
-static int filllib_confirm_safety(int m, int n, int color, int *di, int *dj);
+static int filllib_confirm_safety(int pos, int color, int *di, int *dj);
+
/* Determine whether a point is adjacent to at least one own string which
* isn't dead.
@@ -48,7 +49,7 @@
}
-/* Determine whether (m, n) effectively is a black or white point.
+/* Determine whether (pos) effectively is a black or white point.
* The test for inessentiality is to avoid filling the liberties
* around a killing nakade string.
*/
@@ -96,7 +97,7 @@
* that several backfilling moves are ultimately necessary.
*
* If a move for color is found, return 1, otherwise return 0.
- * The move is returned in (*i, *j).
+ * The move is returned in (*move).
*/
int
@@ -117,33 +118,34 @@
memset(potential_color, 0, sizeof(potential_color));
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
- int pos = POS(m, n);
- if (board[pos] == EMPTY)
+ int ii = POS(m, n);
+
+ if (board[ii] == EMPTY)
continue;
- if (worm[pos].inessential || DRAGON2(pos).safety == INESSENTIAL)
+ if (worm[ii].inessential || DRAGON2(ii).safety == INESSENTIAL)
continue;
- if (dragon[pos].matcher_status != ALIVE) {
+ if (dragon[ii].matcher_status != ALIVE) {
for (k = 0; k < 4; k++) {
- int pos2 = pos + delta[k];
- if (board[pos2] == EMPTY)
- potential_color[pos2] |= OTHER_COLOR(board[pos]);
+ int jj = ii + delta[k];
+
+ if (board[jj] == EMPTY)
+ potential_color[jj] |= OTHER_COLOR(board[ii]);
}
}
- if (dragon[pos].matcher_status != DEAD) {
+ if (dragon[ii].matcher_status != DEAD) {
for (k = 0; k < 12; k++) {
- int di = deltai[k%8];
- int dj = deltaj[k%8];
+ int d = delta[k%8];
+
if (k >= 8) {
- if (BOARD(m+di, n+dj) != EMPTY)
+ if (board[ii+d] != EMPTY)
continue;
- di *= 2;
- dj *= 2;
+ d *= 2;
}
- if (BOARD(m+di, n+dj) == EMPTY)
- potential_color[POS(m+di, n+dj)] |= board[pos];
+ if (board[ii+d] == EMPTY)
+ potential_color[ii+d] |= board[ii];
}
}
}
@@ -151,7 +153,8 @@
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
- int pos = POS(m, n);
+ int ii = POS(m, n);
+
/* It seems we can't trust an empty liberty to be gray-colored
* either as a cave or as a cavity. Instead we look for empty
* intersections with at least one neighbor of each color, where
@@ -161,19 +164,19 @@
int found_white = 0;
int found_black = 0;
- if (board[pos] != EMPTY)
+ if (board[ii] != EMPTY)
continue;
/* Quick rejection based on preliminary test above. */
- if (potential_color[POS(m, n)] != GRAY)
+ if (potential_color[ii] != GRAY)
continue;
/* Loop over the neighbors. */
for (k = 0; k < 4; k++) {
- int dm = deltai[k];
- int dn = deltaj[k];
- if (ON_BOARD(POS(m+dm, n+dn)))
- analyze_neighbor(POS(m+dm, n+dn), &found_black, &found_white);
+ int d = delta[k];
+
+ if (ON_BOARD(ii+d))
+ analyze_neighbor(ii+d, &found_black, &found_white);
}
/* Do we have neighbors of both colors? */
@@ -190,18 +193,18 @@
* 6. Move would violate confirm_safety.
*/
- DEBUG(DEBUG_FILLLIB, "Filllib: Considering move at %m.\n", m, n);
+ DEBUG(DEBUG_FILLLIB, "Filllib: Considering move at %1m.\n", ii);
/* Legal and tactically safe, play it if it passes
* confirm_safety test, i.e. that it isn't a blunder which
* causes problems for other strings.
*/
- if (safe_move(pos, color) == WIN) {
+ if (safe_move(ii, color) == WIN) {
DEBUG(DEBUG_FILLLIB, "Filllib: Tactically safe.\n");
- if (filllib_confirm_safety(m, n, color, &di, &dj)) {
+ if (filllib_confirm_safety(ii, color, &di, &dj)) {
/* Safety confirmed. */
DEBUG(DEBUG_FILLLIB, "Filllib: Safety confirmed.\n");
- *move = POS(m, n);
+ *move = ii;
return 1;
}
else if (di != -1) {
@@ -228,13 +231,13 @@
}
/* Try to play the move. */
- if (trymove(pos, color, "fill_liberty", NO_MOVE, EMPTY, NO_MOVE)) {
+ if (trymove(ii, color, "fill_liberty", NO_MOVE, EMPTY, NO_MOVE)) {
popgo();
/* Legal, but not safe. Look for backfilling move. */
DEBUG(DEBUG_FILLLIB,
"Filllib: Legal but not safe, looking for backfilling move.\n");
- if (find_backfilling_move(POS(m, n), color, move)) {
+ if (find_backfilling_move(ii, color, move)) {
DEBUG(DEBUG_FILLLIB, "Filllib: Backfilling move at %1m.\n", *move);
/* In certain positions it may happen that an illegal move
* is found. This probably only can happen if we try to play
@@ -250,7 +253,7 @@
/* If the move turns out to be strategically unsafe, or
* setting up a double threat elsewhere, also discard it.
*/
- if (!filllib_confirm_safety(I(*move), J(*move), color, &di, &dj)) {
+ if (!filllib_confirm_safety(*move, color, &di, &dj)) {
DEBUG(DEBUG_FILLLIB,
"Filllib: Safety not confirmed, discarded.\n");
continue;
@@ -261,15 +264,15 @@
}
else {
/* If we captured some stones, this move should be ok anyway. */
- if (does_capture_something(pos, color)) {
+ if (does_capture_something(ii, color)) {
DEBUG(DEBUG_FILLLIB,
"Filllib: Not tactically safe, but captures stones.\n");
- if (!filllib_confirm_safety(m, n, color, &di, &dj)) {
+ if (!filllib_confirm_safety(ii, color, &di, &dj)) {
DEBUG(DEBUG_FILLLIB,
"Filllib: Safety not confirmed, discarded.\n");
continue;
}
- *move = POS(m, n);
+ *move = ii;
return 1;
}
}
@@ -280,11 +283,11 @@
*/
DEBUG(DEBUG_FILLLIB, "Filllib: Illegal, looking for back-capture.\n");
for (k = 0; k < 4; k++) {
- int dm = deltai[k];
- int dn = deltaj[k];
- if (BOARD(m+dm, n+dn) == other
- && worm[POS(m+dm, n+dn)].attack_codes[0] == WIN) {
- *move = worm[POS(m+dm, n+dn)].attack_points[0];
+ int d = delta[k];
+
+ if (board[ii+d] == other
+ && worm[ii+d].attack_codes[0] == WIN) {
+ *move = worm[ii+d].attack_points[0];
DEBUG(DEBUG_FILLLIB, "Filllib: Found at %1m.\n", *move);
return 1;
}
@@ -293,12 +296,12 @@
DEBUG(DEBUG_FILLLIB,
"Filllib: Nothing found, looking for ko back-capture.\n");
for (k = 0; k < 4; k++) {
- int dm = deltai[k];
- int dn = deltaj[k];
- if (BOARD(m+dm, n+dn) == other
- && worm[POS(m+dm, n+dn)].attack_codes[0] != 0
- && is_legal(worm[POS(m+dm, n+dn)].attack_points[0], color)) {
- *move = worm[POS(m+dm, n+dn)].attack_points[0];
+ int d = delta[k];
+
+ if (board[ii+d] == other
+ && worm[ii+d].attack_codes[0] != 0
+ && is_legal(worm[ii+d].attack_points[0], color)) {
+ *move = worm[ii+d].attack_points[0];
DEBUG(DEBUG_FILLLIB, "Filllib: Found at %1m.\n", *move);
return 1;
}
@@ -307,13 +310,13 @@
DEBUG(DEBUG_FILLLIB,
"Filllib: Nothing found, looking for threat to back-capture.\n");
for (k = 0; k < 4; k++) {
- int dm = deltai[k];
- int dn = deltaj[k];
- if (BOARD(m+dm, n+dn) == other
- && worm[POS(m+dm, n+dn)].attack_codes[0] != 0) {
+ int d = delta[k];
+
+ if (board[ii+d] == other
+ && worm[ii+d].attack_codes[0] != 0) {
/* Just pick some other liberty. */
int libs[2];
- if (findlib(POS(m+dm, n+dn), 2, libs) > 1) {
+ if (findlib(ii+d, 2, libs) > 1) {
if (is_legal(libs[0], color))
*move = libs[0];
else if (is_legal(libs[1], color))
@@ -325,6 +328,7 @@
}
}
}
+
/* Nothing found. */
DEBUG(DEBUG_FILLLIB, "Filllib: No move found.\n");
@@ -335,15 +339,15 @@
/* The strategy for finding a backfilling move is to first identify
* moves that
*
- * 1. defends the position obtained after playing (m,n).
- * 2. captures a stone adjacent to our neighbors to (m,n), before
- * (m,n) is played.
+ * 1. defends the position obtained after playing (move).
+ * 2. captures a stone adjacent to our neighbors to (move), before
+ * (move) is played.
*
- * Then we check which of these are legal before (m,n) is played. If
+ * Then we check which of these are legal before (move) is played. If
* there is at least one, we take one of these arbitrarily as a
* backfilling move.
*
- * Now it may happen that (m,n) still isn't a safe move. In that case
+ * Now it may happen that (move) still isn't a safe move. In that case
* we recurse to find a new backfilling move. To do things really
* correctly we should also give the opponent the opportunity to keep
* up the balance of the position by letting him do a backfilling move
@@ -361,22 +365,22 @@
int liberties;
int neighbors;
int found_one = 0;
- int apos = NO_MOVE;
- int bpos = NO_MOVE;
+ int aa = NO_MOVE;
+ int bb = NO_MOVE;
int extra_pop = 0;
int success = 0;
int acode;
int saved_move = NO_MOVE;
- /* Play (m,n) and identify all liberties and adjacent strings. */
+ /* Play (move) and identify all liberties and adjacent strings. */
if (!trymove(move, color, "find_backfilling_move", move, EMPTY, NO_MOVE))
return 0; /* This shouldn't happen, I believe. */
/* The move wasn't safe, so there must be an attack for the
* opponent. Save it for later use.
*/
- acode = attack(move, &apos);
- gg_assert(acode != 0 && apos > NO_MOVE);
+ acode = attack(move, &aa);
+ gg_assert(acode != 0 && aa > NO_MOVE);
/* Find liberties. */
liberties = findlib(move, MAXLIBS, libs);
@@ -384,7 +388,7 @@
/* Find neighbors. */
neighbors = chainlinks(move, adjs);
- /* Remove (m,n) again. */
+ /* Remove (move) again. */
popgo();
/* It's most fun to capture stones. Start by trying to take some
@@ -404,13 +408,13 @@
* good enough.
*/
for (k = 0; k < neighbors; k++) {
- if (attack(adjs[k], &bpos) == WIN) {
- if (liberty_of_string(bpos, adjs[k])) {
- *backfill_move = bpos;
+ if (attack(adjs[k], &bb) == WIN) {
+ if (liberty_of_string(bb, adjs[k])) {
+ *backfill_move = bb;
return 1;
}
else
- saved_move = bpos;
+ saved_move = bb;
}
}
@@ -447,7 +451,7 @@
return 0; /* This really shouldn't happen. */
/* Allow opponent to get a move in here. */
- if (trymove(apos, OTHER_COLOR(color), "find_backfilling_move", move,
+ if (trymove(aa, OTHER_COLOR(color), "find_backfilling_move", move,
EMPTY, NO_MOVE))
extra_pop = 1;
@@ -472,15 +476,17 @@
}
-/* Confirm that (m, n) is a safe move for color. In addition to
+/* Confirm that (pos) is a safe move for color. In addition to
* calling the global confirm_safety(), this function also calls the
* owl code to verify the strategical viability of the move.
+ *
+ * FIXME: Make di, dj 1-dimensional when confirm_safety() is 1-d
*/
static int
-filllib_confirm_safety(int m, int n, int color, int *di, int *dj)
+filllib_confirm_safety(int pos, int color, int *di, int *dj)
{
int k;
- int ai = -1, aj = -1;
+ int aa = NO_MOVE;
int save_verbose;
gg_assert(stackp == 0);
@@ -491,21 +497,20 @@
* our color.
*/
for (k = 0; k < 4; k++)
- if (BOARD(m + deltai[k], n + deltaj[k]) == color) {
- ai = m + deltai[k];
- aj = n + deltaj[k];
+ if (board[pos + delta[k]] == color) {
+ aa = pos + delta[k];
break;
}
/* If none found, look for a neighbor of an attacked adjacent string. */
- if (ai == -1)
+ if (aa == NO_MOVE)
for (k = 0; k < 4; k++) {
- int i = m + deltai[k];
- int j = n + deltaj[k];
- if (BOARD(i, j) == OTHER_COLOR(color)
- && !play_attack_defend_n(color, 0, 1, m, n, i, j)) {
+ int ii = pos + delta[k];
+
+ if (board[ii] == OTHER_COLOR(color)
+ && !play_attack_defend_n(color, 0, 1, I(pos), J(pos), I(ii), J(ii))) {
int adj;
- adj = chainlinks(POS(i, j), adjs);
+ adj = chainlinks(ii, adjs);
/* It seems unlikely that we would ever get adjacent strings
* here, but if it should happen we simply give up and say the
* move is unsafe.
@@ -513,8 +518,7 @@
if (adj == 0)
return 0;
- ai = I(adjs[0]);
- aj = J(adjs[0]);
+ aa = adjs[0];
break;
}
}
@@ -522,7 +526,7 @@
/* We should have found something by now. If not something's
* probably broken elsewhere. Declare the move unsafe if it happens.
*/
- if (ai == -1)
+ if (aa == NO_MOVE)
return 0;
/* Ask the owl code whether this move is strategically viable. */
@@ -530,11 +534,11 @@
save_verbose = verbose;
if (verbose > 0)
verbose--;
- if (!owl_does_defend(m, n, ai, aj))
+ if (!owl_does_defend(I(pos), J(pos), I(aa), J(aa)))
return 0;
verbose = save_verbose;
- return confirm_safety(m, n, color, 0, di, dj);
+ return confirm_safety(I(pos), J(pos), color, 0, di, dj);
}
Only in gnugo-3.1.10p1iw1/engine: filllib.c.save
Only in gnugo-3.1.10p1iw1/engine: filllib.c~
Binary files gnugo-3.1.10p1/engine/filllib.o and
gnugo-3.1.10p1iw1/engine/filllib.o differ
Binary files gnugo-3.1.10p1/engine/fuseki.o and
gnugo-3.1.10p1iw1/engine/fuseki.o differ
Binary files gnugo-3.1.10p1/engine/genmove.o and
gnugo-3.1.10p1iw1/engine/genmove.o differ
Binary files gnugo-3.1.10p1/engine/globals.o and
gnugo-3.1.10p1iw1/engine/globals.o differ
Binary files gnugo-3.1.10p1/engine/hash.o and gnugo-3.1.10p1iw1/engine/hash.o
differ
Binary files gnugo-3.1.10p1/engine/influence.o and
gnugo-3.1.10p1iw1/engine/influence.o differ
Binary files gnugo-3.1.10p1/engine/interface.o and
gnugo-3.1.10p1iw1/engine/interface.o differ
Binary files gnugo-3.1.10p1/engine/libboard.a and
gnugo-3.1.10p1iw1/engine/libboard.a differ
Binary files gnugo-3.1.10p1/engine/libengine.a and
gnugo-3.1.10p1iw1/engine/libengine.a differ
diff -ur gnugo-3.1.10p1/engine/liberty.h gnugo-3.1.10p1iw1/engine/liberty.h
--- gnugo-3.1.10p1/engine/liberty.h Tue Oct 16 19:57:07 2001
+++ gnugo-3.1.10p1iw1/engine/liberty.h Tue Oct 16 20:24:24 2001
@@ -364,7 +364,6 @@
void fuseki(int color);
void semeai(int color);
void small_semeai(void);
-void small_semeai_analyzer(int, int, int, int);
void shapes(int color);
void endgame_shapes(int color);
Only in gnugo-3.1.10p1iw1/engine: liberty.h~
Binary files gnugo-3.1.10p1/engine/life.o and gnugo-3.1.10p1iw1/engine/life.o
differ
Binary files gnugo-3.1.10p1/engine/matchpat.o and
gnugo-3.1.10p1iw1/engine/matchpat.o differ
Binary files gnugo-3.1.10p1/engine/move_reasons.o and
gnugo-3.1.10p1iw1/engine/move_reasons.o differ
Binary files gnugo-3.1.10p1/engine/optics.o and
gnugo-3.1.10p1iw1/engine/optics.o differ
Binary files gnugo-3.1.10p1/engine/owl.o and gnugo-3.1.10p1iw1/engine/owl.o
differ
Binary files gnugo-3.1.10p1/engine/printutils.o and
gnugo-3.1.10p1iw1/engine/printutils.o differ
Binary files gnugo-3.1.10p1/engine/readconnect.o and
gnugo-3.1.10p1iw1/engine/readconnect.o differ
Binary files gnugo-3.1.10p1/engine/reading.o and
gnugo-3.1.10p1iw1/engine/reading.o differ
Binary files gnugo-3.1.10p1/engine/score.o and gnugo-3.1.10p1iw1/engine/score.o
differ
diff -ur gnugo-3.1.10p1/engine/semeai.c gnugo-3.1.10p1iw1/engine/semeai.c
--- gnugo-3.1.10p1/engine/semeai.c Fri Oct 12 17:06:54 2001
+++ gnugo-3.1.10p1iw1/engine/semeai.c Tue Oct 16 21:49:31 2001
@@ -28,9 +28,8 @@
#define INFINITY 1000
-static void analyze_semeai(int m, int n, int i, int j);
-static void add_appropriate_semeai_moves(int ti, int tj,
- int ai, int aj, int bi, int bj,
+static void analyze_semeai(int aa, int bb);
+static void add_appropriate_semeai_moves(int pos, int aa, int bb,
int my_status, int your_status,
int margin_of_safety);
@@ -47,8 +46,8 @@
{
int d1, d2;
int k;
- int ai = -1, aj = -1;
- int bi = -1, bj = -1;
+ int aa = NO_MOVE;
+ int bb = NO_MOVE;
int other = OTHER_COLOR(color);
TRACE("Semeai Player is THINKING for %s!\n",
@@ -70,50 +69,45 @@
/* Dragons d1 (our) and d2 (opponent) are adjacent and both DEAD
* or CRITICAL.
*/
- ai = I(DRAGON(d1).origin);
- aj = J(DRAGON(d1).origin);
- bi = I(DRAGON(d2).origin);
- bj = J(DRAGON(d2).origin);
+ aa = DRAGON(d1).origin;
+ bb = DRAGON(d2).origin;
/* Ignore inessential worms or dragons */
- if (worm[POS(ai, aj)].inessential
- || DRAGON2(POS(ai, aj)).safety == INESSENTIAL
- || worm[POS(bi, bj)].inessential
- || DRAGON2(POS(bi, bj)).safety == INESSENTIAL)
+ if (worm[aa].inessential
+ || DRAGON2(aa).safety == INESSENTIAL
+ || worm[bb].inessential
+ || DRAGON2(bb).safety == INESSENTIAL)
continue;
- analyze_semeai(ai, aj, bi, bj);
+ analyze_semeai(aa, bb);
}
}
}
-/* liberty_of_dragon(i, j, m, n) returns true if the vertex at (i, j) is a
- * liberty of the dragon with origin at (m, n).
+
+/* liberty_of_dragon(pos, dr) returns true if the vertex at (pos) is a
+ * liberty of the dragon with origin at (dr).
*/
static int
-liberty_of_dragon(int i, int j, int m, int n)
+liberty_of_dragon(int pos, int dr)
{
- if (i == -1)
+ if (pos == NO_MOVE)
return 0;
- if (BOARD(i, j) != EMPTY)
+ if (board[pos] != EMPTY)
return 0;
- if (i > 0
- && dragon[POS(i-1, j)].origin == POS(m, n))
+ if (ON_BOARD(pos-NS) && dragon[pos-NS].origin == dr)
return 1;
- if (i < board_size - 1
- && dragon[POS(i+1, j)].origin == POS(m, n))
+ if (ON_BOARD(pos+NS) && dragon[pos+NS].origin == dr)
return 1;
- if (j > 0
- && dragon[POS(i, j-1)].origin == POS(m, n))
+ if (ON_BOARD(pos-1) && dragon[pos-1].origin == dr)
return 1;
- if (j < board_size - 1
- && dragon[POS(i, j+1)].origin == POS(m, n))
+ if (ON_BOARD(pos+1) && dragon[pos+1].origin == dr)
return 1;
return 0;
@@ -125,24 +119,25 @@
* DEAD or CRITICAL.
*/
static void
-analyze_semeai(int ai, int aj, int bi, int bj)
+analyze_semeai(int aa, int bb)
{
/* We start liberty counts at 1 since we will be subtracting
* the number of worms. */
int mylibs = 1, yourlibs = 1, commonlibs = 0;
- int yourlibi = -1, yourlibj = -1;
- int commonlibi = -1, commonlibj = -1;
- int color = BOARD(ai, aj);
+ int yourlib = NO_MOVE;
+ int commonlib = NO_MOVE;
+ int color = board[aa];
int i, j;
+ int ii;
int m, n;
int my_status = UNKNOWN;
int your_status = UNKNOWN;
int di, dj;
+ int dd;
int margin_of_safety = 0;
int owl_code_sufficient = 0;
- DEBUG(DEBUG_SEMEAI, "semeai_analyzer: %m (me) vs %m (them)\n",
- ai, aj, bi, bj);
+ DEBUG(DEBUG_SEMEAI, "semeai_analyzer: %1m (me) vs %1m (them)\n", aa, bb);
/* If both dragons are owl-critical, or my dragon is owl-critical
* and your dragon is owl-dead, and the attack point for my dragon
@@ -152,31 +147,34 @@
* Correction: We can't add an owl defense move reason here because
* this would be a defense of an opponent dragon.
*/
- if (dragon[POS(ai, aj)].owl_status == CRITICAL
- && (dragon[POS(bi, bj)].owl_status == CRITICAL
- || dragon[POS(bi, bj)].owl_status == DEAD)) {
- if (dragon[POS(bi, bj)].owl_defense_point == dragon[POS(ai,
aj)].owl_attack_point)
+ if (dragon[aa].owl_status == CRITICAL
+ && (dragon[bb].owl_status == CRITICAL
+ || dragon[bb].owl_status == DEAD)) {
+ if (dragon[bb].owl_defense_point == dragon[aa].owl_attack_point)
return;
- if (dragon[POS(ai, aj)].owl_attack_point != NO_MOVE
- && owl_does_defend(I(dragon[POS(ai, aj)].owl_attack_point),
- J(dragon[POS(ai, aj)].owl_attack_point), bi, bj)) {
+ if (dragon[aa].owl_attack_point != NO_MOVE
+ && owl_does_defend(I(dragon[aa].owl_attack_point),
+ J(dragon[aa].owl_attack_point), I(bb), J(bb))) {
#if 0
- add_owl_defense_move(dragon[POS(ai, aj)].owl_attacki,
- dragon[POS(ai, aj)].owl_attackj,
- bi, bj);
- DEBUG(DEBUG_SEMEAI, "added owl defense of %m at %m\n",
- bi, bj, dragon[POS(ai, aj)].owl_defendi, dragon[POS(ai,
aj)].owl_defendj);
+ add_owl_defense_move(dragon[aa].owl_attacki,
+ dragon[aa].owl_attackj,
+ I(bb), J(bb));
+ DEBUG(DEBUG_SEMEAI, "added owl defense of %1m at %1m\n",
+ bb, dragon[aa].owl_defense_point);
#endif
- if (dragon[POS(bi, bj)].owl_status == DEAD) {
+ if (dragon[bb].owl_status == DEAD) {
for (m = 0; m < board_size; m++)
- for (n = 0; n < board_size; n++)
- if (BOARD(m, n) == BOARD(bi, bj) && same_dragon(POS(m, n), POS(bi,
bj))) {
- dragon[POS(m, n)].owl_status = CRITICAL;
- dragon[POS(m, n)].matcher_status = CRITICAL;
+ for (n = 0; n < board_size; n++) {
+ ii = POS(m, n);
+
+ if (board[ii] == board[bb] && same_dragon(ii, bb)) {
+ dragon[ii].owl_status = CRITICAL;
+ dragon[ii].matcher_status = CRITICAL;
}
+ }
DEBUG(DEBUG_SEMEAI,
- "changed owl_status and matcher_status of %m to CRITICAL\n",
- bi, bj);
+ "changed owl_status and matcher_status of %1m to CRITICAL\n",
+ bb);
}
owl_code_sufficient = 1;
}
@@ -186,17 +184,16 @@
* dragon owl_does_attack your dragon, add another owl attack move
* reason.
*/
- if ((dragon[POS(ai, aj)].owl_status == CRITICAL)
- && (dragon[POS(bi, bj)].owl_status == CRITICAL)) {
- if (dragon[POS(bi, bj)].owl_attack_point == dragon[POS(ai,
aj)].owl_defense_point)
+ if ((dragon[aa].owl_status == CRITICAL)
+ && (dragon[bb].owl_status == CRITICAL)) {
+ if (dragon[bb].owl_attack_point == dragon[aa].owl_defense_point)
return;
- if (dragon[POS(ai, aj)].owl_defense_point != NO_MOVE
- && owl_does_attack(I(dragon[POS(ai, aj)].owl_defense_point),
- J(dragon[POS(ai, aj)].owl_defense_point), bi, bj)) {
- add_owl_attack_move(dragon[POS(ai, aj)].owl_defense_point,
- POS(bi, bj));
- DEBUG(DEBUG_SEMEAI, "added owl attack of %m at %1m\n",
- bi, bj, dragon[POS(ai, aj)].owl_defense_point);
+ if (dragon[aa].owl_defense_point != NO_MOVE
+ && owl_does_attack(I(dragon[aa].owl_defense_point),
+ J(dragon[aa].owl_defense_point), I(bb), J(bb))) {
+ add_owl_attack_move(dragon[aa].owl_defense_point, bb);
+ DEBUG(DEBUG_SEMEAI, "added owl attack of %1m at %1m\n",
+ bb, dragon[aa].owl_defense_point);
owl_code_sufficient = 1;
}
}
@@ -206,28 +203,32 @@
* owl_does_defend my dragon, add another owl defense move reason
* and possibly change the owl status of my dragon to critical.
*/
- if ((dragon[POS(ai, aj)].owl_status == CRITICAL
- || dragon[POS(ai, aj)].owl_status == DEAD)
- && dragon[POS(bi, bj)].owl_status == CRITICAL) {
- if (dragon[POS(bi, bj)].owl_attack_point == dragon[POS(ai,
aj)].owl_defense_point)
+ if ((dragon[aa].owl_status == CRITICAL
+ || dragon[aa].owl_status == DEAD)
+ && dragon[bb].owl_status == CRITICAL) {
+ if (dragon[bb].owl_attack_point == dragon[aa].owl_defense_point)
return;
- if (dragon[POS(bi, bj)].owl_attack_point != NO_MOVE
- && owl_does_defend(I(dragon[POS(bi, bj)].owl_attack_point),
- J(dragon[POS(bi, bj)].owl_attack_point), ai, aj)) {
- add_owl_defense_move(dragon[POS(bi, bj)].owl_attack_point,
- POS(ai, aj));
- DEBUG(DEBUG_SEMEAI, "added owl defense of %m at %1m\n",
- ai, aj, dragon[POS(bi, bj)].owl_attack_point);
- if (dragon[POS(ai, aj)].owl_status == DEAD) {
+
+ if (dragon[bb].owl_attack_point != NO_MOVE
+ && owl_does_defend(I(dragon[bb].owl_attack_point),
+ J(dragon[bb].owl_attack_point), I(aa), J(aa)))
+ {
+ add_owl_defense_move(dragon[bb].owl_attack_point, aa);
+ DEBUG(DEBUG_SEMEAI, "added owl defense of %1m at %1m\n",
+ aa, dragon[bb].owl_attack_point);
+ if (dragon[aa].owl_status == DEAD) {
for (m = 0; m < board_size; m++)
- for (n = 0; n < board_size; n++)
- if (BOARD(m, n) == BOARD(ai, aj) && same_dragon(POS(m, n), POS(ai,
aj))) {
- dragon[POS(m, n)].owl_status = CRITICAL;
- dragon[POS(m, n)].matcher_status = CRITICAL;
+ for (n = 0; n < board_size; n++) {
+ ii = POS(m, n);
+
+ if (board[ii] == board[aa] && same_dragon(ii, aa)) {
+ dragon[ii].owl_status = CRITICAL;
+ dragon[ii].matcher_status = CRITICAL;
}
+ }
DEBUG(DEBUG_SEMEAI,
- "changed owl_status and matcher_status of %m to CRITICAL\n",
- ai, aj);
+ "changed owl_status and matcher_status of %1m to CRITICAL\n",
+ aa);
}
owl_code_sufficient = 1;
}
@@ -240,19 +241,21 @@
* Correction: We can't add an owl attack move reason here because
* this would be an attack on our own dragon.
*/
- if ((dragon[POS(ai, aj)].owl_status == CRITICAL)
- && (dragon[POS(bi, bj)].owl_status == CRITICAL)) {
- if (dragon[POS(bi, bj)].owl_defense_point == dragon[POS(ai,
aj)].owl_attack_point)
+ if ((dragon[aa].owl_status == CRITICAL)
+ && (dragon[bb].owl_status == CRITICAL))
+ {
+ if (dragon[bb].owl_defense_point == dragon[aa].owl_attack_point)
return;
- if (dragon[POS(bi, bj)].owl_defense_point != NO_MOVE
- && owl_does_attack(I(dragon[POS(bi, bj)].owl_defense_point),
- J(dragon[POS(bi, bj)].owl_defense_point), ai, aj)) {
+
+ if (dragon[bb].owl_defense_point != NO_MOVE
+ && owl_does_attack(I(dragon[bb].owl_defense_point),
+ J(dragon[bb].owl_defense_point), I(aa), J(aa))) {
#if 0
- add_owl_attack_move(dragon[POS(bi, bj)].owl_defendi,
- dragon[POS(bi, bj)].owl_defendj,
- ai, aj);
- DEBUG(DEBUG_SEMEAI, "added owl attack of %m at %m\n",
- ai, aj, dragon[POS(bi, bj)].owl_attacki, dragon[POS(bi,
bj)].owl_attackj);
+ add_owl_attack_move(dragon[bb].owl_defendi,
+ dragon[bb].owl_defendj,
+ I(aa), J(aa));
+ DEBUG(DEBUG_SEMEAI, "added owl attack of %1m at %1m\n",
+ aa, dragon[bb].owl_attack_point);
#endif
owl_code_sufficient = 1;
}
@@ -264,7 +267,7 @@
return;
}
-
+/*qwe*/
/* The semeai module is prone to errors since semeai cannot
* really be handled by static analysis. It is really only needed
* when the dragons have many liberties since tight situations
@@ -275,22 +278,25 @@
*/
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
- if (worm[POS(m, n)].origin == POS(m, n)
- && worm[POS(m, n)].attack_codes[0] == WIN)
- if (dragon[POS(m, n)].origin == POS(ai, aj)
- || dragon[POS(m, n)].origin == POS(bi, bj)) {
+ int ii = POS(m, n);
+
+ if (worm[ii].origin == ii
+ && worm[ii].attack_codes[0] == WIN)
+ if (dragon[ii].origin == aa
+ || dragon[ii].origin == bb) {
int adj;
int adjs[MAXCHAIN];
int r;
- adj = chainlinks(POS(m, n), adjs);
+ adj = chainlinks(ii, adjs);
for (r = 0; r < adj; r++) {
- int ci = I(adjs[r]);
- int cj = J(adjs[r]);
- if (dragon[POS(ci, cj)].origin == POS(ai, aj)
- || dragon[POS(ci, cj)].origin == POS(bi, bj))
- if (owl_substantial(m, n)) {
- DEBUG(DEBUG_SEMEAI, "...tactical situation detected,
exiting\n");
+ int cc = adjs[r];
+
+ if (dragon[cc].origin == aa
+ || dragon[cc].origin == bb)
+ if (owl_substantial(I(ii), J(ii))) {
+ DEBUG(DEBUG_SEMEAI,
+ "...tactical situation detected, exiting\n");
return;
}
}
@@ -300,9 +306,12 @@
/* Mark the dragons as involved in semeai */
for (i = 0; i < board_size; i++)
- for (j = 0; j < board_size; j++)
- if (same_dragon(POS(i, j), POS(ai, aj)) || same_dragon(POS(i, j),
POS(bi, bj)))
- DRAGON2(POS(i, j)).semeai = 1;
+ for (j = 0; j < board_size; j++) {
+ int ii = POS(i, j);
+
+ if (same_dragon(ii, aa) || same_dragon(ii, bb))
+ DRAGON2(ii).semeai = 1;
+ }
/* First we try to determine the number of liberties of each
* dragon, and the number of common liberties. We subtract
@@ -314,43 +323,43 @@
*/
for (i = 0; i < board_size; i++)
for (j = 0; j < board_size; j++) {
- if (BOARD(i, j)
- && worm[POS(i, j)].origin == POS(i, j)) {
- if (same_dragon(POS(i, j), POS(ai, aj)))
+ ii = POS(i, j);
+
+ if (board[ii]
+ && worm[ii].origin == ii) {
+ if (same_dragon(ii, aa))
mylibs--;
- if (same_dragon(POS(i, j), POS(bi, bj)))
+ if (same_dragon(ii, bb))
yourlibs--;
}
- else if (BOARD(i, j) == EMPTY) {
- if (liberty_of_dragon(i, j, bi, bj)) {
+ else if (board[ii] == EMPTY) {
+ if (liberty_of_dragon(ii, bb)) {
yourlibs ++;
- if (liberty_of_dragon(i, j, ai, aj)) {
+ if (liberty_of_dragon(ii, aa)) {
commonlibs++;
mylibs++;
- commonlibi = i;
- commonlibj = j;
- }
- else {
- yourlibi = i;
- yourlibj = j;
+ commonlib = ii;
}
+ else
+ yourlib = ii;
}
- else if (liberty_of_dragon(i, j, ai, aj))
+ else if (liberty_of_dragon(ii, aa))
mylibs++;
}
}
+
/* We add 1 to the
* number of liberties of an owl critical dragon if the point
* of attack is not a liberty of the dragon, since a move
* may have to be invested in attacking it.
*/
- if (dragon[POS(ai, aj)].owl_status == CRITICAL
- && !liberty_of_string(dragon[POS(ai, aj)].owl_attack_point, POS(ai, aj)))
+ if (dragon[aa].owl_status == CRITICAL
+ && !liberty_of_string(dragon[aa].owl_attack_point, aa))
mylibs++;
- if (dragon[POS(bi, bj)].owl_status == CRITICAL
- && !liberty_of_string(dragon[POS(bi, bj)].owl_attack_point, POS(bi, bj)))
+ if (dragon[bb].owl_status == CRITICAL
+ && !liberty_of_string(dragon[bb].owl_attack_point, bb))
yourlibs++;
/* Now we compute the statuses which result from a
@@ -389,7 +398,7 @@
* (5) If C>0 and M<C+Y, Y<C+M, then the situation is seki.
* (6) If C>0 and Y=C+M, then you can kill, I can make seki. CRITICAL.
*
- * If I have an eye and you dont:
+ * If I have an eye and you don't:
*
* In this case, M > 0. This situation (me ari me nashi) can
* never be seki. The common liberties must be filled by you,
@@ -407,8 +416,8 @@
* (2) If Y+C=M whoever moves first wins. CRITICAL.
* (3) If Y+C<M I win. */
- if (DRAGON2(POS(ai, aj)).genus == 0
- && DRAGON2(POS(bi, bj)).genus == 0) {
+ if (DRAGON2(aa).genus == 0
+ && DRAGON2(bb).genus == 0) {
if (commonlibs == 0) {
if (mylibs > yourlibs) {
my_status = ALIVE;
@@ -467,8 +476,8 @@
margin_of_safety = yourlibs - mylibs - commonlibs;
}
}
- if (DRAGON2(POS(ai, aj)).genus > 0
- && DRAGON2(POS(bi, bj)).genus > 0) {
+ if (DRAGON2(aa).genus > 0
+ && DRAGON2(bb).genus > 0) {
if (mylibs > yourlibs + commonlibs) {
my_status = ALIVE;
your_status = DEAD;
@@ -506,8 +515,8 @@
margin_of_safety = 0;
}
}
- if (DRAGON2(POS(ai, aj)).genus > 0
- && DRAGON2(POS(bi, bj)).genus == 0) {
+ if (DRAGON2(aa).genus > 0
+ && DRAGON2(bb).genus == 0) {
if (mylibs > commonlibs + yourlibs) {
my_status = ALIVE;
your_status = DEAD;
@@ -523,8 +532,8 @@
margin_of_safety = mylibs + commonlibs - yourlibs;
}
}
- if (DRAGON2(POS(ai, aj)).genus == 0
- && DRAGON2(POS(bi, bj)).genus > 0) {
+ if (DRAGON2(aa).genus == 0
+ && DRAGON2(bb).genus > 0) {
if (yourlibs + commonlibs > mylibs) {
my_status = DEAD;
your_status = ALIVE;
@@ -553,65 +562,82 @@
* want to take it. So the matcher status is not changed.
*/
- if (dragon[POS(ai, aj)].owl_status != CRITICAL) {
+ if (dragon[aa].owl_status != CRITICAL) {
if (my_status == ALIVE) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to ALIVE.\n", ai, aj);
- DRAGON2(POS(ai, aj)).safety = ALIVE_IN_SEKI;
+ "Changing matcher_status of %1m to ALIVE.\n", aa);
+ DRAGON2(aa).safety = ALIVE_IN_SEKI;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(ai, aj), POS(di, dj))) {
- dragon[POS(di, dj)].matcher_status = ALIVE;
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+
+ if (same_dragon(aa, dd)) {
+ dragon[dd].matcher_status = ALIVE;
}
+ }
}
else if (my_status == CRITICAL) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to CRITICAL.\n", ai, aj);
- DRAGON2(POS(ai, aj)).safety = CRITICAL;
+ "Changing matcher_status of %1m to CRITICAL.\n", aa);
+ DRAGON2(aa).safety = CRITICAL;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(ai, aj), POS(di, dj)))
- dragon[POS(di, dj)].matcher_status = CRITICAL;
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+
+ if (same_dragon(aa, dd))
+ dragon[dd].matcher_status = CRITICAL;
+ }
}
else if (my_status == DEAD) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to DEAD.\n", ai, aj);
- DRAGON2(POS(ai, aj)).safety = DEAD;
+ "Changing matcher_status of %1m to DEAD.\n", aa);
+ DRAGON2(aa).safety = DEAD;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(ai, aj), POS(di, dj)))
- dragon[POS(di, dj)].matcher_status = DEAD;
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+
+ if (same_dragon(aa, dd))
+ dragon[dd].matcher_status = DEAD;
+ }
}
}
if (your_status == ALIVE) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to ALIVE.\n", bi, bj);
- DRAGON2(POS(bi, bj)).safety = ALIVE_IN_SEKI;
+ "Changing matcher_status of %1m to ALIVE.\n", bb);
+ DRAGON2(bb).safety = ALIVE_IN_SEKI;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(bi, bj), POS(di, dj)))
- dragon[POS(di, dj)].matcher_status = ALIVE;
- }
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+ if (same_dragon(bb, dd))
+ dragon[dd].matcher_status = ALIVE;
+ }
+ }
else if (your_status == CRITICAL) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to CRITICAL.\n", bi, bj);
- DRAGON2(POS(bi, bj)).safety = CRITICAL;
+ "Changing matcher_status of %1m to CRITICAL.\n", bb);
+ DRAGON2(bb).safety = CRITICAL;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(bi, bj), POS(di, dj))) {
- dragon[POS(di, dj)].matcher_status = CRITICAL;
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+
+ if (same_dragon(bb, dd)) {
+ dragon[dd].matcher_status = CRITICAL;
}
+ }
}
else if (your_status == DEAD) {
DEBUG(DEBUG_SEMEAI,
- "Changing matcher_status of %m to DEAD.\n", bi, bj);
- DRAGON2(POS(bi, bj)).safety = DEAD;
+ "Changing matcher_status of %1m to DEAD.\n", bb);
+ DRAGON2(bb).safety = DEAD;
for (di = 0; di < board_size; di++)
- for (dj = 0; dj < board_size; dj++)
- if (same_dragon(POS(bi, bj), POS(di, dj)))
- dragon[POS(di, dj)].matcher_status = DEAD;
+ for (dj = 0; dj < board_size; dj++) {
+ dd = POS(di, dj);
+
+ if (same_dragon(bb, dd))
+ dragon[dd].matcher_status = DEAD;
+ }
}
/* Find the recommended semeai moves. In order of priority,
@@ -624,47 +650,41 @@
if ((my_status == CRITICAL) || (your_status == CRITICAL)) {
int found_one = 0;
- if (dragon[POS(ai, aj)].owl_status == CRITICAL
- && dragon[POS(ai, aj)].owl_defense_point != NO_MOVE)
- add_appropriate_semeai_moves(I(dragon[POS(ai, aj)].owl_defense_point),
- J(dragon[POS(ai, aj)].owl_defense_point),
- ai, aj, bi, bj, my_status, your_status,
- margin_of_safety);
- else if (dragon[POS(bi, bj)].owl_status == CRITICAL
- && dragon[POS(bi, bj)].owl_attack_point != NO_MOVE)
- add_appropriate_semeai_moves(I(dragon[POS(bi, bj)].owl_attack_point),
- J(dragon[POS(bi, bj)].owl_attack_point),
- ai, aj, bi, bj, my_status, your_status,
- margin_of_safety);
+ if (dragon[aa].owl_status == CRITICAL
+ && dragon[aa].owl_defense_point != NO_MOVE)
+ add_appropriate_semeai_moves(dragon[aa].owl_defense_point, aa, bb,
+ my_status, your_status, margin_of_safety);
+ else if (dragon[bb].owl_status == CRITICAL
+ && dragon[bb].owl_attack_point != NO_MOVE)
+ add_appropriate_semeai_moves(dragon[bb].owl_attack_point, aa, bb,
+ my_status, your_status, margin_of_safety);
else if (commonlibs > 1) {
- if (DRAGON2(POS(ai, aj)).heyes > 0)
- add_appropriate_semeai_moves(I(DRAGON2(POS(ai, aj)).heye),
- J(DRAGON2(POS(ai, aj)).heye),
- ai, aj, bi, bj, my_status, your_status,
- margin_of_safety);
- if (DRAGON2(POS(bi, bj)).heyes > 0)
- add_appropriate_semeai_moves(I(DRAGON2(POS(bi, bj)).heye),
- J(DRAGON2(POS(bi, bj)).heye),
- ai, aj, bi, bj, my_status, your_status,
- margin_of_safety);
+ if (DRAGON2(aa).heyes > 0)
+ add_appropriate_semeai_moves(DRAGON2(aa).heye, aa, bb,
+ my_status, your_status, margin_of_safety);
+ if (DRAGON2(bb).heyes > 0)
+ add_appropriate_semeai_moves(DRAGON2(bb).heye, aa, bb,
+ my_status, your_status, margin_of_safety);
}
else {
for (i = 0; i < board_size-1; i++)
- for (j = 0; j < board_size-1; j++)
- if (liberty_of_dragon(i, j, bi, bj)
- && !liberty_of_dragon(i, j, ai, aj)
- && safe_move2(i, j, color)) {
+ for (j = 0; j < board_size-1; j++) {
+ ii = POS(i, j);
+
+ if (liberty_of_dragon(ii, bb)
+ && !liberty_of_dragon(ii, aa)
+ && safe_move(ii, color)) {
/* add move reasons for EVERY outside liberty where we can
* play safely. A move to win a semeai might not be a
* safe move if it is inside the opponent's eyespace.
* However we hope that the reading code can analyze the
* semeai in cases where every safe liberty has been filled.
*/
- add_appropriate_semeai_moves(i, j, ai, aj, bi, bj,
- my_status, your_status,
+ add_appropriate_semeai_moves(ii, aa, bb, my_status, your_status,
margin_of_safety);
found_one = 1;
}
+ }
if (!found_one) {
/* No outside liberties --- look for common liberties.
* Filling a common liberty is usually bad but if our
@@ -674,12 +694,14 @@
* be a safe move.
*/
for (i = 0; i < board_size-1; i++)
- for (j = 0; j < board_size-1; j++)
- if (liberty_of_dragon(i, j, bi, bj)
- && safe_move2(i, j, color))
- add_appropriate_semeai_moves(i, j, ai, aj, bi, bj,
- my_status, your_status,
+ for (j = 0; j < board_size-1; j++) {
+ ii = POS(i, j);
+
+ if (liberty_of_dragon(ii, bb)
+ && safe_move(ii, color))
+ add_appropriate_semeai_moves(ii, aa, bb, my_status, your_status,
margin_of_safety);
+ }
}
}
}
@@ -688,18 +710,18 @@
/* Add those move reasons which are appropriate. */
static void
-add_appropriate_semeai_moves(int ti, int tj, int ai, int aj, int bi, int bj,
+add_appropriate_semeai_moves(int pos, int aa, int bb,
int my_status, int your_status,
int margin_of_safety)
{
if (my_status == CRITICAL)
- add_semeai_move(POS(ti, tj), POS(ai, aj));
+ add_semeai_move(pos, aa);
else if (margin_of_safety==1)
- add_semeai_threat(POS(ti, tj), POS(ai, aj));
+ add_semeai_threat(pos, aa);
if (your_status == CRITICAL)
- add_semeai_move(POS(ti, tj), POS(bi, bj));
+ add_semeai_move(pos, bb);
else if (margin_of_safety==1)
- add_semeai_threat(POS(ti, tj), POS(bi, bj));
+ add_semeai_threat(pos, bb);
}
@@ -712,6 +734,7 @@
revise_semeai(int color)
{
int m, n;
+ int ii;
int found_one = 0;
int other = OTHER_COLOR(color);
@@ -719,15 +742,17 @@
for (m = 0; m < board_size; m++)
for (n = 0; n < board_size; n++) {
- if (DRAGON2(POS(m, n)).semeai
- && dragon[POS(m, n)].matcher_status == DEAD
- && dragon[POS(m, n)].color == other)
+ ii = POS(m, n);
+
+ if (DRAGON2(ii).semeai
+ && dragon[ii].matcher_status == DEAD
+ && dragon[ii].color == other)
{
found_one = 1;
- dragon[POS(m, n)].matcher_status = UNKNOWN;
- if (dragon[POS(m, n)].origin == POS(m, n))
- TRACE("revise_semeai: changed status of dragon %m from DEAD to
UNKNOWN\n",
- m, n);
+ dragon[ii].matcher_status = UNKNOWN;
+ if (dragon[ii].origin == ii)
+ TRACE("revise_semeai: changed status of dragon %1m from DEAD to
UNKNOWN\n",
+ ii);
}
}
@@ -735,6 +760,12 @@
}
+/* ---------------------------------------------------------------- */
+
+
+static void small_semeai_analyzer(int aa, int bb);
+
+
/* small_semeai() addresses a deficiency in the reading code:
* for reasons of speed, savestone3 and savestone4 do not
* sufficiently check whether there may be an adjoining string
@@ -755,55 +786,60 @@
small_semeai()
{
int i, j;
+ int ii;
+
for (i = 0; i < board_size; i++)
- for (j = 0; j < board_size; j++)
- if (BOARD(i, j)
- && (worm[POS(i, j)].liberties == 3 || worm[POS(i, j)].liberties == 4)
- && worm[POS(i, j)].attack_codes[0] != 0) {
- int other = OTHER_COLOR(BOARD(i, j));
- if (i > 0 && BOARD(i-1, j) == other)
- small_semeai_analyzer(i, j, i-1, j);
- if (i < board_size-1 && BOARD(i+1, j) == other)
- small_semeai_analyzer(i, j, i+1, j);
- if (j > 0 && BOARD(i, j-1) == other)
- small_semeai_analyzer(i, j, i, j-1);
- if (j < board_size-1 && BOARD(i, j+1) == other)
- small_semeai_analyzer(i, j, i, j+1);
+ for (j = 0; j < board_size; j++) {
+ ii = POS(i, j);
+
+ if (board[ii]
+ && (worm[ii].liberties == 3 || worm[ii].liberties == 4)
+ && worm[ii].attack_codes[0] != 0) {
+ int other = OTHER_COLOR(board[ii]);
+ if (I(ii) > 0 && board[ii-NS] == other)
+ small_semeai_analyzer(ii, ii-NS);
+ if (I(ii) < board_size-1 && board[ii+NS] == other)
+ small_semeai_analyzer(ii, ii+NS);
+ if (J(ii) > 0 && board[ii-1] == other)
+ small_semeai_analyzer(ii, ii-1);
+ if (J(ii) < board_size-1 && board[ii+1] == other)
+ small_semeai_analyzer(ii, ii+1);
}
+ }
}
/* Helper function for small_semeai. Tries to resolve the
- * semeai between (i,j) and (m,n), possibly revising points
+ * semeai between (aa) and (bb), possibly revising points
* of attack and defense.
*/
-void
-small_semeai_analyzer(int i, int j, int m, int n)
+static void
+small_semeai_analyzer(int aa, int bb)
{
- int apos;
- int color = BOARD(i, j);
- int other = BOARD(m, n);
+ int attack_point;
+ int color = board[aa]; /* i, j*/
+ int other = board[bb]; /* m, n*/
- if (worm[POS(m, n)].attack_codes[0] == 0 || worm[POS(m, n)].liberties < 3)
+ if (worm[bb].attack_codes[0] == 0 || worm[bb].liberties < 3)
return;
- if (worm[POS(i, j)].attack_codes[0] == 0 || worm[POS(i, j)].liberties < 3)
+ if (worm[aa].attack_codes[0] == 0 || worm[aa].liberties < 3)
return;
/* FIXME: There are many more possibilities to consider */
- if (trymove(worm[POS(i, j)].attack_points[0], other,
- "small_semeai_analyzer", POS(i, j), EMPTY, 0)) {
- int acode = attack(POS(m, n), &apos);
+ if (trymove(worm[aa].attack_points[0], other,
+ "small_semeai_analyzer", aa, EMPTY, NO_MOVE)) {
+ int acode = attack(bb, &attack_point);
if (acode == 0) {
popgo();
- change_defense(POS(m, n), worm[POS(i, j)].attack_points[0], 1);
+ change_defense(bb, worm[aa].attack_points[0], 1);
}
- else if (trymove(apos, color, "small_semeai_analyzer", POS(i, j),
+ else if (trymove(attack_point, color, "small_semeai_analyzer", aa,
EMPTY, NO_MOVE)) {
- if (attack(POS(i, j), NULL) == 0) {
+ if (attack(aa, NULL) == 0) {
popgo();
popgo();
- change_attack(POS(i, j), 0, 0);
+ change_attack(aa, 0, 0);
}
else {
popgo();
@@ -815,19 +851,19 @@
}
gg_assert(stackp == 0);
- if (trymove(worm[POS(m, n)].attack_points[0], color,
- "small_semeai_analyzer", POS(m, n), EMPTY, 0)) {
- int acode = attack(POS(i, j), &apos);
+ if (trymove(worm[bb].attack_points[0], color,
+ "small_semeai_analyzer", bb, EMPTY, NO_MOVE)) {
+ int acode = attack(aa, &attack_point);
if (acode == 0) {
popgo();
- change_defense(POS(i, j), worm[POS(m, n)].attack_points[0], 1);
+ change_defense(aa, worm[bb].attack_points[0], 1);
}
- else if (trymove(apos, other, "small_semeai_analyzer", POS(m, n),
+ else if (trymove(attack_point, other, "small_semeai_analyzer", bb,
EMPTY, NO_MOVE)) {
- if (attack(POS(m, n), NULL) == 0) {
+ if (attack(bb, NULL) == 0) {
popgo();
popgo();
- change_attack(POS(m, n), 0, 0);
+ change_attack(bb, 0, 0);
}
else {
popgo();
Only in gnugo-3.1.10p1iw1/engine: semeai.c.save
Only in gnugo-3.1.10p1iw1/engine: semeai.c~
Binary files gnugo-3.1.10p1/engine/semeai.o and
gnugo-3.1.10p1iw1/engine/semeai.o differ
Binary files gnugo-3.1.10p1/engine/sgfdecide.o and
gnugo-3.1.10p1iw1/engine/sgfdecide.o differ
Binary files gnugo-3.1.10p1/engine/sgffile.o and
gnugo-3.1.10p1iw1/engine/sgffile.o differ
Binary files gnugo-3.1.10p1/engine/shapes.o and
gnugo-3.1.10p1iw1/engine/shapes.o differ
Binary files gnugo-3.1.10p1/engine/showbord.o and
gnugo-3.1.10p1iw1/engine/showbord.o differ
Binary files gnugo-3.1.10p1/engine/utils.o and gnugo-3.1.10p1iw1/engine/utils.o
differ
Binary files gnugo-3.1.10p1/engine/worm.o and gnugo-3.1.10p1iw1/engine/worm.o
differ
Only in gnugo-3.1.10p1iw1/interface/debugboard: Makefile
Only in gnugo-3.1.10p1iw1/interface/debugboard: debugboard
Only in gnugo-3.1.10p1iw1/interface/debugboard: display.o
Only in gnugo-3.1.10p1iw1/interface/debugboard: gui.o
Only in gnugo-3.1.10p1iw1/interface/debugboard: main.o
Binary files gnugo-3.1.10p1/interface/gnugo and
gnugo-3.1.10p1iw1/interface/gnugo differ
Binary files gnugo-3.1.10p1/interface/main.o and
gnugo-3.1.10p1iw1/interface/main.o differ
Binary files gnugo-3.1.10p1/interface/play_ascii.o and
gnugo-3.1.10p1iw1/interface/play_ascii.o differ
Binary files gnugo-3.1.10p1/interface/play_gtp.o and
gnugo-3.1.10p1iw1/interface/play_gtp.o differ
Binary files gnugo-3.1.10p1/interface/play_solo.o and
gnugo-3.1.10p1iw1/interface/play_solo.o differ
Binary files gnugo-3.1.10p1/patterns/apatterns.o and
gnugo-3.1.10p1iw1/patterns/apatterns.o differ
Binary files gnugo-3.1.10p1/patterns/barriers.o and
gnugo-3.1.10p1iw1/patterns/barriers.o differ
Binary files gnugo-3.1.10p1/patterns/conn.o and
gnugo-3.1.10p1iw1/patterns/conn.o differ
Binary files gnugo-3.1.10p1/patterns/connections.o and
gnugo-3.1.10p1iw1/patterns/connections.o differ
Binary files gnugo-3.1.10p1/patterns/dpatterns.o and
gnugo-3.1.10p1iw1/patterns/dpatterns.o differ
Binary files gnugo-3.1.10p1/patterns/endgame.o and
gnugo-3.1.10p1iw1/patterns/endgame.o differ
Binary files gnugo-3.1.10p1/patterns/extract_fuseki and
gnugo-3.1.10p1iw1/patterns/extract_fuseki differ
Binary files gnugo-3.1.10p1/patterns/extract_fuseki.o and
gnugo-3.1.10p1iw1/patterns/extract_fuseki.o differ
Binary files gnugo-3.1.10p1/patterns/fuseki13.o and
gnugo-3.1.10p1iw1/patterns/fuseki13.o differ
Binary files gnugo-3.1.10p1/patterns/fuseki19.o and
gnugo-3.1.10p1iw1/patterns/fuseki19.o differ
Binary files gnugo-3.1.10p1/patterns/fuseki9.o and
gnugo-3.1.10p1iw1/patterns/fuseki9.o differ
Binary files gnugo-3.1.10p1/patterns/fusekipat.o and
gnugo-3.1.10p1iw1/patterns/fusekipat.o differ
Binary files gnugo-3.1.10p1/patterns/helpers.o and
gnugo-3.1.10p1iw1/patterns/helpers.o differ
Binary files gnugo-3.1.10p1/patterns/influence.o and
gnugo-3.1.10p1iw1/patterns/influence.o differ
Binary files gnugo-3.1.10p1/patterns/joseki and
gnugo-3.1.10p1iw1/patterns/joseki differ
Binary files gnugo-3.1.10p1/patterns/joseki.o and
gnugo-3.1.10p1iw1/patterns/joseki.o differ
Binary files gnugo-3.1.10p1/patterns/josekidb.o and
gnugo-3.1.10p1iw1/patterns/josekidb.o differ
Binary files gnugo-3.1.10p1/patterns/libdfa.a and
gnugo-3.1.10p1iw1/patterns/libdfa.a differ
Binary files gnugo-3.1.10p1/patterns/libpatterns.a and
gnugo-3.1.10p1iw1/patterns/libpatterns.a differ
Binary files gnugo-3.1.10p1/patterns/owl_attackpat.o and
gnugo-3.1.10p1iw1/patterns/owl_attackpat.o differ
Binary files gnugo-3.1.10p1/patterns/owl_defendpat.o and
gnugo-3.1.10p1iw1/patterns/owl_defendpat.o differ
Binary files gnugo-3.1.10p1/patterns/owl_vital_apat.o and
gnugo-3.1.10p1iw1/patterns/owl_vital_apat.o differ
Binary files gnugo-3.1.10p1/patterns/patterns.o and
gnugo-3.1.10p1iw1/patterns/patterns.o differ
Only in gnugo-3.1.10p1iw1/regression: Makefile
Binary files gnugo-3.1.10p1/sgf/libsgf.a and gnugo-3.1.10p1iw1/sgf/libsgf.a
differ
Binary files gnugo-3.1.10p1/sgf/sgfnode.o and gnugo-3.1.10p1iw1/sgf/sgfnode.o
differ
Binary files gnugo-3.1.10p1/sgf/sgftree.o and gnugo-3.1.10p1iw1/sgf/sgftree.o
differ
Only in gnugo-3.1.10p1iw1: stamp-h
Binary files gnugo-3.1.10p1/utils/gg_utils.o and
gnugo-3.1.10p1iw1/utils/gg_utils.o differ
Binary files gnugo-3.1.10p1/utils/libutils.a and
gnugo-3.1.10p1iw1/utils/libutils.a differ
- [gnugo-devel] Patch: semeai.c and filllib.c now 1-dimensional,
Inge Wallin <=