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