1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* 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. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "liberty.h"
#include "dfa.h"
#include <memory.h>
/* Array for use by TRANSFORM() macro. */
int transformation[MAX_OFFSET][8];
/* Matrix array for use by TRANSFORM2() macro. */
const int transformation2[8][2][2] = {
{ { 1, 0},
{ 0, 1}}, /* a - identity transformation matrix */
{ { 0, 1},
{-1, 0}}, /* g - rotate 90 clockwise */
{ {-1, 0},
{ 0, -1}}, /* d - rotate 180 */
{ { 0, -1},
{ 1, 0}}, /* f - rotate 90 counter-clockwise */
{ { 0, -1},
{-1, 0}}, /* h - rotate 90 clockwise and flip on x axis */
{ {-1, 0},
{ 0, 1}}, /* b - flip on x axis */
{ { 0, 1},
{ 1, 0}}, /* e - rotate 90 counter-clockwise and flip on x axis */
{ { 1, 0},
{ 0, -1}} /* c - flip on y axis */
};
/* Initialize transformation[][] array. */
void
transformation_init(void)
{
int k;
int dx;
int dy;
for (k = 0; k < 8; k++) {
for (dy = -MAX_BOARD+1; dy <= MAX_BOARD-1; dy++) {
for (dx = -MAX_BOARD+1; dx <= MAX_BOARD-1; dx++) {
int tx;
int ty;
TRANSFORM2(dx, dy, &tx, &ty, k);
transformation[OFFSET(dx, dy)][k] = DELTA(tx, ty);
}
}
}
}
/* Spiral orders for DFA matching and building. */
int spiral[DFA_MAX_ORDER][8];
/* The spiral order is the way we scan the board, we begin on the
* anchor and we progressively scan all its neigbouring intersections,
* collecting all the known patterns we meet on our way:
*
* 4 4 4
* 1 1 13 13 513 513 ... and so on until we reach a
* 2 2 2 2 827 stopping state in the DFA.
* 6
*
* Build the spiral order for each transformation: instead of changing
* the board or changing the patterns, we only change the order. For
* e.g. the same DFA can perform the pattern matching
*
* That way for identity:
*
* 40 04
* 5139 and this way for mirror symetry: 9315
* 827 728
* 6 6
*
* Anther possibility is to generate one string by pattern and by
* transformation in `mkpat' to avoid any runtime transformation but
* it drastically increases the size of DFAs.
*/
void
build_spiral_order(void)
{
int i;
int j;
int k;
char mark[2 * DFA_MAX_BOARD + 1][2 * DFA_MAX_BOARD + 1];
int queue_i[DFA_MAX_ORDER];
int queue_j[DFA_MAX_ORDER];
int queue_start = 0;
int queue_end = 1;
static const int delta_i[4] = { 1, 0, -1, 0};
static const int delta_j[4] = { 0, 1, 0, -1};
/* Initialization. */
memset(mark, 1, sizeof(mark));
for (i = 1; i < 2 * DFA_MAX_BOARD; i++) {
for (j = 1; j < 2 * DFA_MAX_BOARD; j++)
mark[i][j] = 0;
}
queue_i[0] = DFA_MAX_BOARD;
queue_j[0] = DFA_MAX_BOARD;
mark[DFA_MAX_BOARD][DFA_MAX_BOARD] = 1;
do {
int transformation;
/* Transform queued coordinates and store DFA offsets in spiral[][]. */
for (transformation = 0; transformation < 8; transformation++) {
TRANSFORM2(queue_i[queue_start] - DFA_MAX_BOARD,
queue_j[queue_start] - DFA_MAX_BOARD,
&i, &j, transformation);
spiral[queue_start][transformation] = DFA_BASE * i + j;
}
for (k = 0; k < 4; k++) {
i = queue_i[queue_start] + delta_i[k];
j = queue_j[queue_start] + delta_j[k];
if (!mark[i][j]) {
queue_i[queue_end] = i;
queue_j[queue_end++] = j;
mark[i][j] = 1;
}
}
} while (++queue_start < queue_end);
if (0) {
int transformation;
for (transformation = 0; transformation < 8; transformation++) {
fprintf(stderr, "Transformation %d:\n", transformation);
for (k = 0; k < 16; k++) {
fprintf(stderr, "\t%d(%c); %d\n", k, 'A' + k,
spiral[k][transformation]);
}
}
}
}
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/
|