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 } 279