1 /* 2 * Copyright (c) 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)makemove.c 8.1 (Berkeley) 07/24/94"; 13 #endif /* not lint */ 14 15 #include "gomoku.h" 16 17 /* direction deltas */ 18 int dd[4] = { 19 MRIGHT, MRIGHT+MDOWN, MDOWN, MDOWN+MLEFT 20 }; 21 22 int weight[5] = { 0, 1, 7, 22, 100 }; 23 24 /* 25 * Return values: 26 * MOVEOK everything is OK. 27 * RESIGN Player resigned. 28 * ILLEGAL Illegal move. 29 * WIN The the winning move was just played. 30 * TIE The game is a tie. 31 */ 32 makemove(us, mv) 33 int us, mv; 34 { 35 register struct spotstr *sp, *fsp; 36 register union combo *cp; 37 struct spotstr *osp; 38 struct combostr *cbp, *cbp1; 39 union combo *cp1; 40 register int i, f, r, d, n; 41 int space, val, bmask; 42 43 /* check for end of game */ 44 if (mv == RESIGN) 45 return(RESIGN); 46 47 /* check for illegal move */ 48 sp = &board[mv]; 49 if (sp->s_occ != EMPTY) 50 return(ILLEGAL); 51 52 /* make move */ 53 sp->s_occ = us; 54 movelog[movenum - 1] = mv; 55 if (++movenum == BSZ * BSZ) 56 return(TIE); 57 58 /* compute new frame values */ 59 sp->s_wval = 0; 60 osp = sp; 61 for (r = 4; --r >= 0; ) { /* for each direction */ 62 d = dd[r]; 63 fsp = osp; 64 bmask = BFLAG << r; 65 for (f = 5; --f >= 0; fsp -= d) { /* for each frame */ 66 if (fsp->s_occ == BORDER) 67 goto nextr; 68 if (fsp->s_flg & bmask) 69 continue; 70 71 /* remove this frame from the sorted list of frames */ 72 cbp = fsp->s_frame[r]; 73 if (cbp->c_next) { 74 if (sortframes[BLACK] == cbp) 75 sortframes[BLACK] = cbp->c_next; 76 if (sortframes[WHITE] == cbp) 77 sortframes[WHITE] = cbp->c_next; 78 cbp->c_next->c_prev = cbp->c_prev; 79 cbp->c_prev->c_next = cbp->c_next; 80 } 81 82 /* compute old weight value for this frame */ 83 cp = &fsp->s_fval[BLACK][r]; 84 if (cp->s <= 0x500) 85 val = weight[5 - cp->c.a - cp->c.b]; 86 else 87 val = 0; 88 cp = &fsp->s_fval[WHITE][r]; 89 if (cp->s <= 0x500) 90 val += weight[5 - cp->c.a - cp->c.b]; 91 92 /* compute new combo value for this frame */ 93 sp = fsp; 94 space = sp->s_occ == EMPTY; 95 n = 0; 96 for (i = 5; --i >= 0; sp += d) { /* for each spot */ 97 if (sp->s_occ == us) 98 n++; 99 else if (sp->s_occ == EMPTY) 100 sp->s_wval -= val; 101 else { 102 /* this frame is now blocked, adjust values */ 103 fsp->s_flg |= bmask; 104 fsp->s_fval[BLACK][r].s = MAXCOMBO; 105 fsp->s_fval[WHITE][r].s = MAXCOMBO; 106 while (--i >= 0) { 107 sp += d; 108 if (sp->s_occ == EMPTY) 109 sp->s_wval -= val; 110 } 111 goto nextf; 112 } 113 } 114 115 /* check for game over */ 116 if (n == 5) 117 return(WIN); 118 119 /* compute new value & combo number for this frame & color */ 120 fsp->s_fval[!us][r].s = MAXCOMBO; 121 cp = &fsp->s_fval[us][r]; 122 /* both ends open? */ 123 if (space && sp->s_occ == EMPTY) { 124 cp->c.a = 4 - n; 125 cp->c.b = 1; 126 } else { 127 cp->c.a = 5 - n; 128 cp->c.b = 0; 129 } 130 val = weight[n]; 131 sp = fsp; 132 for (i = 5; --i >= 0; sp += d) /* for each spot */ 133 if (sp->s_occ == EMPTY) 134 sp->s_wval += val; 135 136 /* add this frame to the sorted list of frames by combo value */ 137 cbp1 = sortframes[us]; 138 if (!cbp1) 139 sortframes[us] = cbp->c_next = cbp->c_prev = cbp; 140 else { 141 cp1 = &board[cbp1->c_vertex].s_fval[us][cbp1->c_dir]; 142 if (cp->s <= cp1->s) { 143 /* insert at the head of the list */ 144 sortframes[us] = cbp; 145 } else { 146 do { 147 cbp1 = cbp1->c_next; 148 cp1 = &board[cbp1->c_vertex].s_fval[us][cbp1->c_dir]; 149 if (cp->s <= cp1->s) 150 break; 151 } while (cbp1 != sortframes[us]); 152 } 153 cbp->c_next = cbp1; 154 cbp->c_prev = cbp1->c_prev; 155 cbp1->c_prev->c_next = cbp; 156 cbp1->c_prev = cbp; 157 } 158 159 nextf: 160 ; 161 } 162 163 /* both ends open? */ 164 if (fsp->s_occ == EMPTY) { 165 cp = &fsp->s_fval[BLACK][r]; 166 if (cp->c.b) { 167 cp->c.a += 1; 168 cp->c.b = 0; 169 } 170 cp = &fsp->s_fval[WHITE][r]; 171 if (cp->c.b) { 172 cp->c.a += 1; 173 cp->c.b = 0; 174 } 175 } 176 177 nextr: 178 ; 179 } 180 181 return(MOVEOK); 182 } 183