]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - mille/misc.c
This patch fixes adventure(6) to use `extern' on declarations of
[bsdgames-darwin.git] / mille / misc.c
1 /* $NetBSD: misc.c,v 1.8 1999/03/29 05:12:39 mrg Exp $ */
2
3 /*
4 * Copyright (c) 1983, 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. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: misc.c,v 1.8 1999/03/29 05:12:39 mrg Exp $");
42 #endif
43 #endif /* not lint */
44
45 #include <sys/file.h>
46 #include <termios.h>
47
48 #if __STDC__
49 #include <stdarg.h>
50 #else
51 #include <varargs.h>
52 #endif
53
54 #include "mille.h"
55 #ifndef unctrl
56 #include "unctrl.h"
57 #endif
58
59
60 /*
61 * @(#)misc.c 1.2 (Berkeley) 3/28/83
62 */
63
64 #define NUMSAFE 4
65
66 bool
67 #if __STDC__
68 error(const char *str, ...)
69 #else
70 error(str, va_alist)
71 const char *str;
72 va_dcl
73 #endif
74 {
75 va_list ap;
76
77 #if __STDC__
78 va_start(ap, str);
79 #else
80 va_start(ap);
81 #endif
82 wmove(Score, ERR_Y, ERR_X);
83 vwprintw(Score, str, ap);
84 clrtoeol();
85 putchar('\07');
86 refresh();
87 va_end(ap);
88 return FALSE;
89 }
90
91 CARD
92 getcard()
93 {
94 int c, c1;
95
96 for (;;) {
97 while ((c = readch()) == '\n' || c == '\r' || c == ' ')
98 continue;
99 if (islower(c))
100 c = toupper(c);
101 if (c == killchar() || c == erasechar())
102 return -1;
103 addstr(unctrl(c));
104 clrtoeol();
105 switch (c) {
106 case '1': case '2': case '3':
107 case '4': case '5': case '6':
108 c -= '0';
109 break;
110 case '0': case 'P': case 'p':
111 c = 0;
112 break;
113 default:
114 putchar('\07');
115 addch('\b');
116 if (!isprint(c))
117 addch('\b');
118 c = -1;
119 break;
120 }
121 refresh();
122 if (c >= 0) {
123 while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
124 if (c1 == killchar())
125 return -1;
126 else if (c1 == erasechar()) {
127 addch('\b');
128 clrtoeol();
129 refresh();
130 goto cont;
131 }
132 else
133 write(0, "\07", 1);
134 return c;
135 }
136 cont: ;
137 }
138 }
139
140 int
141 check_ext(forcomp)
142 bool forcomp;
143 {
144
145
146 if (End == 700)
147 if (Play == PLAYER) {
148 if (getyn(EXTENSIONPROMPT)) {
149 extend:
150 if (!forcomp)
151 End = 1000;
152 return TRUE;
153 }
154 else {
155 done:
156 if (!forcomp)
157 Finished = TRUE;
158 return FALSE;
159 }
160 }
161 else {
162 PLAY *pp, *op;
163 int i, safe, miles;
164
165 pp = &Player[COMP];
166 op = &Player[PLAYER];
167 for (safe = 0, i = 0; i < NUMSAFE; i++)
168 if (pp->safety[i] != S_UNKNOWN)
169 safe++;
170 if (safe < 2)
171 goto done;
172 if (op->mileage == 0 || onecard(op)
173 || (op->can_go && op->mileage >= 500))
174 goto done;
175 for (miles = 0, i = 0; i < NUMSAFE; i++)
176 if (op->safety[i] != S_PLAYED
177 && pp->safety[i] == S_UNKNOWN)
178 miles++;
179 if (miles + safe == NUMSAFE)
180 goto extend;
181 for (miles = 0, i = 0; i < HAND_SZ; i++)
182 if ((safe = pp->hand[i]) <= C_200)
183 miles += Value[safe];
184 if (miles + (Topcard - Deck) * 3 > 1000)
185 goto extend;
186 goto done;
187 }
188 else
189 goto done;
190 }
191
192 /*
193 * Get a yes or no answer to the given question. Saves are
194 * also allowed. Return TRUE if the answer was yes, FALSE if no.
195 */
196 int
197 getyn(promptno)
198 int promptno;
199 {
200 char c;
201
202 Saved = FALSE;
203 for (;;) {
204 leaveok(Board, FALSE);
205 prompt(promptno);
206 clrtoeol();
207 refresh();
208 switch (c = readch()) {
209 case 'n': case 'N':
210 addch('N');
211 refresh();
212 leaveok(Board, TRUE);
213 return FALSE;
214 case 'y': case 'Y':
215 addch('Y');
216 refresh();
217 leaveok(Board, TRUE);
218 return TRUE;
219 case 's': case 'S':
220 addch('S');
221 refresh();
222 Saved = save();
223 continue;
224 case CTRL('L'):
225 wrefresh(curscr);
226 break;
227 default:
228 addstr(unctrl(c));
229 refresh();
230 putchar('\07');
231 break;
232 }
233 }
234 }
235
236 /*
237 * Check to see if more games are desired. If not, and game
238 * came from a saved file, make sure that they don't want to restore
239 * it. Exit appropriately.
240 */
241 void
242 check_more()
243 {
244 On_exit = TRUE;
245 if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
246 if (getyn(ANOTHERGAMEPROMPT))
247 return;
248 else {
249 /*
250 * must do accounting normally done in main()
251 */
252 if (Player[PLAYER].total > Player[COMP].total)
253 Player[PLAYER].games++;
254 else if (Player[PLAYER].total < Player[COMP].total)
255 Player[COMP].games++;
256 Player[COMP].total = 0;
257 Player[PLAYER].total = 0;
258 }
259 else
260 if (getyn(ANOTHERHANDPROMPT))
261 return;
262 if (!Saved && getyn(SAVEGAMEPROMPT))
263 if (!save())
264 return;
265 die(0);
266 }
267
268 int
269 readch()
270 {
271 int cnt;
272 static char c;
273
274 for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
275 if (cnt > 100)
276 exit(1);
277 return c;
278 }