1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)misc.c 5.2 (Berkeley) 12/29/87"; 15 #endif /* not lint */ 16 17 #include "mille.h" 18 #ifndef unctrl 19 #include "unctrl.h" 20 #endif 21 22 # include <sys/file.h> 23 24 # ifdef attron 25 # include <term.h> 26 # define _tty cur_term->Nttyb 27 # endif attron 28 29 /* 30 * @(#)misc.c 1.2 (Berkeley) 3/28/83 31 */ 32 33 #define NUMSAFE 4 34 35 /* VARARGS1 */ 36 error(str, arg) 37 char *str; 38 { 39 stdscr = Score; 40 mvprintw(ERR_Y, ERR_X, str, arg); 41 clrtoeol(); 42 putchar(''); 43 refresh(); 44 stdscr = Board; 45 return FALSE; 46 } 47 48 CARD 49 getcard() 50 { 51 reg int c, c1; 52 53 for (;;) { 54 while ((c = readch()) == '\n' || c == '\r' || c == ' ') 55 continue; 56 if (islower(c)) 57 c = toupper(c); 58 if (c == killchar() || c == erasechar()) 59 return -1; 60 addstr(unctrl(c)); 61 clrtoeol(); 62 switch (c) { 63 case '1': case '2': case '3': 64 case '4': case '5': case '6': 65 c -= '0'; 66 break; 67 case '0': case 'P': case 'p': 68 c = 0; 69 break; 70 default: 71 putchar(''); 72 addch('\b'); 73 if (!isprint(c)) 74 addch('\b'); 75 c = -1; 76 break; 77 } 78 refresh(); 79 if (c >= 0) { 80 while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ') 81 if (c1 == killchar()) 82 return -1; 83 else if (c1 == erasechar()) { 84 addch('\b'); 85 clrtoeol(); 86 refresh(); 87 goto cont; 88 } 89 else 90 write(0, "", 1); 91 return c; 92 } 93 cont: ; 94 } 95 } 96 97 check_ext(forcomp) 98 reg bool forcomp; { 99 100 101 if (End == 700) 102 if (Play == PLAYER) { 103 if (getyn(EXTENSIONPROMPT)) { 104 extend: 105 if (!forcomp) 106 End = 1000; 107 return TRUE; 108 } 109 else { 110 done: 111 if (!forcomp) 112 Finished = TRUE; 113 return FALSE; 114 } 115 } 116 else { 117 reg PLAY *pp, *op; 118 reg int i, safe, miles; 119 120 pp = &Player[COMP]; 121 op = &Player[PLAYER]; 122 for (safe = 0, i = 0; i < NUMSAFE; i++) 123 if (pp->safety[i] != S_UNKNOWN) 124 safe++; 125 if (safe < 2) 126 goto done; 127 if (op->mileage == 0 || onecard(op) 128 || (op->can_go && op->mileage >= 500)) 129 goto done; 130 for (miles = 0, i = 0; i < NUMSAFE; i++) 131 if (op->safety[i] != S_PLAYED 132 && pp->safety[i] == S_UNKNOWN) 133 miles++; 134 if (miles + safe == NUMSAFE) 135 goto extend; 136 for (miles = 0, i = 0; i < HAND_SZ; i++) 137 if ((safe = pp->hand[i]) <= C_200) 138 miles += Value[safe]; 139 if (miles + (Topcard - Deck) * 3 > 1000) 140 goto extend; 141 goto done; 142 } 143 else 144 goto done; 145 } 146 147 /* 148 * Get a yes or no answer to the given question. Saves are 149 * also allowed. Return TRUE if the answer was yes, FALSE if no. 150 */ 151 getyn(promptno) 152 register int promptno; { 153 154 reg char c; 155 156 Saved = FALSE; 157 for (;;) { 158 leaveok(Board, FALSE); 159 prompt(promptno); 160 clrtoeol(); 161 refresh(); 162 switch (c = readch()) { 163 case 'n': case 'N': 164 addch('N'); 165 refresh(); 166 leaveok(Board, TRUE); 167 return FALSE; 168 case 'y': case 'Y': 169 addch('Y'); 170 refresh(); 171 leaveok(Board, TRUE); 172 return TRUE; 173 case 's': case 'S': 174 addch('S'); 175 refresh(); 176 Saved = save(); 177 continue; 178 default: 179 addstr(unctrl(c)); 180 refresh(); 181 putchar(''); 182 break; 183 } 184 } 185 } 186 187 /* 188 * Check to see if more games are desired. If not, and game 189 * came from a saved file, make sure that they don't want to restore 190 * it. Exit appropriately. 191 */ 192 check_more() { 193 194 flush_input(); 195 196 On_exit = TRUE; 197 if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000) 198 if (getyn(ANOTHERGAMEPROMPT)) 199 return; 200 else { 201 /* 202 * must do accounting normally done in main() 203 */ 204 if (Player[PLAYER].total > Player[COMP].total) 205 Player[PLAYER].games++; 206 else if (Player[PLAYER].total < Player[COMP].total) 207 Player[COMP].games++; 208 Player[COMP].total = 0; 209 Player[PLAYER].total = 0; 210 } 211 else 212 if (getyn(ANOTHERHANDPROMPT)) 213 return; 214 if (!Saved && getyn(SAVEGAMEPROMPT)) 215 if (!save()) 216 return; 217 die(); 218 } 219 220 readch() 221 { 222 reg int cnt; 223 static char c; 224 225 for (cnt = 0; read(0, &c, 1) <= 0; cnt++) 226 if (cnt > 100) 227 exit(1); 228 return c; 229 } 230 231 flush_input() 232 { 233 # ifdef TIOCFLUSH 234 static int ioctl_args = FREAD; 235 236 (void) ioctl(fileno(stdin), TIOCFLUSH, &ioctl_args); 237 # else 238 fflush(stdin); 239 # endif 240 } 241