1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 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. 20 * 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. 32 * 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 $ 36 */ 37 38 #include <sys/file.h> 39 #include <stdarg.h> 40 #include <termios.h> 41 42 #include "mille.h" 43 #include <term.h> 44 45 /* 46 * @(#)misc.c 1.2 (Berkeley) 3/28/83 47 */ 48 49 #define NUMSAFE 4 50 51 /* VARARGS1 */ 52 bool 53 error(const char *str, ...) 54 { 55 va_list arg; 56 57 va_start(arg, str); 58 stdscr = Score; 59 move(ERR_Y, ERR_X); 60 vw_printw(stdscr, str, arg); 61 va_end(arg); 62 clrtoeol(); 63 putchar('\07'); 64 refresh(); 65 stdscr = Board; 66 return FALSE; 67 } 68 69 CARD 70 getcard(void) 71 { 72 int c, c1; 73 74 for (;;) { 75 while ((c = readch()) == '\n' || c == '\r' || c == ' ') 76 continue; 77 if (islower(c)) 78 c = toupper(c); 79 if (c == killchar() || c == erasechar()) 80 return -1; 81 addstr(unctrl(c)); 82 clrtoeol(); 83 switch (c) { 84 case '1': case '2': case '3': 85 case '4': case '5': case '6': 86 c -= '0'; 87 break; 88 case '0': case 'P': case 'p': 89 c = 0; 90 break; 91 default: 92 putchar('\07'); 93 addch('\b'); 94 if (!isprint(c)) 95 addch('\b'); 96 c = -1; 97 break; 98 } 99 refresh(); 100 if (c >= 0) { 101 while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ') 102 if (c1 == killchar()) 103 return -1; 104 else if (c1 == erasechar()) { 105 addch('\b'); 106 clrtoeol(); 107 refresh(); 108 goto cont; 109 } 110 else 111 write(0, "\07", 1); 112 return c; 113 } 114 cont: ; 115 } 116 } 117 118 bool 119 check_ext(bool forcomp) 120 { 121 122 123 if (End == 700) 124 if (Play == PLAYER) { 125 if (getyn(EXTENSIONPROMPT)) { 126 extend: 127 if (!forcomp) 128 End = 1000; 129 return TRUE; 130 } 131 else { 132 done: 133 if (!forcomp) 134 Finished = TRUE; 135 return FALSE; 136 } 137 } 138 else { 139 PLAY *pp, *op; 140 int i, safe, miles; 141 142 pp = &Player[COMP]; 143 op = &Player[PLAYER]; 144 for (safe = 0, i = 0; i < NUMSAFE; i++) 145 if (pp->safety[i] != S_UNKNOWN) 146 safe++; 147 if (safe < 2) 148 goto done; 149 if (op->mileage == 0 || onecard(op) 150 || (op->can_go && op->mileage >= 500)) 151 goto done; 152 for (miles = 0, i = 0; i < NUMSAFE; i++) 153 if (op->safety[i] != S_PLAYED 154 && pp->safety[i] == S_UNKNOWN) 155 miles++; 156 if (miles + safe == NUMSAFE) 157 goto extend; 158 for (miles = 0, i = 0; i < HAND_SZ; i++) 159 if ((safe = pp->hand[i]) <= C_200) 160 miles += Value[safe]; 161 if (miles + (Topcard - Deck) * 3 > 1000) 162 goto extend; 163 goto done; 164 } 165 else 166 goto done; 167 } 168 169 /* 170 * Get a yes or no answer to the given question. Saves are 171 * also allowed. Return TRUE if the answer was yes, FALSE if no. 172 */ 173 bool 174 getyn(int promptno) 175 { 176 177 char c; 178 179 Saved = FALSE; 180 for (;;) { 181 leaveok(Board, FALSE); 182 prompt(promptno); 183 clrtoeol(); 184 refresh(); 185 switch (c = readch()) { 186 case 'n': case 'N': 187 addch('N'); 188 refresh(); 189 leaveok(Board, TRUE); 190 return FALSE; 191 case 'y': case 'Y': 192 addch('Y'); 193 refresh(); 194 leaveok(Board, TRUE); 195 return TRUE; 196 case 's': case 'S': 197 addch('S'); 198 refresh(); 199 Saved = save(); 200 continue; 201 case CTRL('L'): 202 wrefresh(curscr); 203 break; 204 default: 205 addstr(unctrl(c)); 206 refresh(); 207 putchar('\07'); 208 break; 209 } 210 } 211 } 212 213 /* 214 * Check to see if more games are desired. If not, and game 215 * came from a saved file, make sure that they don't want to restore 216 * it. Exit appropriately. 217 */ 218 void 219 check_more(void) 220 { 221 222 On_exit = TRUE; 223 if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000) 224 if (getyn(ANOTHERGAMEPROMPT)) 225 return; 226 else { 227 /* 228 * must do accounting normally done in main() 229 */ 230 if (Player[PLAYER].total > Player[COMP].total) 231 Player[PLAYER].games++; 232 else if (Player[PLAYER].total < Player[COMP].total) 233 Player[COMP].games++; 234 Player[COMP].total = 0; 235 Player[PLAYER].total = 0; 236 } 237 else 238 if (getyn(ANOTHERHANDPROMPT)) 239 return; 240 if (!Saved && getyn(SAVEGAMEPROMPT)) 241 if (!save()) 242 return; 243 die(0); 244 } 245 246 char 247 readch(void) 248 { 249 int cnt; 250 static char c; 251 252 for (cnt = 0; read(0, &c, 1) <= 0; cnt++) 253 if (cnt > 100) 254 exit(1); 255 return c; 256 } 257