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