HAMMER: MFC all changes through 20080924
[dragonfly.git] / games / mille / misc.c
blob7f02f6d1c1eb9e91bf889add22830a8ec5ce6bc7
1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
33 * @(#)misc.c 8.1 (Berkeley) 5/31/93
34 * $FreeBSD: src/games/mille/misc.c,v 1.8.2.1 2001/06/13 13:52:14 dwmalone Exp $
35 * $DragonFly: src/games/mille/misc.c,v 1.4 2006/08/27 17:17:23 pavalos Exp $
38 #include <sys/file.h>
39 #include <stdarg.h>
40 #include <termios.h>
42 #include "mille.h"
45 # ifdef attron
46 # include <term.h>
47 # define _tty cur_term->Nttyb
48 # endif /* attron */
51 * @(#)misc.c 1.2 (Berkeley) 3/28/83
54 #define NUMSAFE 4
56 /* VARARGS1 */
57 bool
58 error(const char *str, ...)
60 va_list arg;
62 va_start(arg, str);
63 stdscr = Score;
64 move(ERR_Y, ERR_X);
65 vw_printw(stdscr, str, arg);
66 va_end(arg);
67 clrtoeol();
68 putchar('\07');
69 refresh();
70 stdscr = Board;
71 return FALSE;
74 CARD
75 getcard(void)
77 int c, c1;
79 for (;;) {
80 while ((c = readch()) == '\n' || c == '\r' || c == ' ')
81 continue;
82 if (islower(c))
83 c = toupper(c);
84 if (c == killchar() || c == erasechar())
85 return -1;
86 addstr(unctrl(c));
87 clrtoeol();
88 switch (c) {
89 case '1': case '2': case '3':
90 case '4': case '5': case '6':
91 c -= '0';
92 break;
93 case '0': case 'P': case 'p':
94 c = 0;
95 break;
96 default:
97 putchar('\07');
98 addch('\b');
99 if (!isprint(c))
100 addch('\b');
101 c = -1;
102 break;
104 refresh();
105 if (c >= 0) {
106 while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
107 if (c1 == killchar())
108 return -1;
109 else if (c1 == erasechar()) {
110 addch('\b');
111 clrtoeol();
112 refresh();
113 goto cont;
115 else
116 write(0, "\07", 1);
117 return c;
119 cont: ;
123 bool
124 check_ext(bool forcomp)
128 if (End == 700)
129 if (Play == PLAYER) {
130 if (getyn(EXTENSIONPROMPT)) {
131 extend:
132 if (!forcomp)
133 End = 1000;
134 return TRUE;
136 else {
137 done:
138 if (!forcomp)
139 Finished = TRUE;
140 return FALSE;
143 else {
144 PLAY *pp, *op;
145 int i, safe, miles;
147 pp = &Player[COMP];
148 op = &Player[PLAYER];
149 for (safe = 0, i = 0; i < NUMSAFE; i++)
150 if (pp->safety[i] != S_UNKNOWN)
151 safe++;
152 if (safe < 2)
153 goto done;
154 if (op->mileage == 0 || onecard(op)
155 || (op->can_go && op->mileage >= 500))
156 goto done;
157 for (miles = 0, i = 0; i < NUMSAFE; i++)
158 if (op->safety[i] != S_PLAYED
159 && pp->safety[i] == S_UNKNOWN)
160 miles++;
161 if (miles + safe == NUMSAFE)
162 goto extend;
163 for (miles = 0, i = 0; i < HAND_SZ; i++)
164 if ((safe = pp->hand[i]) <= C_200)
165 miles += Value[safe];
166 if (miles + (Topcard - Deck) * 3 > 1000)
167 goto extend;
168 goto done;
170 else
171 goto done;
175 * Get a yes or no answer to the given question. Saves are
176 * also allowed. Return TRUE if the answer was yes, FALSE if no.
178 bool
179 getyn(int promptno)
182 char c;
184 Saved = FALSE;
185 for (;;) {
186 leaveok(Board, FALSE);
187 prompt(promptno);
188 clrtoeol();
189 refresh();
190 switch (c = readch()) {
191 case 'n': case 'N':
192 addch('N');
193 refresh();
194 leaveok(Board, TRUE);
195 return FALSE;
196 case 'y': case 'Y':
197 addch('Y');
198 refresh();
199 leaveok(Board, TRUE);
200 return TRUE;
201 case 's': case 'S':
202 addch('S');
203 refresh();
204 Saved = save();
205 continue;
206 case CTRL('L'):
207 wrefresh(curscr);
208 break;
209 default:
210 addstr(unctrl(c));
211 refresh();
212 putchar('\07');
213 break;
219 * Check to see if more games are desired. If not, and game
220 * came from a saved file, make sure that they don't want to restore
221 * it. Exit appropriately.
223 void
224 check_more(void)
227 On_exit = TRUE;
228 if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
229 if (getyn(ANOTHERGAMEPROMPT))
230 return;
231 else {
233 * must do accounting normally done in main()
235 if (Player[PLAYER].total > Player[COMP].total)
236 Player[PLAYER].games++;
237 else if (Player[PLAYER].total < Player[COMP].total)
238 Player[COMP].games++;
239 Player[COMP].total = 0;
240 Player[PLAYER].total = 0;
242 else
243 if (getyn(ANOTHERHANDPROMPT))
244 return;
245 if (!Saved && getyn(SAVEGAMEPROMPT))
246 if (!save())
247 return;
248 die(0);
251 char
252 readch(void)
254 int cnt;
255 static char c;
257 for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
258 if (cnt > 100)
259 exit(1);
260 return c;