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