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