405 lines
11 KiB
C
405 lines
11 KiB
C
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||
|
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
|
||
|
* http://www.gnu.org/software/gnugo/ for more information. *
|
||
|
* *
|
||
|
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
|
||
|
* 2008 and 2009 by the Free Software Foundation. *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or *
|
||
|
* modify it under the terms of the GNU General Public License as *
|
||
|
* published by the Free Software Foundation - version 3 or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
* This program is distributed in the hope that it will be useful, *
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||
|
* GNU General Public License in file COPYING for more details. *
|
||
|
* *
|
||
|
* You should have received a copy of the GNU General Public *
|
||
|
* License along with this program; if not, write to the Free *
|
||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||
|
* Boston, MA 02111, USA. *
|
||
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
|
||
|
/* Compile the eye database. This produces eyes.c. */
|
||
|
|
||
|
/* see also eyes.db, eyes.h and engine/optics.c */
|
||
|
|
||
|
|
||
|
#define MAXLINE 80
|
||
|
#define MAXDIMEN 20
|
||
|
#define MAXSIZE 20
|
||
|
#define MAXPATNO 800
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
#include "eyes.h"
|
||
|
|
||
|
|
||
|
int
|
||
|
main(void)
|
||
|
{
|
||
|
char line[MAXLINE];
|
||
|
int patno = 0;
|
||
|
int p;
|
||
|
char vertex[MAXDIMEN][MAXDIMEN];
|
||
|
signed char marginal[MAXDIMEN][MAXDIMEN];
|
||
|
signed char edge[MAXDIMEN][MAXDIMEN];
|
||
|
unsigned char flags[MAXDIMEN][MAXDIMEN];
|
||
|
int neighbors[MAXSIZE];
|
||
|
int k, l, h;
|
||
|
int m = 0, n = 0;
|
||
|
int vi[MAXSIZE];
|
||
|
int vj[MAXSIZE];
|
||
|
int eye_number[MAXPATNO];
|
||
|
int esize[MAXPATNO];
|
||
|
int msize[MAXPATNO];
|
||
|
int value_a[MAXPATNO];
|
||
|
int value_b[MAXPATNO];
|
||
|
int value_c[MAXPATNO];
|
||
|
int value_d[MAXPATNO];
|
||
|
int ends[MAXPATNO];
|
||
|
int two_neighbors[MAXPATNO];
|
||
|
int three_neighbors[MAXPATNO];
|
||
|
int num_attacks = 0;
|
||
|
int num_defenses = 0;
|
||
|
int debug = 0;
|
||
|
int fatal_errors = 0;
|
||
|
|
||
|
printf("\
|
||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\\n\
|
||
|
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *\n\
|
||
|
* http://www.gnu.org/software/gnugo/ for more information. *\n\
|
||
|
* *\n\
|
||
|
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *\n\
|
||
|
* by the Free Software Foundation. *\n\
|
||
|
* *\n\
|
||
|
* This program is free software; you can redistribute it and/or *\n\
|
||
|
* modify it under the terms of the GNU General Public License as *\n\
|
||
|
* published by the Free Software Foundation - version 3 *\n\
|
||
|
* or (at your option) any later version *\n\
|
||
|
* *\n\
|
||
|
* This program is distributed in the hope that it will be useful, *\n\
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *\n\
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\n\
|
||
|
* GNU General Public License in file COPYING for more details. *\n\
|
||
|
* *\n\
|
||
|
* You should have received a copy of the GNU General Public *\n\
|
||
|
* License along with this program; if not, write to the Free *\n\
|
||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *\n\
|
||
|
* Boston, MA 02111, USA. *\n\
|
||
|
\\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n");
|
||
|
|
||
|
printf("/* This file is automatically generated by mkeyes. Do not\n");
|
||
|
printf(" * edit it directly. Instead, edit the eye shape database.\n");
|
||
|
printf(" */\n\n");
|
||
|
printf("#include <stdio.h> /* for NULL */\n");
|
||
|
printf("#include \"eyes.h\"\n\n");
|
||
|
|
||
|
memset(ends, 0, sizeof(ends));
|
||
|
memset(two_neighbors, 0, sizeof(two_neighbors));
|
||
|
memset(three_neighbors, 0, sizeof(three_neighbors));
|
||
|
memset(esize, 0, sizeof(esize));
|
||
|
|
||
|
while (fgets(line, MAXLINE, stdin) && !fatal_errors) {
|
||
|
int last = strlen(line) - 1;
|
||
|
|
||
|
if (line[last] != '\n') {
|
||
|
fprintf(stderr, "mkeyes: line truncated: %s\n", line);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* remove trailing whitespace */
|
||
|
for (last--; last >= 0 && isspace((int) line[last]); last--) {
|
||
|
line[last] = '\n';
|
||
|
line[last+1] = '\0';
|
||
|
}
|
||
|
|
||
|
/* New pattern. */
|
||
|
if (sscanf(line, "Pattern %d", &p)) {
|
||
|
eye_number[patno] = p;
|
||
|
if (patno > 0 && eye_number[patno] <= eye_number[patno-1]) {
|
||
|
fprintf(stderr, "mkeyes: Pattern %d out of sequence\n",
|
||
|
eye_number[patno]);
|
||
|
return 1;
|
||
|
}
|
||
|
if (debug)
|
||
|
fprintf(stderr, "parsing pattern %d\n", eye_number[patno]);
|
||
|
|
||
|
memset(vertex, 0, sizeof(vertex));
|
||
|
memset(marginal, 0, sizeof(marginal));
|
||
|
memset(edge, 0, sizeof(edge));
|
||
|
memset(flags, 0, sizeof(flags));
|
||
|
|
||
|
m = 0;
|
||
|
esize[patno] = 0;
|
||
|
msize[patno] = 0;
|
||
|
num_attacks = 0;
|
||
|
num_defenses = 0;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Empty line or comment line, skip. */
|
||
|
if (strncmp("#", line, 1) == 0 || strncmp("\n", line, 1) == 0)
|
||
|
continue;
|
||
|
|
||
|
if (strncmp(":", line, 1) != 0) {
|
||
|
/* diagram line. */
|
||
|
for (n = 0; n < MAXDIMEN && strncmp("\n", line + n, 1); n++) {
|
||
|
/* space, harmless CR, or corner symbol */
|
||
|
if (line[n] == ' ' || line[n] == '\r' || line[n] == '+')
|
||
|
continue;
|
||
|
|
||
|
/* vertical edge */
|
||
|
if (line[n] == '|') {
|
||
|
if (n == 0)
|
||
|
edge[m][n+1]++;
|
||
|
else
|
||
|
edge[m][n-1]++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* horizontal edge */
|
||
|
if (line[n] == '-') {
|
||
|
if (m == 0)
|
||
|
edge[m+1][n]++;
|
||
|
else
|
||
|
edge[m-1][n]++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* All other symbols. */
|
||
|
vi[esize[patno]] = m;
|
||
|
vj[esize[patno]] = n;
|
||
|
vertex[m][n] = line[n];
|
||
|
if (debug)
|
||
|
fprintf(stderr, "%c", line[n]);
|
||
|
switch (line[n])
|
||
|
{
|
||
|
case '.':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_BE_EMPTY;
|
||
|
break;
|
||
|
|
||
|
case '!':
|
||
|
msize[patno]++;
|
||
|
marginal[m][n] = 1;
|
||
|
flags[m][n] = CAN_BE_EMPTY;
|
||
|
break;
|
||
|
|
||
|
case '@':
|
||
|
msize[patno]++;
|
||
|
marginal[m][n] = 1;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT | EYE_ATTACK_POINT;
|
||
|
num_attacks++;
|
||
|
num_defenses++;
|
||
|
break;
|
||
|
|
||
|
case '$':
|
||
|
msize[patno]++;
|
||
|
marginal[m][n] = 1;
|
||
|
flags[m][n] = CAN_CONTAIN_STONE;
|
||
|
break;
|
||
|
|
||
|
case '(':
|
||
|
msize[patno]++;
|
||
|
marginal[m][n] = 1;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT;
|
||
|
num_attacks++;
|
||
|
break;
|
||
|
|
||
|
case ')':
|
||
|
msize[patno]++;
|
||
|
marginal[m][n] = 1;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT;
|
||
|
num_defenses++;
|
||
|
break;
|
||
|
|
||
|
case 'x':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_BE_EMPTY | CAN_CONTAIN_STONE;
|
||
|
break;
|
||
|
|
||
|
case '*':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT | EYE_DEFENSE_POINT;
|
||
|
num_attacks++;
|
||
|
num_defenses++;
|
||
|
break;
|
||
|
|
||
|
case '<':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT;
|
||
|
num_attacks++;
|
||
|
break;
|
||
|
|
||
|
case '>':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT;
|
||
|
num_defenses++;
|
||
|
break;
|
||
|
|
||
|
case 'X':
|
||
|
marginal[m][n] = 0;
|
||
|
flags[m][n] = CAN_CONTAIN_STONE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf(stderr,
|
||
|
"mkeyes: invalid character %c in pattern %d\n",
|
||
|
line[n], eye_number[patno]);
|
||
|
fatal_errors++;
|
||
|
break;
|
||
|
}
|
||
|
esize[patno]++;
|
||
|
}
|
||
|
m++;
|
||
|
if (debug)
|
||
|
fprintf(stderr, "\n");
|
||
|
}
|
||
|
else {
|
||
|
/* Colon line. */
|
||
|
sscanf(line, ":%1d%1d%1d%1d", &value_a[patno], &value_b[patno],
|
||
|
&value_c[patno], &value_d[patno]);
|
||
|
if (debug)
|
||
|
fprintf(stderr, "value=%d%d%d%d\n", value_a[patno], value_b[patno],
|
||
|
value_c[patno], value_d[patno]);
|
||
|
|
||
|
if (value_b[patno] != value_c[patno]) {
|
||
|
if (num_attacks == 0 || num_defenses == 0) {
|
||
|
fprintf(stderr,
|
||
|
"mkeyes: missing attack or defense point in pattern %d\n",
|
||
|
eye_number[patno]);
|
||
|
fatal_errors++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (value_b[patno] == value_c[patno]) {
|
||
|
if (num_attacks > 0 || num_defenses > 0) {
|
||
|
fprintf(stderr,
|
||
|
"mkeyes: attack or defense point in settled pattern %d\n",
|
||
|
eye_number[patno]);
|
||
|
fatal_errors++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("static struct eye_vertex eye%d[] = {\n", eye_number[patno]);
|
||
|
|
||
|
for (l = 0; l < esize[patno]; l++) {
|
||
|
int ni[4];
|
||
|
int nj[4];
|
||
|
int nb[4];
|
||
|
int mx[MAXDIMEN][MAXDIMEN];
|
||
|
int count = 0;
|
||
|
int i = vi[l];
|
||
|
int j = vj[l];
|
||
|
|
||
|
memset(mx, -1, sizeof(mx));
|
||
|
|
||
|
neighbors[l] = 0;
|
||
|
|
||
|
for (h = 0; h < 4; h++) {
|
||
|
ni[h] = -1;
|
||
|
nj[h] = -1;
|
||
|
nb[h] = -1;
|
||
|
}
|
||
|
|
||
|
mx[i][j] = 0;
|
||
|
|
||
|
if (i > 0 && vertex[i-1][j]) {
|
||
|
ni[neighbors[l]] = i-1;
|
||
|
nj[neighbors[l]] = j;
|
||
|
neighbors[l]++;
|
||
|
count++;
|
||
|
mx[i-1][j] = l;
|
||
|
}
|
||
|
|
||
|
if (i < MAXDIMEN-1 && vertex[i+1][j]) {
|
||
|
ni[neighbors[l]] = i+1;
|
||
|
nj[neighbors[l]] = j;
|
||
|
neighbors[l]++;
|
||
|
count++;
|
||
|
mx[i+1][j] = l;
|
||
|
}
|
||
|
|
||
|
if (j > 0 && vertex[i][j-1]) {
|
||
|
ni[neighbors[l]] = i;
|
||
|
nj[neighbors[l]] = j-1;
|
||
|
neighbors[l]++;
|
||
|
mx[i][j-1] = l;
|
||
|
}
|
||
|
|
||
|
if (j < MAXDIMEN-1 && vertex[i][j+1]) {
|
||
|
ni[neighbors[l]] = i;
|
||
|
nj[neighbors[l]] = j+1;
|
||
|
neighbors[l]++;
|
||
|
mx[i][j+1] = l;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (neighbors[l] == 1)
|
||
|
ends[patno]++;
|
||
|
else if (neighbors[l] == 2)
|
||
|
two_neighbors[patno]++;
|
||
|
else if (neighbors[l] == 3)
|
||
|
three_neighbors[patno]++;
|
||
|
|
||
|
for (h = 0; h < esize[patno]; h++) {
|
||
|
|
||
|
for (k = 0; k < 4; k++)
|
||
|
if (ni[k] != -1 && vi[h] == ni[k] && vj[h] == nj[k])
|
||
|
nb[k] = h;
|
||
|
}
|
||
|
|
||
|
|
||
|
printf(" {%d, %d, %2d, %d, {%2d, %2d, %2d, %2d}}",
|
||
|
marginal[i][j], (int) edge[i][j], (int) flags[i][j],
|
||
|
neighbors[l], nb[0], nb[1], nb[2], nb[3]);
|
||
|
|
||
|
if (l < esize[patno]-1)
|
||
|
printf(",\n");
|
||
|
else
|
||
|
printf("\n};\n\n");
|
||
|
}
|
||
|
|
||
|
patno++;
|
||
|
if (patno >= MAXPATNO) {
|
||
|
fprintf(stderr,
|
||
|
"mkeyes: Too many eye patterns. Increase MAXPATNO in mkeyes.c\n");
|
||
|
fatal_errors++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
printf("\nstruct eye_graph graphs[] = {\n");
|
||
|
for (l = 0; l < patno; l++) {
|
||
|
|
||
|
printf(" {eye%d, %d, %d, %d, %d, %d, %d, {%d, %d, %d, %d}}",
|
||
|
eye_number[l], eye_number[l], esize[l], msize[l], ends[l],
|
||
|
two_neighbors[l], three_neighbors[l],
|
||
|
value_a[l], value_b[l], value_c[l], value_d[l]);
|
||
|
if (l < patno-1)
|
||
|
printf(",\n");
|
||
|
else
|
||
|
printf(",\n {NULL, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}}\n};\n");
|
||
|
}
|
||
|
|
||
|
if (fatal_errors) {
|
||
|
printf("\n\n#error in eye database. Rebuild.\n\n");
|
||
|
}
|
||
|
|
||
|
return fatal_errors;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Local Variables:
|
||
|
* tab-width: 8
|
||
|
* c-basic-offset: 2
|
||
|
* End:
|
||
|
*/
|