1 /*
2 GNU GO - the game of Go (Wei-Chi)
3 Version 1.1 last revised 3-1-89
4 Copyright (C) Free Software Foundation, Inc.
5 written by Man L. Li
6 modified by Wayne Iba
7 documented by Bob Webber
8 NeXT version by John Neil
9 */
10 /*
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation - version 1.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License in file COPYING for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 Please report any bug/fix, modification, suggestion to
25
26 mail address: Man L. Li
27 Dept. of Computer Science
28 University of Houston
29 4800 Calhoun Road
30 Houston, TX 77004
31
32 e-mail address: manli@cs.uh.edu (Internet)
33 coscgbn@uhvax1.bitnet (BITNET)
34 70070,404 (CompuServe)
35
36 For the NeXT version, please report any bug/fix, modification, suggestion to
37
38 mail address: John Neil
39 Mathematics Department
40 Portland State University
41 PO Box 751
42 Portland, OR 97207
43
44 e-mail address: neil@math.mth.pdx.edu (Internet)
45 neil@psuorvm.bitnet (BITNET)
46 */
47
48 #include "comment.header"
49
50 /* $Id: matchpat.c,v 1.1 2003/01/12 04:01:52 gcasa Exp $ */
51
52 /*
53 * $Log: matchpat.c,v $
54 * Revision 1.1 2003/01/12 04:01:52 gcasa
55 * Committing the entire GNU Go and NeXT Go application to the repository.
56 * See COPYING file for GNU License.
57 *
58 * Revision 1.3 1997/07/06 19:35:03 ergo
59 * actual version
60 *
61 * Revision 1.2 1997/05/04 18:57:08 ergo
62 * added time control for moves
63 *
64 */
65
66 #define EMPTY 0
67 #define MAXPC 16
68 #define abs(x) ((x) < 0 ? -(x) : (x))
69 #define line(x) (abs(x - 9))
70
71 extern unsigned char p[19][19];
72 extern int currentStone, opposingStone, MAXX, MAXY;
73 extern int lib;
74 extern void countlib(int,int,int);
75
matchpat(int m,int n,int * i,int * j,int * val)76 int matchpat(int m, int n, int *i, int *j, int *val)
77 /* match pattern and get next move */
78 {
79 struct patval {int x, y, att;}; /* pattern x, y coor and attribute */
80 /* att = 0 - empty, 1 - your piece, 2 - my piece, 3 - my next move */
81 /* 4 - empty on edge, 5 - your piece on edge, 6 - my piece on edge */
82 struct pattern {
83 struct patval patn[MAXPC]; /* pattern */
84 /* number of pieces in pattern, no. of transformation, pattern value */
85 int patlen, trfno, patwt;
86 };
87
88 #include "patterns.h"
89
90 /* transformation matrice */
91 static int trf [8][2][2] = {
92 {{1, 0}, {0, 1}}, /* linear transfomation matrix */
93 {{1, 0}, {0, -1}}, /* invert */
94 {{0, 1}, {-1, 0}}, /* rotate 90 */
95 {{0, -1}, {-1, 0}}, /* rotate 90 and invert */
96 {{-1, 0}, {0, 1}}, /* flip left */
97 {{-1, 0}, {0, -1}}, /* flip left and invert */
98 {{0, 1}, {1, 0}}, /* rotate 90 and flip left */
99 {{0, -1}, {1, 0}} /* rotate 90, flip left and invert */
100 };
101 int k, my, nx, l, r, cont;
102 int ti, tj, tval;
103
104 *i = -1; *j = -1; *val = -1;
105 ti = tj = 0;
106 for (r = 0; r < PATNO; r++)
107 /* try each pattern */
108 for (l = 0; l < pat[r].trfno; l++)
109 /* try each orientation transformation */
110 {
111 k = 0; cont = 1;
112 while ((k != pat[r].patlen) && cont)
113 /* match each point */
114 {
115 /* transform pattern real coordinate */
116 nx = n + trf[l][0][0] * pat[r].patn[k].x
117 + trf[l][0][1] * pat[r].patn[k].y;
118 my = m + trf[l][1][0] * pat[r].patn[k].x
119 + trf[l][1][1] * pat[r].patn[k].y;
120
121 /* outside the board */
122 if ((my < 0) || ( my > MAXY - 1) || (nx < 0) || (nx > MAXX - 1))
123 {
124 cont = 0;
125 break;
126 }
127 switch (pat[r].patn[k].att) {
128 case 0 : if (p[my][nx] == EMPTY) /* open */
129 break;
130 else
131 {
132 cont = 0;
133 break;
134 }
135 case 1 : if (p[my][nx] == opposingStone) /* your piece */
136 break;
137 else
138 {
139 cont = 0;
140 break;
141 }
142 case 2 : if (p[my][nx] == currentStone) /* my piece */
143 break;
144 else
145 {
146 cont = 0;
147 break;
148 }
149 case 3 : if (p[my][nx] == EMPTY) /* open for new move */
150 {
151 lib = 0;
152 countlib(my, nx, currentStone); /* check liberty */
153 if (lib > 1) /* move o.k. */
154 {
155 ti = my;
156 tj = nx;
157 break;
158 }
159 else
160 {
161 cont = 0;
162 break;
163 }
164 }
165 else
166 {
167 cont = 0;
168 break;
169 }
170 case 4 : if ((p[my][nx] == EMPTY) /* open on edge */
171 && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
172 break;
173 else
174 {
175 cont = 0;
176 break;
177 }
178 case 5 : if ((p[my][nx] == opposingStone) /* your piece on edge */
179 && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
180 break;
181 else
182 {
183 cont = 0;
184 break;
185 }
186 case 6 : if ((p[my][nx] == currentStone) /* my piece on edge */
187 && ((my == 0) || (my == MAXY - 1) || (nx == 0) || (nx == MAXX - 1)))
188 break;
189 else
190 {
191 cont = 0;
192 break;
193 }
194 }
195 ++k;
196 }
197 if (cont) /* match pattern */
198 {
199 tval = pat[r].patwt;
200 if ((r >= 8) && (r <= 13)) /* patterns for expand region */
201 {
202 if (line(ti) > 7) /* penalty on line 1, 2 */
203 tval--;
204 else
205 if ((line(ti) == 6) || (line(ti) == 7))
206 tval++; /* reward on line 3, 4 */
207
208 if (line(tj) > 7) /* penalty on line 1, 2 */
209 tval--;
210 else
211 if ((line(tj) == 6) || (line(tj) == 7))
212 tval++; /* reward on line 3, 4 */
213 }
214 if (tval > *val)
215 {
216 *val = tval;
217 *i = ti;
218 *j = tj;
219 }
220 }
221 }
222 if (*val > 0) /* pattern matched */
223 return 1;
224 else /* match failed */
225 return 0;
226 } /* end matchpat */
227