1 /* $NetBSD: bdinit.c,v 1.4 1997/10/10 13:36:01 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ralph Campbell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "from: @(#)bdinit.c 8.2 (Berkeley) 5/3/95"; 43 #else 44 __RCSID("$NetBSD: bdinit.c,v 1.4 1997/10/10 13:36:01 lukem Exp $"); 45 #endif 46 #endif /* not lint */ 47 48 #include <string.h> 49 #include "gomoku.h" 50 51 void 52 bdinit(bp) 53 struct spotstr *bp; 54 { 55 int i, j, r; 56 struct spotstr *sp; 57 struct combostr *cbp; 58 59 movenum = 1; 60 61 /* mark the borders as such */ 62 sp = bp; 63 for (i = BSZ2; --i >= 0; sp++) { 64 sp->s_occ = BORDER; /* top border */ 65 sp->s_flg = BFLAGALL; 66 } 67 68 /* fill entire board with EMPTY spots */ 69 memset(frames, 0, sizeof(frames)); 70 cbp = frames; 71 for (j = 0; ++j < BSZ1; sp++) { /* for each row */ 72 for (i = 0; ++i < BSZ1; sp++) { /* for each column */ 73 sp->s_occ = EMPTY; 74 sp->s_flg = 0; 75 sp->s_wval = 0; 76 if (j < 5) { 77 /* directions 1, 2, 3 are blocked */ 78 sp->s_flg |= (BFLAG << 1) | (BFLAG << 2) | 79 (BFLAG << 3); 80 sp->s_fval[BLACK][1].s = MAXCOMBO; 81 sp->s_fval[BLACK][2].s = MAXCOMBO; 82 sp->s_fval[BLACK][3].s = MAXCOMBO; 83 sp->s_fval[WHITE][1].s = MAXCOMBO; 84 sp->s_fval[WHITE][2].s = MAXCOMBO; 85 sp->s_fval[WHITE][3].s = MAXCOMBO; 86 } else if (j == 5) { 87 /* five spaces, blocked on one side */ 88 sp->s_fval[BLACK][1].s = 0x500; 89 sp->s_fval[BLACK][2].s = 0x500; 90 sp->s_fval[BLACK][3].s = 0x500; 91 sp->s_fval[WHITE][1].s = 0x500; 92 sp->s_fval[WHITE][2].s = 0x500; 93 sp->s_fval[WHITE][3].s = 0x500; 94 } else { 95 /* six spaces, not blocked */ 96 sp->s_fval[BLACK][1].s = 0x401; 97 sp->s_fval[BLACK][2].s = 0x401; 98 sp->s_fval[BLACK][3].s = 0x401; 99 sp->s_fval[WHITE][1].s = 0x401; 100 sp->s_fval[WHITE][2].s = 0x401; 101 sp->s_fval[WHITE][3].s = 0x401; 102 } 103 if (i > (BSZ - 4)) { 104 /* directions 0, 1 are blocked */ 105 sp->s_flg |= BFLAG | (BFLAG << 1); 106 sp->s_fval[BLACK][0].s = MAXCOMBO; 107 sp->s_fval[BLACK][1].s = MAXCOMBO; 108 sp->s_fval[WHITE][0].s = MAXCOMBO; 109 sp->s_fval[WHITE][1].s = MAXCOMBO; 110 } else if (i == (BSZ - 4)) { 111 sp->s_fval[BLACK][0].s = 0x500; 112 sp->s_fval[WHITE][0].s = 0x500; 113 /* if direction 1 is not blocked */ 114 if (!(sp->s_flg & (BFLAG << 1))) { 115 sp->s_fval[BLACK][1].s = 0x500; 116 sp->s_fval[WHITE][1].s = 0x500; 117 } 118 } else { 119 sp->s_fval[BLACK][0].s = 0x401; 120 sp->s_fval[WHITE][0].s = 0x401; 121 if (i < 5) { 122 /* direction 3 is blocked */ 123 sp->s_flg |= (BFLAG << 3); 124 sp->s_fval[BLACK][3].s = MAXCOMBO; 125 sp->s_fval[WHITE][3].s = MAXCOMBO; 126 } else if (i == 5 && 127 !(sp->s_flg & (BFLAG << 3))) { 128 sp->s_fval[BLACK][3].s = 0x500; 129 sp->s_fval[WHITE][3].s = 0x500; 130 } 131 } 132 /* 133 * Allocate a frame structure for non blocked frames. 134 */ 135 for (r = 4; --r >= 0; ) { 136 if (sp->s_flg & (BFLAG << r)) 137 continue; 138 cbp->c_combo.s = sp->s_fval[BLACK][r].s; 139 cbp->c_vertex = sp - board; 140 cbp->c_nframes = 1; 141 cbp->c_dir = r; 142 sp->s_frame[r] = cbp; 143 cbp++; 144 } 145 } 146 sp->s_occ = BORDER; /* left & right border */ 147 sp->s_flg = BFLAGALL; 148 } 149 150 /* mark the borders as such */ 151 for (i = BSZ1; --i >= 0; sp++) { 152 sp->s_occ = BORDER; /* bottom border */ 153 sp->s_flg = BFLAGALL; 154 } 155 156 sortframes[BLACK] = (struct combostr *)0; 157 sortframes[WHITE] = (struct combostr *)0; 158 init_overlap(); 159 } 160 161 /* 162 * Initialize the overlap array. 163 * Each entry in the array is a bit mask with eight bits corresponding 164 * to whether frame B overlaps frame A (as indexed by overlap[A * FAREA + B]). 165 * The eight bits coorespond to whether A and B are open ended (length 6) or 166 * closed (length 5). 167 * 0 A closed and B closed 168 * 1 A closed and B open 169 * 2 A open and B closed 170 * 3 A open and B open 171 * 4 A closed and B closed and overlaps in more than one spot 172 * 5 A closed and B open and overlaps in more than one spot 173 * 6 A open and B closed and overlaps in more than one spot 174 * 7 A open and B open and overlaps in more than one spot 175 * As pieces are played, it can make frames not overlap if there are no 176 * common open spaces shared between the two frames. 177 */ 178 void 179 init_overlap() 180 { 181 struct spotstr *sp1, *sp2; 182 struct combostr *cbp; 183 int i, f, r, n, d1, d2; 184 int mask, bmask, vertex, s; 185 u_char *str; 186 short *ip; 187 188 memset(overlap, 0, sizeof(overlap)); 189 memset(intersect, 0, sizeof(intersect)); 190 str = &overlap[FAREA * FAREA]; 191 ip = &intersect[FAREA * FAREA]; 192 for (cbp = frames + FAREA; --cbp >= frames; ) { /* each frame */ 193 str -= FAREA; 194 ip -= FAREA; 195 sp1 = &board[vertex = cbp->c_vertex]; 196 d1 = dd[r = cbp->c_dir]; 197 /* 198 * s = 5 if closed, 6 if open. 199 * At this point black & white are the same. 200 */ 201 s = 5 + sp1->s_fval[BLACK][r].c.b; 202 /* for each spot in frame A */ 203 for (i = 0; i < s; i++, sp1 += d1, vertex += d1) { 204 /* the sixth spot in frame A only overlaps if it is open */ 205 mask = (i == 5) ? 0xC : 0xF; 206 /* for each direction */ 207 for (r = 4; --r >= 0; ) { 208 bmask = BFLAG << r; 209 sp2 = sp1; 210 d2 = dd[r]; 211 /* for each frame that intersects at spot sp1 */ 212 for (f = 0; f < 6; f++, sp2 -= d2) { 213 if (sp2->s_occ == BORDER) 214 break; 215 if (sp2->s_flg & bmask) 216 continue; 217 n = sp2->s_frame[r] - frames; 218 ip[n] = vertex; 219 str[n] |= (f == 5) ? mask & 0xA : mask; 220 if (r == cbp->c_dir) { 221 /* compute the multiple spot overlap values */ 222 switch (i) { 223 case 0: /* sp1 is the first spot in A */ 224 if (f == 4) 225 str[n] |= 0xA0; 226 else if (f != 5) 227 str[n] |= 0xF0; 228 break; 229 case 1: /* sp1 is the second spot in A */ 230 if (f == 5) 231 str[n] |= 0xA0; 232 else 233 str[n] |= 0xF0; 234 break; 235 case 4: /* sp1 is the penultimate spot in A */ 236 if (f == 0) 237 str[n] |= 0xC0; 238 else 239 str[n] |= 0xF0; 240 break; 241 case 5: /* sp1 is the last spot in A */ 242 if (f == 1) 243 str[n] |= 0xC0; 244 else if (f != 0) 245 str[n] |= 0xF0; 246 break; 247 default: 248 str[n] |= 0xF0; 249 } 250 } 251 } 252 } 253 } 254 } 255 } 256