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