xref: /original-bsd/games/mille/misc.c (revision a4f2d92b)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)misc.c	5.2 (Berkeley) 12/29/87";
15 #endif /* not lint */
16 
17 #include	"mille.h"
18 #ifndef	unctrl
19 #include	"unctrl.h"
20 #endif
21 
22 # include	<sys/file.h>
23 
24 # ifdef	attron
25 #	include	<term.h>
26 #	define	_tty	cur_term->Nttyb
27 # endif	attron
28 
29 /*
30  * @(#)misc.c	1.2 (Berkeley) 3/28/83
31  */
32 
33 #define	NUMSAFE	4
34 
35 /* VARARGS1 */
36 error(str, arg)
37 char	*str;
38 {
39 	stdscr = Score;
40 	mvprintw(ERR_Y, ERR_X, str, arg);
41 	clrtoeol();
42 	putchar('');
43 	refresh();
44 	stdscr = Board;
45 	return FALSE;
46 }
47 
48 CARD
49 getcard()
50 {
51 	reg int		c, c1;
52 
53 	for (;;) {
54 		while ((c = readch()) == '\n' || c == '\r' || c == ' ')
55 			continue;
56 		if (islower(c))
57 			c = toupper(c);
58 		if (c == killchar() || c == erasechar())
59 			return -1;
60 		addstr(unctrl(c));
61 		clrtoeol();
62 		switch (c) {
63 		  case '1':	case '2':	case '3':
64 		  case '4':	case '5':	case '6':
65 			c -= '0';
66 			break;
67 		  case '0':	case 'P':	case 'p':
68 			c = 0;
69 			break;
70 		  default:
71 			putchar('');
72 			addch('\b');
73 			if (!isprint(c))
74 				addch('\b');
75 			c = -1;
76 			break;
77 		}
78 		refresh();
79 		if (c >= 0) {
80 			while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
81 				if (c1 == killchar())
82 					return -1;
83 				else if (c1 == erasechar()) {
84 					addch('\b');
85 					clrtoeol();
86 					refresh();
87 					goto cont;
88 				}
89 				else
90 					write(0, "", 1);
91 			return c;
92 		}
93 cont:		;
94 	}
95 }
96 
97 check_ext(forcomp)
98 reg bool	forcomp; {
99 
100 
101 	if (End == 700)
102 		if (Play == PLAYER) {
103 			if (getyn(EXTENSIONPROMPT)) {
104 extend:
105 				if (!forcomp)
106 					End = 1000;
107 				return TRUE;
108 			}
109 			else {
110 done:
111 				if (!forcomp)
112 					Finished = TRUE;
113 				return FALSE;
114 			}
115 		}
116 		else {
117 			reg PLAY	*pp, *op;
118 			reg int		i, safe, miles;
119 
120 			pp = &Player[COMP];
121 			op = &Player[PLAYER];
122 			for (safe = 0, i = 0; i < NUMSAFE; i++)
123 				if (pp->safety[i] != S_UNKNOWN)
124 					safe++;
125 			if (safe < 2)
126 				goto done;
127 			if (op->mileage == 0 || onecard(op)
128 			    || (op->can_go && op->mileage >= 500))
129 				goto done;
130 			for (miles = 0, i = 0; i < NUMSAFE; i++)
131 				if (op->safety[i] != S_PLAYED
132 				    && pp->safety[i] == S_UNKNOWN)
133 					miles++;
134 			if (miles + safe == NUMSAFE)
135 				goto extend;
136 			for (miles = 0, i = 0; i < HAND_SZ; i++)
137 				if ((safe = pp->hand[i]) <= C_200)
138 					miles += Value[safe];
139 			if (miles + (Topcard - Deck) * 3 > 1000)
140 				goto extend;
141 			goto done;
142 		}
143 	else
144 		goto done;
145 }
146 
147 /*
148  *	Get a yes or no answer to the given question.  Saves are
149  * also allowed.  Return TRUE if the answer was yes, FALSE if no.
150  */
151 getyn(promptno)
152 register int	promptno; {
153 
154 	reg char	c;
155 
156 	Saved = FALSE;
157 	for (;;) {
158 		leaveok(Board, FALSE);
159 		prompt(promptno);
160 		clrtoeol();
161 		refresh();
162 		switch (c = readch()) {
163 		  case 'n':	case 'N':
164 			addch('N');
165 			refresh();
166 			leaveok(Board, TRUE);
167 			return FALSE;
168 		  case 'y':	case 'Y':
169 			addch('Y');
170 			refresh();
171 			leaveok(Board, TRUE);
172 			return TRUE;
173 		  case 's':	case 'S':
174 			addch('S');
175 			refresh();
176 			Saved = save();
177 			continue;
178 		  default:
179 			addstr(unctrl(c));
180 			refresh();
181 			putchar('');
182 			break;
183 		}
184 	}
185 }
186 
187 /*
188  *	Check to see if more games are desired.  If not, and game
189  * came from a saved file, make sure that they don't want to restore
190  * it.  Exit appropriately.
191  */
192 check_more() {
193 
194 	flush_input();
195 
196 	On_exit = TRUE;
197 	if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
198 		if (getyn(ANOTHERGAMEPROMPT))
199 			return;
200 		else {
201 			/*
202 			 * must do accounting normally done in main()
203 			 */
204 			if (Player[PLAYER].total > Player[COMP].total)
205 				Player[PLAYER].games++;
206 			else if (Player[PLAYER].total < Player[COMP].total)
207 				Player[COMP].games++;
208 			Player[COMP].total = 0;
209 			Player[PLAYER].total = 0;
210 		}
211 	else
212 		if (getyn(ANOTHERHANDPROMPT))
213 			return;
214 	if (!Saved && getyn(SAVEGAMEPROMPT))
215 		if (!save())
216 			return;
217 	die();
218 }
219 
220 readch()
221 {
222 	reg int		cnt;
223 	static char	c;
224 
225 	for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
226 		if (cnt > 100)
227 			exit(1);
228 	return c;
229 }
230 
231 flush_input()
232 {
233 # ifdef	TIOCFLUSH
234 	static int	ioctl_args = FREAD;
235 
236 	(void) ioctl(fileno(stdin), TIOCFLUSH, &ioctl_args);
237 # else
238 	fflush(stdin);
239 # endif
240 }
241