Home | History | Annotate | Line # | Download | only in common_source
subs.c revision 1.17
      1 /*	$NetBSD: subs.c,v 1.17 2009/08/12 05:17:57 dholland 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. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)subs.c	8.1 (Berkeley) 5/31/93";
     36 #else
     37 __RCSID("$NetBSD: subs.c,v 1.17 2009/08/12 05:17:57 dholland Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include "back.h"
     42 
     43 int     buffnum;
     44 static char outbuff[BUFSIZ];
     45 
     46 static const char plred[] = "Player is red, computer is white.";
     47 static const char plwhite[] = "Player is white, computer is red.";
     48 static const char nocomp[] = "(No computer play.)";
     49 
     50 static const char *const descr[] = {
     51 	"Usage:  backgammon [-] [n r w b pr pw pb t3a]\n",
     52 	"\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
     53 	"\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
     54 	"\tb\ttwo players, red and white (implies n)",
     55 	"\tpr\tprint the board before red's turn",
     56 	"\tpw\tprint the board before white's turn",
     57 	"\tpb\tprint the board before both player's turn",
     58 	"\tterm\tterminal is a term",
     59 	"\tsfile\trecover saved game from file",
     60 	0
     61 };
     62 
     63 void
     64 errexit(const char *s)
     65 {
     66 	write(2, "\n", 1);
     67 	perror(s);
     68 	getout(0);
     69 }
     70 
     71 int
     72 addbuf(int c)
     73 {
     74 	buffnum++;
     75 	if (buffnum == BUFSIZ) {
     76 		if (write(1, outbuff, BUFSIZ) != BUFSIZ)
     77 			errexit("addbuf (write):");
     78 		buffnum = 0;
     79 	}
     80 	outbuff[buffnum] = c;
     81 	return (0);
     82 }
     83 
     84 void
     85 buflush(void)
     86 {
     87 	if (buffnum < 0)
     88 		return;
     89 	buffnum++;
     90 	if (write(1, outbuff, buffnum) != buffnum)
     91 		errexit("buflush (write):");
     92 	buffnum = -1;
     93 }
     94 
     95 int
     96 readc(void)
     97 {
     98 	char    c;
     99 
    100 	if (tflag) {
    101 		cline();
    102 		newpos();
    103 	}
    104 	buflush();
    105 	if (read(0, &c, 1) != 1)
    106 		errexit("readc");
    107 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
    108 	if (c == '\177')
    109 		getout(0);
    110 #endif
    111 	if (c == '\033' || c == '\015')
    112 		return ('\n');
    113 	if (cflag)
    114 		return (c);
    115 	if (c == '\014')
    116 		return ('R');
    117 	if (c >= 'a' && c <= 'z')
    118 		return (c & 0137);
    119 	return (c);
    120 }
    121 
    122 void
    123 writec(int c)
    124 {
    125 	if (tflag)
    126 		fancyc(c);
    127 	else
    128 		addbuf(c);
    129 }
    130 
    131 void
    132 writel(const char *l)
    133 {
    134 #ifdef DEBUG
    135 	const char   *s;
    136 
    137 	if (trace == NULL)
    138 		trace = fopen("bgtrace", "w");
    139 
    140 	fprintf(trace, "writel: \"");
    141 	for (s = l; *s; s++) {
    142 		if (*s < ' ' || *s == '\177')
    143 			fprintf(trace, "^%c", (*s) ^ 0100);
    144 		else
    145 			putc(*s, trace);
    146 	}
    147 	fprintf(trace, "\"\n");
    148 	fflush(trace);
    149 #endif
    150 
    151 	while (*l)
    152 		writec(*l++);
    153 }
    154 
    155 void
    156 proll(void)
    157 {
    158 	if (d0)
    159 		swap;
    160 	if (cturn == 1)
    161 		writel("Red's roll:  ");
    162 	else
    163 		writel("White's roll:  ");
    164 	writec(D0 + '0');
    165 	writec('\040');
    166 	writec(D1 + '0');
    167 	if (tflag)
    168 		cline();
    169 }
    170 
    171 void
    172 wrint(int n)
    173 {
    174 	int     i, j, t;
    175 
    176 	for (i = 4; i > 0; i--) {
    177 		t = 1;
    178 		for (j = 0; j < i; j++)
    179 			t *= 10;
    180 		if (n > t - 1)
    181 			writec((n / t) % 10 + '0');
    182 	}
    183 	writec(n % 10 + '0');
    184 }
    185 
    186 void
    187 gwrite(void)
    188 {
    189 	int     r, c;
    190 
    191 	r = c = 0;
    192 	if (tflag) {
    193 		r = curr;
    194 		c = curc;
    195 		curmove(16, 0);
    196 	}
    197 	if (gvalue > 1) {
    198 		writel("Game value:  ");
    199 		wrint(gvalue);
    200 		writel(".  ");
    201 		if (dlast == -1)
    202 			writel(color[0]);
    203 		else
    204 			writel(color[1]);
    205 		writel(" doubled last.");
    206 	} else {
    207 		switch (pnum) {
    208 		case -1:	/* player is red */
    209 			writel(plred);
    210 			break;
    211 		case 0:	/* player is both colors */
    212 			writel(nocomp);
    213 			break;
    214 		case 1:	/* player is white */
    215 			writel(plwhite);
    216 		}
    217 	}
    218 
    219 	if (rscore || wscore) {
    220 		writel("  ");
    221 		wrscore();
    222 	}
    223 	if (tflag) {
    224 		cline();
    225 		curmove(r, c);
    226 	}
    227 }
    228 
    229 int
    230 quit(void)
    231 {
    232 
    233 	if (tflag) {
    234 		curmove(20, 0);
    235 		clend();
    236 	} else
    237 		writec('\n');
    238 	writel("Are you sure you want to quit?");
    239 	if (yorn(0)) {
    240 		if (rfl) {
    241 			writel("Would you like to save this game?");
    242 			if (yorn(0))
    243 				save(0);
    244 		}
    245 		cturn = 0;
    246 		return (1);
    247 	}
    248 	return (0);
    249 }
    250 
    251 int
    252 yorn(int special)
    253 {
    254 	char    c;
    255 	int     i;
    256 
    257 	i = 1;
    258 	while ((c = readc()) != 'Y' && c != 'N') {
    259 		if (special && c == special)
    260 			return (2);
    261 		if (i) {
    262 			if (special) {
    263 				writel("  (Y, N, or ");
    264 				writec(special);
    265 				writec(')');
    266 			} else
    267 				writel("  (Y or N)");
    268 			i = 0;
    269 		} else
    270 			writec('\007');
    271 	}
    272 	if (c == 'Y')
    273 		writel("  Yes.\n");
    274 	else
    275 		writel("  No.\n");
    276 	if (tflag)
    277 		buflush();
    278 	return (c == 'Y');
    279 }
    280 
    281 void
    282 wrhit(int i)
    283 {
    284 	writel("Blot hit on ");
    285 	wrint(i);
    286 	writec('.');
    287 	writec('\n');
    288 }
    289 
    290 void
    291 nexturn(void)
    292 {
    293 	int     c;
    294 
    295 	cturn = -cturn;
    296 	c = cturn / abs(cturn);
    297 	home = bar;
    298 	bar = 25 - bar;
    299 	offptr += c;
    300 	offopp -= c;
    301 	inptr += c;
    302 	inopp -= c;
    303 	Colorptr += c;
    304 	colorptr += c;
    305 }
    306 
    307 void
    308 getarg(char ***arg)
    309 {
    310 	char  **s;
    311 
    312 	/* process arguments here.  dashes are ignored, nbrw are ignored if
    313 	 * the game is being recovered */
    314 
    315 	s = *arg;
    316 	while (*s && s[0][0] == '-') {
    317 		switch (s[0][1]) {
    318 
    319 			/* don't ask if rules or instructions needed */
    320 		case 'n':
    321 			if (rflag)
    322 				break;
    323 			aflag = 0;
    324 			args[acnt++] = 'n';
    325 			break;
    326 
    327 			/* player is both red and white */
    328 		case 'b':
    329 			if (rflag)
    330 				break;
    331 			pnum = 0;
    332 			aflag = 0;
    333 			args[acnt++] = 'b';
    334 			break;
    335 
    336 			/* player is red */
    337 		case 'r':
    338 			if (rflag)
    339 				break;
    340 			pnum = -1;
    341 			aflag = 0;
    342 			args[acnt++] = 'r';
    343 			break;
    344 
    345 			/* player is white */
    346 		case 'w':
    347 			if (rflag)
    348 				break;
    349 			pnum = 1;
    350 			aflag = 0;
    351 			args[acnt++] = 'w';
    352 			break;
    353 
    354 			/* print board after move according to following
    355 			 * character */
    356 		case 'p':
    357 			if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
    358 				break;
    359 			args[acnt++] = 'p';
    360 			args[acnt++] = s[0][2];
    361 			if (s[0][2] == 'r')
    362 				bflag = 1;
    363 			if (s[0][2] == 'w')
    364 				bflag = -1;
    365 			if (s[0][2] == 'b')
    366 				bflag = 0;
    367 			break;
    368 
    369 		case 't':
    370 			if (s[0][2] == '\0') {	/* get terminal caps */
    371 				s++;
    372 				tflag = getcaps(*s);
    373 			} else
    374 				tflag = getcaps(&s[0][2]);
    375 			break;
    376 
    377 		case 's':
    378 			s++;
    379 			/* recover file */
    380 			if (s[0] == NULL) {
    381 				writel("No save file named\n");
    382 				getout(0);
    383 			} else
    384 				recover(s[0]);
    385 			break;
    386 		}
    387 		s++;
    388 	}
    389 	if (s[0] != 0)
    390 		recover(s[0]);
    391 }
    392 
    393 void
    394 init(void)
    395 {
    396 	int     i;
    397 
    398 	for (i = 0; i < 26;)
    399 		board[i++] = 0;
    400 	board[1] = 2;
    401 	board[6] = board[13] = -5;
    402 	board[8] = -3;
    403 	board[12] = board[19] = 5;
    404 	board[17] = 3;
    405 	board[24] = -2;
    406 	off[0] = off[1] = -15;
    407 	in[0] = in[1] = 5;
    408 	gvalue = 1;
    409 	dlast = 0;
    410 }
    411 
    412 void
    413 wrscore(void)
    414 {
    415 	writel("Score:  ");
    416 	writel(color[1]);
    417 	writec(' ');
    418 	wrint(rscore);
    419 	writel(", ");
    420 	writel(color[0]);
    421 	writec(' ');
    422 	wrint(wscore);
    423 }
    424 
    425 void
    426 fixtty(struct termios *t)
    427 {
    428 	if (tflag)
    429 		newpos();
    430 	buflush();
    431 	if (tcsetattr(0, TCSADRAIN, t) < 0)
    432 		errexit("fixtty");
    433 }
    434 
    435 void
    436 getout(int dummy __unused)
    437 {
    438 	/* go to bottom of screen */
    439 	if (tflag) {
    440 		curmove(23, 0);
    441 		cline();
    442 	} else
    443 		writec('\n');
    444 
    445 	/* fix terminal status */
    446 	fixtty(&old);
    447 	exit(0);
    448 }
    449 
    450 void
    451 roll(void)
    452 {
    453 	char    c;
    454 	int     row;
    455 	int     col;
    456 
    457 	row = col = 0;
    458 	if (iroll) {
    459 		if (tflag) {
    460 			row = curr;
    461 			col = curc;
    462 			curmove(17, 0);
    463 		} else
    464 			writec('\n');
    465 		writel("ROLL: ");
    466 		c = readc();
    467 		if (c != '\n') {
    468 			while (c < '1' || c > '6')
    469 				c = readc();
    470 			D0 = c - '0';
    471 			writec(' ');
    472 			writec(c);
    473 			c = readc();
    474 			while (c < '1' || c > '6')
    475 				c = readc();
    476 			D1 = c - '0';
    477 			writec(' ');
    478 			writec(c);
    479 			if (tflag) {
    480 				curmove(17, 0);
    481 				cline();
    482 				curmove(row, col);
    483 			} else
    484 				writec('\n');
    485 			return;
    486 		}
    487 		if (tflag) {
    488 			curmove(17, 0);
    489 			cline();
    490 			curmove(row, col);
    491 		} else
    492 			writec('\n');
    493 	}
    494 	D0 = rnum(6) + 1;
    495 	D1 = rnum(6) + 1;
    496 	d0 = 0;
    497 }
    498