1 /* $OpenBSD: fancy.c,v 1.10 2001/06/23 23:50:03 pjanzen Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)fancy.c 8.1 (Berkeley) 5/31/93"; 39 #else 40 static char rcsid[] = "$OpenBSD: fancy.c,v 1.10 2001/06/23 23:50:03 pjanzen Exp $"; 41 #endif 42 #endif /* not lint */ 43 44 #include <err.h> 45 #include "back.h" 46 47 int oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 48 int oldr, oldw; 49 50 void 51 fboard() 52 { 53 int i, j, k, l; 54 55 /* could use box() or wborder() instead of the following */ 56 move(0, 0); /* do top line */ 57 for (i = 0; i < 53; i++) 58 addch('_'); 59 60 move(15, 0); /* do bottom line */ 61 for (i = 0; i < 53; i++) 62 addch('_'); 63 64 l = 1; /* do vertical lines */ 65 for (i = 52; i > -1; i -= 28) { 66 k = (l == 1 ? 1 : 15); 67 mvaddch(k, i, '|'); 68 for (j = 0; j < 14; j++) 69 mvaddch(k += l, i, '|'); 70 if (i == 24) 71 i += 32; 72 l = -l; /* alternate directions */ 73 } 74 75 /* label positions */ 76 for (i = 13; i < 19; i++) 77 mvprintw(2, 1 + (i - 13) * 4, "%d", i); 78 for (i = 19; i < 25; i++) 79 mvprintw(2, 29 + (i - 19) * 4, "%d", i); 80 for (i = 12; i > 6; i--) 81 mvprintw(14, 1 + (12 - i) * 4, "%2d", i); 82 for (i = 6; i > 0; i--) 83 mvprintw(14, 30 + (6 - i) * 4, "%d", i); 84 85 /* print positions 12-7 */ 86 for (i = 12; i > 6; i--) 87 if (board[i]) 88 bsect(board[i], 13, 1 + 4 * (12 - i), -1); 89 /* print red men on bar */ 90 if (board[0]) 91 bsect(board[0], 13, 25, -1); 92 /* print positions 6-1 */ 93 for (i = 6; i > 0; i--) 94 if (board[i]) 95 bsect(board[i], 13, 29 + 4 * (6 - i), -1); 96 /* print white's home */ 97 l = (off[1] < 0 ? off[1] + 15 : off[1]); 98 bsect(l, 3, 54, 1); 99 100 mvaddstr(8, 25, "BAR"); 101 102 /* print positions 13-18 */ 103 for (i = 13; i < 19; i++) 104 if (board[i]) 105 bsect(board[i], 3, 1 + 4 * (i - 13), 1); 106 /* print white's men on bar */ 107 if (board[25]) 108 bsect(board[25], 3, 25, 1); 109 /* print positions 19-24 */ 110 for (i = 19; i < 25; i++) 111 if (board[i]) 112 bsect(board[i], 3, 29 + 4 * (i - 19), 1); 113 /* print red's home */ 114 l = (off[0] < 0 ? off[0] + 15 : off[0]); 115 bsect(-l, 13, 54, -1); 116 117 for (i = 0; i < 26; i++)/* save board position for refresh later */ 118 oldb[i] = board[i]; 119 oldr = (off[1] < 0 ? off[1] + 15 : off[1]); 120 oldw = -(off[0] < 0 ? off[0] + 15 : off[0]); 121 } 122 123 /* 124 * bsect (b,rpos,cpos,cnext) 125 * Print the contents of a board position. "b" has the value of the 126 * position, "rpos" is the row to start printing, "cpos" is the column to 127 * start printing, and "cnext" is positive if the position starts at the top 128 * and negative if it starts at the bottom. The value of "cpos" is checked 129 * to see if the position is a player's home, since those are printed 130 * differently. 131 */ 132 void 133 bsect(b, rpos, cpos, cnext) 134 int b; /* contents of position */ 135 int rpos; /* row of position */ 136 int cpos; /* column of position */ 137 int cnext; /* direction of position */ 138 { 139 int j; /* index */ 140 int n; /* number of men on position */ 141 int bct; /* counter */ 142 int k; /* index */ 143 char pc; /* color of men on position */ 144 145 n = abs(b); /* initialize n and pc */ 146 pc = (b > 0 ? 'r' : 'w'); 147 148 if (n < 6 && cpos < 54) /* position cursor at start */ 149 move(rpos, cpos + 1); 150 else 151 move(rpos, cpos); 152 153 for (j = 0; j < 5; j++) { /* print position row by row */ 154 155 for (k = 0; k < 15; k += 5) /* print men */ 156 if (n > j + k) 157 addch(pc); 158 159 if (j < 4) { /* figure how far to back up for next row */ 160 if (n < 6) { /* stop if none left */ 161 if (j + 1 == n) 162 break; 163 bct = 1; /* single column */ 164 } else { 165 if (n < 11) { /* two columns */ 166 if (cpos >= 54) { /* home pos */ 167 if (j + 5 >= n) 168 bct = 1; 169 else 170 bct = 2; 171 } else { /* not home */ 172 if (j + 6 >= n) 173 bct = 1; 174 else 175 bct = 2; 176 } 177 } else { /* three columns */ 178 if (j + 10 >= n) 179 bct = 2; 180 else 181 bct = 3; 182 } 183 } 184 getyx(stdscr, rpos, cpos); 185 move(rpos + cnext, cpos - bct); 186 } 187 } 188 } 189 190 void 191 moveplayers() 192 { 193 int i, r, c; 194 195 getyx(stdscr, r, c); 196 for (i = 12; i > 6; i--)/* fix positions 12-7 */ 197 if (board[i] != oldb[i]) { 198 fixpos(oldb[i], board[i], 13, 1 + (12 - i) * 4, -1); 199 oldb[i] = board[i]; 200 } 201 if (board[0] != oldb[0]) { /* fix red men on bar */ 202 fixpos(oldb[0], board[0], 13, 25, -1); 203 oldb[0] = board[0]; 204 } 205 for (i = 6; i > 0; i--) /* fix positions 6-1 */ 206 if (board[i] != oldb[i]) { 207 fixpos(oldb[i], board[i], 13, 29 + (6 - i) * 4, -1); 208 oldb[i] = board[i]; 209 } 210 i = -(off[0] < 0 ? off[0] + 15 : off[0]); /* fix white's home */ 211 if (oldw != i) { 212 fixpos(oldw, i, 13, 54, -1); 213 oldw = i; 214 } 215 for (i = 13; i < 19; i++) /* fix positions 13-18 */ 216 if (board[i] != oldb[i]) { 217 fixpos(oldb[i], board[i], 3, 1 + (i - 13) * 4, 1); 218 oldb[i] = board[i]; 219 } 220 if (board[25] != oldb[25]) { /* fix white men on bar */ 221 fixpos(oldb[25], board[25], 3, 25, 1); 222 oldb[25] = board[25]; 223 } 224 for (i = 19; i < 25; i++) /* fix positions 19-24 */ 225 if (board[i] != oldb[i]) { 226 fixpos(oldb[i], board[i], 3, 29 + (i - 19) * 4, 1); 227 oldb[i] = board[i]; 228 } 229 i = (off[1] < 0 ? off[1] + 15 : off[1]); /* fix red's home */ 230 if (oldr != i) { 231 fixpos(oldr, i, 3, 54, 1); 232 oldr = i; 233 } 234 move(r, c); /* return to saved position */ 235 refresh(); 236 } 237 238 239 void 240 fixpos(old, new, r, c, inc) 241 int old, new, r, c, inc; 242 { 243 int o, n, nv; 244 int ov, nc; 245 char col; 246 247 nc = 0; 248 if (old * new >= 0) { 249 ov = abs(old); 250 nv = abs(new); 251 col = (old + new > 0 ? 'r' : 'w'); 252 o = (ov - 1) / 5; 253 n = (nv - 1) / 5; 254 if (o == n) { 255 if (o == 2) 256 nc = c + 2; 257 if (o == 1) 258 nc = c < 54 ? c : c + 1; 259 if (o == 0) 260 nc = c < 54 ? c + 1 : c; 261 if (ov > nv) 262 fixcol(r + inc * (nv - n * 5), nc, abs(ov - nv), ' ', inc); 263 else 264 fixcol(r + inc * (ov - o * 5), nc, abs(ov - nv), col, inc); 265 return; 266 } else { 267 if (c < 54) { 268 if (o + n == 1) { 269 if (n) { 270 fixcol(r, c, abs(nv - 5), col, inc); 271 if (ov != 5) 272 fixcol(r+inc*ov, c+1, abs(ov-5), col, inc); 273 } else { 274 fixcol(r, c, abs(ov - 5), ' ', inc); 275 if (nv != 5) 276 fixcol(r+inc*nv, c+1, abs(nv-5), ' ', inc); 277 } 278 return; 279 } 280 if (n == 2) { 281 if (ov != 10) 282 fixcol(r+inc*(ov-5), c, abs(ov-10), col, inc); 283 fixcol(r, c + 2, abs(nv - 10), col, inc); 284 } else { 285 if (nv != 10) 286 fixcol(r+inc*(nv-5), c, abs(nv-10), ' ', inc); 287 fixcol(r, c + 2, abs(ov - 10), ' ', inc); 288 } 289 return; 290 } 291 if (n > o) { 292 fixcol(r+inc*(ov%5), c+o, abs(5*n-ov), col, inc); 293 if (nv != 5 * n) 294 fixcol(r, c+n, abs(5*n-nv), col, inc); 295 } else { 296 fixcol(r+inc*(nv%5), c+n, abs(5*n-nv), ' ', inc); 297 if (ov != 5 * o) 298 fixcol(r, c+o, abs(5*o-ov), ' ', inc); 299 } 300 return; 301 } 302 } 303 nv = abs(new); 304 fixcol(r, c + 1, nv, new > 0 ? 'r' : 'w', inc); 305 if (abs(old) <= abs(new)) 306 return; 307 fixcol(r + inc * new, c + 1, abs(old + new), ' ', inc); 308 } 309 310 void 311 fixcol(r, c, l, ch, inc) 312 int r, c, l, ch, inc; 313 { 314 int i; 315 316 mvaddch(r, c, ch); 317 for (i = 1; i < l; i++) { 318 r += inc; 319 mvaddch(r, c, ch); 320 } 321 } 322 323 324 void 325 initcurses() 326 { 327 initscr(); 328 cbreak(); 329 noecho(); 330 keypad(stdscr, TRUE); 331 nl(); 332 clear(); 333 334 if ((LINES < 24) || (COLS < 80)) { 335 endwin(); 336 errx(1, "screen must be at least 24x80."); 337 } 338 } 339