xref: /original-bsd/games/mille/misc.c (revision 16bc4816)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)misc.c	5.8 (Berkeley) 08/31/92";
10 #endif /* not lint */
11 
12 #include <sys/file.h>
13 #include <termios.h>
14 
15 #include	"mille.h"
16 #ifndef	unctrl
17 #include	"unctrl.h"
18 #endif
19 
20 
21 # ifdef	attron
22 #	include	<term.h>
23 #	define	_tty	cur_term->Nttyb
24 # endif	attron
25 
26 /*
27  * @(#)misc.c	1.2 (Berkeley) 3/28/83
28  */
29 
30 #define	NUMSAFE	4
31 
32 /* VARARGS1 */
33 error(str, arg)
34 char	*str;
35 {
36 	stdscr = Score;
37 	mvprintw(ERR_Y, ERR_X, str, arg);
38 	clrtoeol();
39 	putchar('\07');
40 	refresh();
41 	stdscr = Board;
42 	return FALSE;
43 }
44 
45 CARD
46 getcard()
47 {
48 	reg int		c, c1;
49 
50 	for (;;) {
51 		while ((c = readch()) == '\n' || c == '\r' || c == ' ')
52 			continue;
53 		if (islower(c))
54 			c = toupper(c);
55 		if (c == killchar() || c == erasechar())
56 			return -1;
57 		addstr(unctrl(c));
58 		clrtoeol();
59 		switch (c) {
60 		  case '1':	case '2':	case '3':
61 		  case '4':	case '5':	case '6':
62 			c -= '0';
63 			break;
64 		  case '0':	case 'P':	case 'p':
65 			c = 0;
66 			break;
67 		  default:
68 			putchar('\07');
69 			addch('\b');
70 			if (!isprint(c))
71 				addch('\b');
72 			c = -1;
73 			break;
74 		}
75 		refresh();
76 		if (c >= 0) {
77 			while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
78 				if (c1 == killchar())
79 					return -1;
80 				else if (c1 == erasechar()) {
81 					addch('\b');
82 					clrtoeol();
83 					refresh();
84 					goto cont;
85 				}
86 				else
87 					write(0, "\07", 1);
88 			return c;
89 		}
90 cont:		;
91 	}
92 }
93 
94 check_ext(forcomp)
95 reg bool	forcomp; {
96 
97 
98 	if (End == 700)
99 		if (Play == PLAYER) {
100 			if (getyn(EXTENSIONPROMPT)) {
101 extend:
102 				if (!forcomp)
103 					End = 1000;
104 				return TRUE;
105 			}
106 			else {
107 done:
108 				if (!forcomp)
109 					Finished = TRUE;
110 				return FALSE;
111 			}
112 		}
113 		else {
114 			reg PLAY	*pp, *op;
115 			reg int		i, safe, miles;
116 
117 			pp = &Player[COMP];
118 			op = &Player[PLAYER];
119 			for (safe = 0, i = 0; i < NUMSAFE; i++)
120 				if (pp->safety[i] != S_UNKNOWN)
121 					safe++;
122 			if (safe < 2)
123 				goto done;
124 			if (op->mileage == 0 || onecard(op)
125 			    || (op->can_go && op->mileage >= 500))
126 				goto done;
127 			for (miles = 0, i = 0; i < NUMSAFE; i++)
128 				if (op->safety[i] != S_PLAYED
129 				    && pp->safety[i] == S_UNKNOWN)
130 					miles++;
131 			if (miles + safe == NUMSAFE)
132 				goto extend;
133 			for (miles = 0, i = 0; i < HAND_SZ; i++)
134 				if ((safe = pp->hand[i]) <= C_200)
135 					miles += Value[safe];
136 			if (miles + (Topcard - Deck) * 3 > 1000)
137 				goto extend;
138 			goto done;
139 		}
140 	else
141 		goto done;
142 }
143 
144 /*
145  *	Get a yes or no answer to the given question.  Saves are
146  * also allowed.  Return TRUE if the answer was yes, FALSE if no.
147  */
148 getyn(promptno)
149 register int	promptno; {
150 
151 	reg char	c;
152 
153 	Saved = FALSE;
154 	for (;;) {
155 		leaveok(Board, FALSE);
156 		prompt(promptno);
157 		clrtoeol();
158 		refresh();
159 		switch (c = readch()) {
160 		  case 'n':	case 'N':
161 			addch('N');
162 			refresh();
163 			leaveok(Board, TRUE);
164 			return FALSE;
165 		  case 'y':	case 'Y':
166 			addch('Y');
167 			refresh();
168 			leaveok(Board, TRUE);
169 			return TRUE;
170 		  case 's':	case 'S':
171 			addch('S');
172 			refresh();
173 			Saved = save();
174 			continue;
175 		  case CTRL('L'):
176 			wrefresh(curscr);
177 			break;
178 		  default:
179 			addstr(unctrl(c));
180 			refresh();
181 			putchar('\07');
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 	On_exit = TRUE;
195 	if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
196 		if (getyn(ANOTHERGAMEPROMPT))
197 			return;
198 		else {
199 			/*
200 			 * must do accounting normally done in main()
201 			 */
202 			if (Player[PLAYER].total > Player[COMP].total)
203 				Player[PLAYER].games++;
204 			else if (Player[PLAYER].total < Player[COMP].total)
205 				Player[COMP].games++;
206 			Player[COMP].total = 0;
207 			Player[PLAYER].total = 0;
208 		}
209 	else
210 		if (getyn(ANOTHERHANDPROMPT))
211 			return;
212 	if (!Saved && getyn(SAVEGAMEPROMPT))
213 		if (!save())
214 			return;
215 	die(0);
216 }
217 
218 readch()
219 {
220 	reg int		cnt;
221 	static char	c;
222 
223 	for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
224 		if (cnt > 100)
225 			exit(1);
226 	return c;
227 }
228