xref: /original-bsd/games/gomoku/bdinit.c (revision 4e1ffb20)
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.1 (Berkeley) 07/24/94";
13 #endif /* not lint */
14 
15 #include "gomoku.h"
16 
17 bdinit(bp)
18 	struct spotstr *bp;
19 {
20 	register int i, j, r;
21 	register struct spotstr *sp;
22 	register struct combostr *cbp;
23 
24 	movenum = 1;
25 
26 	/* mark the borders as such */
27 	sp = bp;
28 	for (i = BSZ2; --i >= 0; sp++) {
29 		sp->s_occ = BORDER;		/* top border */
30 		sp->s_flg = BFLAGALL;
31 	}
32 
33 	/* fill entire board with EMPTY spots */
34 	cbp = frames;
35 	for (j = 0; ++j < BSZ1; sp++) {			/* for each row */
36 		for (i = 0; ++i < BSZ1; sp++) {		/* for each column */
37 			sp->s_occ = EMPTY;
38 			sp->s_flg = 0;
39 			sp->s_wval = 0;
40 			if (j < 5) {
41 				/* directions 1, 2, 3 are blocked */
42 				sp->s_flg |= (BFLAG << 1) | (BFLAG << 2) |
43 					(BFLAG << 3);
44 				sp->s_fval[BLACK][1].s = MAXCOMBO;
45 				sp->s_fval[BLACK][2].s = MAXCOMBO;
46 				sp->s_fval[BLACK][3].s = MAXCOMBO;
47 				sp->s_fval[WHITE][1].s = MAXCOMBO;
48 				sp->s_fval[WHITE][2].s = MAXCOMBO;
49 				sp->s_fval[WHITE][3].s = MAXCOMBO;
50 			} else if (j == 5) {
51 				/* five spaces, blocked on one side */
52 				sp->s_fval[BLACK][1].s = 0x500;
53 				sp->s_fval[BLACK][2].s = 0x500;
54 				sp->s_fval[BLACK][3].s = 0x500;
55 				sp->s_fval[WHITE][1].s = 0x500;
56 				sp->s_fval[WHITE][2].s = 0x500;
57 				sp->s_fval[WHITE][3].s = 0x500;
58 			} else {
59 				/* six spaces, not blocked */
60 				sp->s_fval[BLACK][1].s = 0x401;
61 				sp->s_fval[BLACK][2].s = 0x401;
62 				sp->s_fval[BLACK][3].s = 0x401;
63 				sp->s_fval[WHITE][1].s = 0x401;
64 				sp->s_fval[WHITE][2].s = 0x401;
65 				sp->s_fval[WHITE][3].s = 0x401;
66 			}
67 			if (i > (BSZ - 4)) {
68 				/* directions 0, 1 are blocked */
69 				sp->s_flg |= BFLAG | (BFLAG << 1);
70 				sp->s_fval[BLACK][0].s = MAXCOMBO;
71 				sp->s_fval[BLACK][1].s = MAXCOMBO;
72 				sp->s_fval[WHITE][0].s = MAXCOMBO;
73 				sp->s_fval[WHITE][1].s = MAXCOMBO;
74 			} else if (i == (BSZ - 4)) {
75 				sp->s_fval[BLACK][0].s = 0x500;
76 				sp->s_fval[WHITE][0].s = 0x500;
77 				/* if direction 1 is not blocked */
78 				if (!(sp->s_flg & (BFLAG << 1))) {
79 					sp->s_fval[BLACK][1].s = 0x500;
80 					sp->s_fval[WHITE][1].s = 0x500;
81 				}
82 			} else {
83 				sp->s_fval[BLACK][0].s = 0x401;
84 				sp->s_fval[WHITE][0].s = 0x401;
85 				if (i < 5) {
86 					/* direction 3 is blocked */
87 					sp->s_flg |= (BFLAG << 3);
88 					sp->s_fval[BLACK][3].s = MAXCOMBO;
89 					sp->s_fval[WHITE][3].s = MAXCOMBO;
90 				} else if (i == 5 &&
91 				    !(sp->s_flg & (BFLAG << 3))) {
92 					sp->s_fval[BLACK][3].s = 0x500;
93 					sp->s_fval[WHITE][3].s = 0x500;
94 				}
95 			}
96 			/*
97 			 * Allocate a frame structure for non blocked frames.
98 			 */
99 			for (r = 4; --r >= 0; ) {
100 				if (sp->s_flg & (BFLAG << r))
101 					continue;
102 				cbp->c_next = (struct combostr *)0;
103 				cbp->c_prev = (struct combostr *)0;
104 				cbp->c_link[0] = (struct combostr *)0;
105 				cbp->c_link[1] = (struct combostr *)0;
106 				cbp->c_combo.s = sp->s_fval[BLACK][r].s;
107 				cbp->c_vertex = sp - board;
108 				cbp->c_nframes = 1;
109 				cbp->c_dir = r;
110 				cbp->c_flg = 0;
111 				cbp->c_refcnt = 0;
112 				sp->s_frame[r] = cbp;
113 				cbp++;
114 			}
115 		}
116 		sp->s_occ = BORDER;		/* left & right border */
117 		sp->s_flg = BFLAGALL;
118 	}
119 
120 	/* mark the borders as such */
121 	for (i = BSZ1; --i >= 0; sp++) {
122 		sp->s_occ = BORDER;		/* bottom border */
123 		sp->s_flg = BFLAGALL;
124 	}
125 
126 	sortframes[BLACK] = (struct combostr *)0;
127 	sortframes[WHITE] = (struct combostr *)0;
128 	init_overlap();
129 }
130 
131 /*
132  * Initialize the overlap array.
133  * Each entry in the array is a bit mask with four bits corresponding
134  * to whether frame A overlaps frame B. The four combinations are
135  * whether A and B are open ended (length 6) or closed (length 5).
136  *	0	A open and B open
137  *	1	A open and B closed
138  *	2	A closed and B open
139  *	3	A closed and B closed
140  */
141 init_overlap()
142 {
143 	register struct spotstr *sp1, *sp2;
144 	register struct combostr *cbp;
145 	register int i, f, r, n, d1, d2;
146 	int mask, bmask, vertex, s;
147 	char *str;
148 	short *ip;
149 
150 	memset(overlap, 0, sizeof(overlap));
151 	memset(intersect, 0, sizeof(intersect));
152 	str = &overlap[FAREA * FAREA];
153 	ip = &intersect[FAREA * FAREA];
154 	for (cbp = frames + FAREA; --cbp >= frames; ) {
155 	    str -= FAREA;
156 	    ip -= FAREA;
157 	    sp1 = &board[vertex = cbp->c_vertex];
158 	    d1 = dd[r = cbp->c_dir];
159 	    s = sp1->s_fval[BLACK][r].c.b;
160 	    for (i = 5 + s; --i >= 0; sp1 += d1, vertex += d1) {
161 		mask = (s && i == 0) ? 0xC : 0xF;
162 		for (r = 4; --r >= 0; ) {
163 		    bmask = BFLAG << r;
164 		    sp2 = sp1;
165 		    d2 = dd[r];
166 		    for (f = 6; --f >= 0; sp2 -= d2) {
167 			if (sp2->s_occ == BORDER)
168 			    break;
169 			if (sp2->s_flg & bmask)
170 			    continue;
171 			n = sp2->s_frame[r] - frames;
172 			str[n] |= (f == 0) ? mask & 0x5 : mask;
173 			ip[n] = vertex;
174 		    }
175 		}
176 	    }
177 	}
178 }
179