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