Home | History | Annotate | Line # | Download | only in common_source
subs.c revision 1.18
      1 /*	$NetBSD: subs.c,v 1.18 2012/10/13 18:44:15 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.18 2012/10/13 18:44:15 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 	struct move *mm = &gm;
    159 
    160 	if (mm->d0)
    161 		mswap(mm);
    162 	if (cturn == 1)
    163 		writel("Red's roll:  ");
    164 	else
    165 		writel("White's roll:  ");
    166 	writec(mm->D0 + '0');
    167 	writec('\040');
    168 	writec(mm->D1 + '0');
    169 	if (tflag)
    170 		cline();
    171 }
    172 
    173 void
    174 wrint(int n)
    175 {
    176 	int     i, j, t;
    177 
    178 	for (i = 4; i > 0; i--) {
    179 		t = 1;
    180 		for (j = 0; j < i; j++)
    181 			t *= 10;
    182 		if (n > t - 1)
    183 			writec((n / t) % 10 + '0');
    184 	}
    185 	writec(n % 10 + '0');
    186 }
    187 
    188 void
    189 gwrite(void)
    190 {
    191 	int     r, c;
    192 
    193 	r = c = 0;
    194 	if (tflag) {
    195 		r = curr;
    196 		c = curc;
    197 		curmove(16, 0);
    198 	}
    199 	if (gvalue > 1) {
    200 		writel("Game value:  ");
    201 		wrint(gvalue);
    202 		writel(".  ");
    203 		if (dlast == -1)
    204 			writel(color[0]);
    205 		else
    206 			writel(color[1]);
    207 		writel(" doubled last.");
    208 	} else {
    209 		switch (pnum) {
    210 		case -1:	/* player is red */
    211 			writel(plred);
    212 			break;
    213 		case 0:	/* player is both colors */
    214 			writel(nocomp);
    215 			break;
    216 		case 1:	/* player is white */
    217 			writel(plwhite);
    218 		}
    219 	}
    220 
    221 	if (rscore || wscore) {
    222 		writel("  ");
    223 		wrscore();
    224 	}
    225 	if (tflag) {
    226 		cline();
    227 		curmove(r, c);
    228 	}
    229 }
    230 
    231 int
    232 quit(void)
    233 {
    234 
    235 	if (tflag) {
    236 		curmove(20, 0);
    237 		clend();
    238 	} else
    239 		writec('\n');
    240 	writel("Are you sure you want to quit?");
    241 	if (yorn(0)) {
    242 		if (rfl) {
    243 			writel("Would you like to save this game?");
    244 			if (yorn(0))
    245 				save(0);
    246 		}
    247 		cturn = 0;
    248 		return (1);
    249 	}
    250 	return (0);
    251 }
    252 
    253 int
    254 yorn(int special)
    255 {
    256 	char    c;
    257 	int     i;
    258 
    259 	i = 1;
    260 	while ((c = readc()) != 'Y' && c != 'N') {
    261 		if (special && c == special)
    262 			return (2);
    263 		if (i) {
    264 			if (special) {
    265 				writel("  (Y, N, or ");
    266 				writec(special);
    267 				writec(')');
    268 			} else
    269 				writel("  (Y or N)");
    270 			i = 0;
    271 		} else
    272 			writec('\007');
    273 	}
    274 	if (c == 'Y')
    275 		writel("  Yes.\n");
    276 	else
    277 		writel("  No.\n");
    278 	if (tflag)
    279 		buflush();
    280 	return (c == 'Y');
    281 }
    282 
    283 void
    284 wrhit(int i)
    285 {
    286 	writel("Blot hit on ");
    287 	wrint(i);
    288 	writec('.');
    289 	writec('\n');
    290 }
    291 
    292 void
    293 nexturn(void)
    294 {
    295 	int     c;
    296 
    297 	cturn = -cturn;
    298 	c = cturn / abs(cturn);
    299 	home = bar;
    300 	bar = 25 - bar;
    301 	offptr += c;
    302 	offopp -= c;
    303 	inptr += c;
    304 	inopp -= c;
    305 	Colorptr += c;
    306 	colorptr += c;
    307 }
    308 
    309 void
    310 getarg(char ***arg)
    311 {
    312 	char  **s;
    313 
    314 	/* process arguments here.  dashes are ignored, nbrw are ignored if
    315 	 * the game is being recovered */
    316 
    317 	s = *arg;
    318 	while (*s && s[0][0] == '-') {
    319 		switch (s[0][1]) {
    320 
    321 			/* don't ask if rules or instructions needed */
    322 		case 'n':
    323 			if (rflag)
    324 				break;
    325 			aflag = 0;
    326 			args[acnt++] = 'n';
    327 			break;
    328 
    329 			/* player is both red and white */
    330 		case 'b':
    331 			if (rflag)
    332 				break;
    333 			pnum = 0;
    334 			aflag = 0;
    335 			args[acnt++] = 'b';
    336 			break;
    337 
    338 			/* player is red */
    339 		case 'r':
    340 			if (rflag)
    341 				break;
    342 			pnum = -1;
    343 			aflag = 0;
    344 			args[acnt++] = 'r';
    345 			break;
    346 
    347 			/* player is white */
    348 		case 'w':
    349 			if (rflag)
    350 				break;
    351 			pnum = 1;
    352 			aflag = 0;
    353 			args[acnt++] = 'w';
    354 			break;
    355 
    356 			/* print board after move according to following
    357 			 * character */
    358 		case 'p':
    359 			if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
    360 				break;
    361 			args[acnt++] = 'p';
    362 			args[acnt++] = s[0][2];
    363 			if (s[0][2] == 'r')
    364 				bflag = 1;
    365 			if (s[0][2] == 'w')
    366 				bflag = -1;
    367 			if (s[0][2] == 'b')
    368 				bflag = 0;
    369 			break;
    370 
    371 		case 't':
    372 			if (s[0][2] == '\0') {	/* get terminal caps */
    373 				s++;
    374 				tflag = getcaps(*s);
    375 			} else
    376 				tflag = getcaps(&s[0][2]);
    377 			break;
    378 
    379 		case 's':
    380 			s++;
    381 			/* recover file */
    382 			if (s[0] == NULL) {
    383 				writel("No save file named\n");
    384 				getout(0);
    385 			} else
    386 				recover(s[0]);
    387 			break;
    388 		}
    389 		s++;
    390 	}
    391 	if (s[0] != 0)
    392 		recover(s[0]);
    393 }
    394 
    395 void
    396 init(void)
    397 {
    398 	int     i;
    399 
    400 	for (i = 0; i < 26;)
    401 		board[i++] = 0;
    402 	board[1] = 2;
    403 	board[6] = board[13] = -5;
    404 	board[8] = -3;
    405 	board[12] = board[19] = 5;
    406 	board[17] = 3;
    407 	board[24] = -2;
    408 	off[0] = off[1] = -15;
    409 	in[0] = in[1] = 5;
    410 	gvalue = 1;
    411 	dlast = 0;
    412 }
    413 
    414 void
    415 wrscore(void)
    416 {
    417 	writel("Score:  ");
    418 	writel(color[1]);
    419 	writec(' ');
    420 	wrint(rscore);
    421 	writel(", ");
    422 	writel(color[0]);
    423 	writec(' ');
    424 	wrint(wscore);
    425 }
    426 
    427 void
    428 fixtty(struct termios *t)
    429 {
    430 	if (tflag)
    431 		newpos();
    432 	buflush();
    433 	if (tcsetattr(0, TCSADRAIN, t) < 0)
    434 		errexit("fixtty");
    435 }
    436 
    437 void
    438 getout(int dummy __unused)
    439 {
    440 	/* go to bottom of screen */
    441 	if (tflag) {
    442 		curmove(23, 0);
    443 		cline();
    444 	} else
    445 		writec('\n');
    446 
    447 	/* fix terminal status */
    448 	fixtty(&old);
    449 	exit(0);
    450 }
    451 
    452 void
    453 roll(void)
    454 {
    455 	char    c;
    456 	int     row;
    457 	int     col;
    458 	struct move *mm = &gm;
    459 
    460 	row = col = 0;
    461 	if (iroll) {
    462 		if (tflag) {
    463 			row = curr;
    464 			col = curc;
    465 			curmove(17, 0);
    466 		} else
    467 			writec('\n');
    468 		writel("ROLL: ");
    469 		c = readc();
    470 		if (c != '\n') {
    471 			while (c < '1' || c > '6')
    472 				c = readc();
    473 			mm->D0 = c - '0';
    474 			writec(' ');
    475 			writec(c);
    476 			c = readc();
    477 			while (c < '1' || c > '6')
    478 				c = readc();
    479 			mm->D1 = c - '0';
    480 			writec(' ');
    481 			writec(c);
    482 			if (tflag) {
    483 				curmove(17, 0);
    484 				cline();
    485 				curmove(row, col);
    486 			} else
    487 				writec('\n');
    488 			return;
    489 		}
    490 		if (tflag) {
    491 			curmove(17, 0);
    492 			cline();
    493 			curmove(row, col);
    494 		} else
    495 			writec('\n');
    496 	}
    497 	mm->D0 = rnum(6) + 1;
    498 	mm->D1 = rnum(6) + 1;
    499 	mm->d0 = 0;
    500 }
    501