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