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