xref: /original-bsd/games/gomoku/bdinit.c (revision d2590928)
1 /*
2  * Copyright (c) 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ralph Campbell.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)bdinit.c	8.2 (Berkeley) 05/03/95";
13 #endif /* not lint */
14 
15 #include <string.h>
16 #include "gomoku.h"
17 
18 bdinit(bp)
19 	struct spotstr *bp;
20 {
21 	register int i, j, r;
22 	register struct spotstr *sp;
23 	register struct combostr *cbp;
24 
25 	movenum = 1;
26 
27 	/* mark the borders as such */
28 	sp = bp;
29 	for (i = BSZ2; --i >= 0; sp++) {
30 		sp->s_occ = BORDER;		/* top border */
31 		sp->s_flg = BFLAGALL;
32 	}
33 
34 	/* fill entire board with EMPTY spots */
35 	memset(frames, 0, sizeof(frames));
36 	cbp = frames;
37 	for (j = 0; ++j < BSZ1; sp++) {			/* for each row */
38 		for (i = 0; ++i < BSZ1; sp++) {		/* for each column */
39 			sp->s_occ = EMPTY;
40 			sp->s_flg = 0;
41 			sp->s_wval = 0;
42 			if (j < 5) {
43 				/* directions 1, 2, 3 are blocked */
44 				sp->s_flg |= (BFLAG << 1) | (BFLAG << 2) |
45 					(BFLAG << 3);
46 				sp->s_fval[BLACK][1].s = MAXCOMBO;
47 				sp->s_fval[BLACK][2].s = MAXCOMBO;
48 				sp->s_fval[BLACK][3].s = MAXCOMBO;
49 				sp->s_fval[WHITE][1].s = MAXCOMBO;
50 				sp->s_fval[WHITE][2].s = MAXCOMBO;
51 				sp->s_fval[WHITE][3].s = MAXCOMBO;
52 			} else if (j == 5) {
53 				/* five spaces, blocked on one side */
54 				sp->s_fval[BLACK][1].s = 0x500;
55 				sp->s_fval[BLACK][2].s = 0x500;
56 				sp->s_fval[BLACK][3].s = 0x500;
57 				sp->s_fval[WHITE][1].s = 0x500;
58 				sp->s_fval[WHITE][2].s = 0x500;
59 				sp->s_fval[WHITE][3].s = 0x500;
60 			} else {
61 				/* six spaces, not blocked */
62 				sp->s_fval[BLACK][1].s = 0x401;
63 				sp->s_fval[BLACK][2].s = 0x401;
64 				sp->s_fval[BLACK][3].s = 0x401;
65 				sp->s_fval[WHITE][1].s = 0x401;
66 				sp->s_fval[WHITE][2].s = 0x401;
67 				sp->s_fval[WHITE][3].s = 0x401;
68 			}
69 			if (i > (BSZ - 4)) {
70 				/* directions 0, 1 are blocked */
71 				sp->s_flg |= BFLAG | (BFLAG << 1);
72 				sp->s_fval[BLACK][0].s = MAXCOMBO;
73 				sp->s_fval[BLACK][1].s = MAXCOMBO;
74 				sp->s_fval[WHITE][0].s = MAXCOMBO;
75 				sp->s_fval[WHITE][1].s = MAXCOMBO;
76 			} else if (i == (BSZ - 4)) {
77 				sp->s_fval[BLACK][0].s = 0x500;
78 				sp->s_fval[WHITE][0].s = 0x500;
79 				/* if direction 1 is not blocked */
80 				if (!(sp->s_flg & (BFLAG << 1))) {
81 					sp->s_fval[BLACK][1].s = 0x500;
82 					sp->s_fval[WHITE][1].s = 0x500;
83 				}
84 			} else {
85 				sp->s_fval[BLACK][0].s = 0x401;
86 				sp->s_fval[WHITE][0].s = 0x401;
87 				if (i < 5) {
88 					/* direction 3 is blocked */
89 					sp->s_flg |= (BFLAG << 3);
90 					sp->s_fval[BLACK][3].s = MAXCOMBO;
91 					sp->s_fval[WHITE][3].s = MAXCOMBO;
92 				} else if (i == 5 &&
93 				    !(sp->s_flg & (BFLAG << 3))) {
94 					sp->s_fval[BLACK][3].s = 0x500;
95 					sp->s_fval[WHITE][3].s = 0x500;
96 				}
97 			}
98 			/*
99 			 * Allocate a frame structure for non blocked frames.
100 			 */
101 			for (r = 4; --r >= 0; ) {
102 				if (sp->s_flg & (BFLAG << r))
103 					continue;
104 				cbp->c_combo.s = sp->s_fval[BLACK][r].s;
105 				cbp->c_vertex = sp - board;
106 				cbp->c_nframes = 1;
107 				cbp->c_dir = r;
108 				sp->s_frame[r] = cbp;
109 				cbp++;
110 			}
111 		}
112 		sp->s_occ = BORDER;		/* left & right border */
113 		sp->s_flg = BFLAGALL;
114 	}
115 
116 	/* mark the borders as such */
117 	for (i = BSZ1; --i >= 0; sp++) {
118 		sp->s_occ = BORDER;		/* bottom border */
119 		sp->s_flg = BFLAGALL;
120 	}
121 
122 	sortframes[BLACK] = (struct combostr *)0;
123 	sortframes[WHITE] = (struct combostr *)0;
124 	init_overlap();
125 }
126 
127 /*
128  * Initialize the overlap array.
129  * Each entry in the array is a bit mask with eight bits corresponding
130  * to whether frame B overlaps frame A (as indexed by overlap[A * FAREA + B]).
131  * The eight bits coorespond to whether A and B are open ended (length 6) or
132  * closed (length 5).
133  *	0	A closed and B closed
134  *	1	A closed and B open
135  *	2	A open and B closed
136  *	3	A open and B open
137  *	4	A closed and B closed and overlaps in more than one spot
138  *	5	A closed and B open and overlaps in more than one spot
139  *	6	A open and B closed and overlaps in more than one spot
140  *	7	A open and B open and overlaps in more than one spot
141  * As pieces are played, it can make frames not overlap if there are no
142  * common open spaces shared between the two frames.
143  */
144 init_overlap()
145 {
146 	register struct spotstr *sp1, *sp2;
147 	register struct combostr *cbp;
148 	register int i, f, r, n, d1, d2;
149 	int mask, bmask, vertex, s;
150 	u_char *str;
151 	short *ip;
152 
153 	memset(overlap, 0, sizeof(overlap));
154 	memset(intersect, 0, sizeof(intersect));
155 	str = &overlap[FAREA * FAREA];
156 	ip = &intersect[FAREA * FAREA];
157 	for (cbp = frames + FAREA; --cbp >= frames; ) {		/* each frame */
158 	    str -= FAREA;
159 	    ip -= FAREA;
160 	    sp1 = &board[vertex = cbp->c_vertex];
161 	    d1 = dd[r = cbp->c_dir];
162 	    /*
163 	     * s = 5 if closed, 6 if open.
164 	     * At this point black & white are the same.
165 	     */
166 	    s = 5 + sp1->s_fval[BLACK][r].c.b;
167 	    /* for each spot in frame A */
168 	    for (i = 0; i < s; i++, sp1 += d1, vertex += d1) {
169 		/* the sixth spot in frame A only overlaps if it is open */
170 		mask = (i == 5) ? 0xC : 0xF;
171 		/* for each direction */
172 		for (r = 4; --r >= 0; ) {
173 		    bmask = BFLAG << r;
174 		    sp2 = sp1;
175 		    d2 = dd[r];
176 		    /* for each frame that intersects at spot sp1 */
177 		    for (f = 0; f < 6; f++, sp2 -= d2) {
178 			if (sp2->s_occ == BORDER)
179 			    break;
180 			if (sp2->s_flg & bmask)
181 			    continue;
182 			n = sp2->s_frame[r] - frames;
183 			ip[n] = vertex;
184 			str[n] |= (f == 5) ? mask & 0xA : mask;
185 			if (r == cbp->c_dir) {
186 			    /* compute the multiple spot overlap values */
187 			    switch (i) {
188 			    case 0:	/* sp1 is the first spot in A */
189 				if (f == 4)
190 				    str[n] |= 0xA0;
191 				else if (f != 5)
192 				    str[n] |= 0xF0;
193 				break;
194 			    case 1:	/* sp1 is the second spot in A */
195 				if (f == 5)
196 				    str[n] |= 0xA0;
197 				else
198 				    str[n] |= 0xF0;
199 				break;
200 			    case 4:	/* sp1 is the penultimate spot in A */
201 				if (f == 0)
202 				    str[n] |= 0xC0;
203 				else
204 				    str[n] |= 0xF0;
205 				break;
206 			    case 5:	/* sp1 is the last spot in A */
207 				if (f == 1)
208 				    str[n] |= 0xC0;
209 				else if (f != 0)
210 				    str[n] |= 0xF0;
211 				break;
212 			    default:
213 				str[n] |= 0xF0;
214 			    }
215 			}
216 		    }
217 		}
218 	    }
219 	}
220 }
221