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