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