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