1 1.19 mrg /* $NetBSD: move.c,v 1.19 2019/02/03 03:19:25 mrg Exp $ */ 2 1.4 cgd 3 1.1 cgd /* 4 1.3 jtc * Copyright (c) 1983, 1993 5 1.3 jtc * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.13 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.7 lukem #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.4 cgd #if 0 35 1.4 cgd static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 5/31/93"; 36 1.4 cgd #else 37 1.19 mrg __RCSID("$NetBSD: move.c,v 1.19 2019/02/03 03:19:25 mrg Exp $"); 38 1.4 cgd #endif 39 1.1 cgd #endif /* not lint */ 40 1.3 jtc 41 1.3 jtc #include <termios.h> 42 1.1 cgd 43 1.14 jdc #ifdef DEBUG 44 1.14 jdc #include <sys/param.h> 45 1.14 jdc #endif 46 1.14 jdc 47 1.1 cgd #include "mille.h" 48 1.1 cgd #ifndef unctrl 49 1.1 cgd #include "unctrl.h" 50 1.1 cgd #endif 51 1.1 cgd 52 1.1 cgd /* 53 1.1 cgd * @(#)move.c 1.2 (Berkeley) 3/28/83 54 1.1 cgd */ 55 1.1 cgd 56 1.1 cgd #undef CTRL 57 1.1 cgd #define CTRL(c) (c - 'A' + 1) 58 1.1 cgd 59 1.17 dholland static void check_go(void); 60 1.17 dholland static int playcard(PLAY *); 61 1.17 dholland static void getmove(void); 62 1.17 dholland static int haspicked(const PLAY *); 63 1.17 dholland 64 1.7 lukem void 65 1.16 dholland domove(void) 66 1.1 cgd { 67 1.7 lukem PLAY *pp; 68 1.7 lukem int i, j; 69 1.7 lukem bool goodplay; 70 1.1 cgd 71 1.1 cgd pp = &Player[Play]; 72 1.14 jdc for (i = 0, j = 0; i < HAND_SZ; i++) 73 1.14 jdc if (pp->hand[i] != -1) 74 1.14 jdc j++; 75 1.14 jdc if (!j) { 76 1.14 jdc nextplay(); 77 1.14 jdc return; 78 1.14 jdc } 79 1.1 cgd if (Play == PLAYER) 80 1.1 cgd getmove(); 81 1.1 cgd else 82 1.1 cgd calcmove(); 83 1.1 cgd Next = FALSE; 84 1.1 cgd goodplay = TRUE; 85 1.1 cgd switch (Movetype) { 86 1.1 cgd case M_DISCARD: 87 1.1 cgd if (haspicked(pp)) { 88 1.1 cgd if (pp->hand[Card_no] == C_INIT) 89 1.1 cgd if (Card_no == 6) 90 1.1 cgd Finished = TRUE; 91 1.1 cgd else 92 1.1 cgd error("no card there"); 93 1.1 cgd else { 94 1.11 jsm if (is_safety(pp->hand[Card_no])) { 95 1.1 cgd error("discard a safety?"); 96 1.1 cgd goodplay = FALSE; 97 1.1 cgd break; 98 1.1 cgd } 99 1.1 cgd Discard = pp->hand[Card_no]; 100 1.1 cgd pp->hand[Card_no] = C_INIT; 101 1.1 cgd Next = TRUE; 102 1.1 cgd if (Play == PLAYER) 103 1.1 cgd account(Discard); 104 1.1 cgd } 105 1.1 cgd } 106 1.1 cgd else 107 1.1 cgd error("must pick first"); 108 1.1 cgd break; 109 1.1 cgd case M_PLAY: 110 1.1 cgd goodplay = playcard(pp); 111 1.1 cgd break; 112 1.1 cgd case M_DRAW: 113 1.1 cgd Card_no = 0; 114 1.1 cgd if (Topcard <= Deck) 115 1.1 cgd error("no more cards"); 116 1.1 cgd else if (haspicked(pp)) 117 1.1 cgd error("already picked"); 118 1.1 cgd else { 119 1.1 cgd pp->hand[0] = *--Topcard; 120 1.1 cgd #ifdef DEBUG 121 1.1 cgd if (Debug) 122 1.1 cgd fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]); 123 1.1 cgd #endif 124 1.1 cgd acc: 125 1.1 cgd if (Play == COMP) { 126 1.1 cgd account(*Topcard); 127 1.11 jsm if (is_safety(*Topcard)) 128 1.1 cgd pp->safety[*Topcard-S_CONV] = S_IN_HAND; 129 1.1 cgd } 130 1.1 cgd if (pp->hand[1] == C_INIT && Topcard > Deck) { 131 1.1 cgd Card_no = 1; 132 1.1 cgd pp->hand[1] = *--Topcard; 133 1.1 cgd #ifdef DEBUG 134 1.1 cgd if (Debug) 135 1.1 cgd fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]); 136 1.1 cgd #endif 137 1.1 cgd goto acc; 138 1.1 cgd } 139 1.1 cgd pp->new_battle = FALSE; 140 1.1 cgd pp->new_speed = FALSE; 141 1.1 cgd } 142 1.1 cgd break; 143 1.1 cgd 144 1.1 cgd case M_ORDER: 145 1.1 cgd break; 146 1.1 cgd } 147 1.1 cgd /* 148 1.1 cgd * move blank card to top by one of two methods. If the 149 1.1 cgd * computer's hand was sorted, the randomness for picking 150 1.1 cgd * between equally valued cards would be lost 151 1.1 cgd */ 152 1.1 cgd if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER]) 153 1.1 cgd sort(pp->hand); 154 1.1 cgd else 155 1.1 cgd for (i = 1; i < HAND_SZ; i++) 156 1.1 cgd if (pp->hand[i] == C_INIT) { 157 1.1 cgd for (j = 0; pp->hand[j] == C_INIT; j++) 158 1.1 cgd if (j >= HAND_SZ) { 159 1.1 cgd j = 0; 160 1.1 cgd break; 161 1.1 cgd } 162 1.1 cgd pp->hand[i] = pp->hand[j]; 163 1.1 cgd pp->hand[j] = C_INIT; 164 1.1 cgd } 165 1.1 cgd if (Topcard <= Deck) 166 1.1 cgd check_go(); 167 1.1 cgd if (Next) 168 1.1 cgd nextplay(); 169 1.1 cgd } 170 1.1 cgd 171 1.1 cgd /* 172 1.1 cgd * Check and see if either side can go. If they cannot, 173 1.1 cgd * the game is over 174 1.1 cgd */ 175 1.17 dholland static void 176 1.16 dholland check_go(void) 177 1.7 lukem { 178 1.7 lukem CARD card; 179 1.7 lukem PLAY *pp, *op; 180 1.7 lukem int i; 181 1.1 cgd 182 1.1 cgd for (pp = Player; pp < &Player[2]; pp++) { 183 1.1 cgd op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]); 184 1.1 cgd for (i = 0; i < HAND_SZ; i++) { 185 1.1 cgd card = pp->hand[i]; 186 1.11 jsm if (is_safety(card) || canplay(pp, op, card)) { 187 1.1 cgd #ifdef DEBUG 188 1.1 cgd if (Debug) { 189 1.1 cgd fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card); 190 1.12 jsm fprintf(outf, "is_safety(card) = %d, ", is_safety(card)); 191 1.1 cgd fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card)); 192 1.1 cgd } 193 1.1 cgd #endif 194 1.1 cgd return; 195 1.1 cgd } 196 1.1 cgd #ifdef DEBUG 197 1.1 cgd else if (Debug) 198 1.1 cgd fprintf(outf, "CHECK_GO: cannot play %s\n", 199 1.1 cgd C_name[card]); 200 1.1 cgd #endif 201 1.1 cgd } 202 1.1 cgd } 203 1.1 cgd Finished = TRUE; 204 1.1 cgd } 205 1.1 cgd 206 1.17 dholland static int 207 1.16 dholland playcard(PLAY *pp) 208 1.1 cgd { 209 1.7 lukem int v; 210 1.7 lukem CARD card; 211 1.1 cgd 212 1.1 cgd /* 213 1.1 cgd * check and see if player has picked 214 1.1 cgd */ 215 1.1 cgd switch (pp->hand[Card_no]) { 216 1.1 cgd default: 217 1.1 cgd if (!haspicked(pp)) 218 1.1 cgd mustpick: 219 1.1 cgd return error("must pick first"); 220 1.1 cgd case C_GAS_SAFE: case C_SPARE_SAFE: 221 1.1 cgd case C_DRIVE_SAFE: case C_RIGHT_WAY: 222 1.1 cgd break; 223 1.1 cgd } 224 1.1 cgd 225 1.1 cgd card = pp->hand[Card_no]; 226 1.1 cgd #ifdef DEBUG 227 1.1 cgd if (Debug) 228 1.1 cgd fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]); 229 1.1 cgd #endif 230 1.1 cgd Next = FALSE; 231 1.1 cgd switch (card) { 232 1.1 cgd case C_200: 233 1.1 cgd if (pp->nummiles[C_200] == 2) 234 1.1 cgd return error("only two 200's per hand"); 235 1.19 mrg /* FALLTHROUGH */ 236 1.1 cgd case C_100: case C_75: 237 1.1 cgd if (pp->speed == C_LIMIT) 238 1.1 cgd return error("limit of 50"); 239 1.19 mrg /* FALLTHROUGH */ 240 1.1 cgd case C_50: 241 1.1 cgd if (pp->mileage + Value[card] > End) 242 1.1 cgd return error("puts you over %d", End); 243 1.19 mrg /* FALLTHROUGH */ 244 1.1 cgd case C_25: 245 1.1 cgd if (!pp->can_go) 246 1.1 cgd return error("cannot move now"); 247 1.1 cgd pp->nummiles[card]++; 248 1.1 cgd v = Value[card]; 249 1.1 cgd pp->total += v; 250 1.1 cgd pp->hand_tot += v; 251 1.1 cgd if ((pp->mileage += v) == End) 252 1.1 cgd check_ext(FALSE); 253 1.1 cgd break; 254 1.1 cgd 255 1.1 cgd case C_GAS: case C_SPARE: case C_REPAIRS: 256 1.1 cgd if (pp->battle != opposite(card)) 257 1.1 cgd return error("can't play \"%s\"", C_name[card]); 258 1.1 cgd pp->battle = card; 259 1.1 cgd if (pp->safety[S_RIGHT_WAY] == S_PLAYED) 260 1.1 cgd pp->can_go = TRUE; 261 1.1 cgd break; 262 1.1 cgd 263 1.1 cgd case C_GO: 264 1.1 cgd if (pp->battle != C_INIT && pp->battle != C_STOP 265 1.11 jsm && !is_repair(pp->battle)) 266 1.1 cgd return error("cannot play \"Go\" on a \"%s\"", 267 1.1 cgd C_name[pp->battle]); 268 1.1 cgd pp->battle = C_GO; 269 1.1 cgd pp->can_go = TRUE; 270 1.1 cgd break; 271 1.1 cgd 272 1.1 cgd case C_END_LIMIT: 273 1.1 cgd if (pp->speed != C_LIMIT) 274 1.1 cgd return error("not limited"); 275 1.1 cgd pp->speed = C_END_LIMIT; 276 1.1 cgd break; 277 1.1 cgd 278 1.1 cgd case C_EMPTY: case C_FLAT: case C_CRASH: 279 1.1 cgd case C_STOP: 280 1.1 cgd pp = &Player[other(Play)]; 281 1.1 cgd if (!pp->can_go) 282 1.1 cgd return error("opponent cannot go"); 283 1.1 cgd else if (pp->safety[safety(card) - S_CONV] == S_PLAYED) 284 1.1 cgd protected: 285 1.1 cgd return error("opponent is protected"); 286 1.1 cgd pp->battle = card; 287 1.1 cgd pp->new_battle = TRUE; 288 1.1 cgd pp->can_go = FALSE; 289 1.1 cgd pp = &Player[Play]; 290 1.1 cgd break; 291 1.1 cgd 292 1.1 cgd case C_LIMIT: 293 1.1 cgd pp = &Player[other(Play)]; 294 1.1 cgd if (pp->speed == C_LIMIT) 295 1.1 cgd return error("opponent has limit"); 296 1.1 cgd if (pp->safety[S_RIGHT_WAY] == S_PLAYED) 297 1.1 cgd goto protected; 298 1.1 cgd pp->speed = C_LIMIT; 299 1.1 cgd pp->new_speed = TRUE; 300 1.1 cgd pp = &Player[Play]; 301 1.1 cgd break; 302 1.1 cgd 303 1.1 cgd case C_GAS_SAFE: case C_SPARE_SAFE: 304 1.1 cgd case C_DRIVE_SAFE: case C_RIGHT_WAY: 305 1.1 cgd if (pp->battle == opposite(card) 306 1.1 cgd || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) { 307 1.11 jsm if (!(card == C_RIGHT_WAY && !is_repair(pp->battle))) { 308 1.1 cgd pp->battle = C_GO; 309 1.1 cgd pp->can_go = TRUE; 310 1.1 cgd } 311 1.1 cgd if (card == C_RIGHT_WAY && pp->speed == C_LIMIT) 312 1.1 cgd pp->speed = C_INIT; 313 1.1 cgd if (pp->new_battle 314 1.1 cgd || (pp->new_speed && card == C_RIGHT_WAY)) { 315 1.1 cgd pp->coups[card - S_CONV] = TRUE; 316 1.1 cgd pp->total += SC_COUP; 317 1.1 cgd pp->hand_tot += SC_COUP; 318 1.1 cgd pp->coupscore += SC_COUP; 319 1.1 cgd } 320 1.1 cgd } 321 1.1 cgd /* 322 1.1 cgd * if not coup, must pick first 323 1.1 cgd */ 324 1.1 cgd else if (pp->hand[0] == C_INIT && Topcard > Deck) 325 1.1 cgd goto mustpick; 326 1.1 cgd pp->safety[card - S_CONV] = S_PLAYED; 327 1.1 cgd pp->total += SC_SAFETY; 328 1.1 cgd pp->hand_tot += SC_SAFETY; 329 1.1 cgd if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) { 330 1.1 cgd pp->total += SC_ALL_SAFE; 331 1.1 cgd pp->hand_tot += SC_ALL_SAFE; 332 1.1 cgd } 333 1.1 cgd if (card == C_RIGHT_WAY) { 334 1.1 cgd if (pp->speed == C_LIMIT) 335 1.1 cgd pp->speed = C_INIT; 336 1.1 cgd if (pp->battle == C_STOP || pp->battle == C_INIT) { 337 1.1 cgd pp->can_go = TRUE; 338 1.1 cgd pp->battle = C_INIT; 339 1.1 cgd } 340 1.11 jsm if (!pp->can_go && is_repair(pp->battle)) 341 1.1 cgd pp->can_go = TRUE; 342 1.1 cgd } 343 1.1 cgd Next = -1; 344 1.1 cgd break; 345 1.1 cgd 346 1.1 cgd case C_INIT: 347 1.1 cgd error("no card there"); 348 1.1 cgd Next = -1; 349 1.1 cgd break; 350 1.1 cgd } 351 1.1 cgd if (pp == &Player[PLAYER]) 352 1.1 cgd account(card); 353 1.1 cgd pp->hand[Card_no] = C_INIT; 354 1.5 thorpej Next = (Next == (bool)-1 ? FALSE : TRUE); 355 1.1 cgd return TRUE; 356 1.1 cgd } 357 1.1 cgd 358 1.17 dholland static void 359 1.16 dholland getmove(void) 360 1.1 cgd { 361 1.7 lukem char c; 362 1.1 cgd #ifdef EXTRAP 363 1.1 cgd static bool last_ex = FALSE; /* set if last command was E */ 364 1.1 cgd 365 1.1 cgd if (last_ex) { 366 1.1 cgd undoex(); 367 1.1 cgd prboard(); 368 1.1 cgd last_ex = FALSE; 369 1.1 cgd } 370 1.1 cgd #endif 371 1.1 cgd for (;;) { 372 1.1 cgd prompt(MOVEPROMPT); 373 1.1 cgd leaveok(Board, FALSE); 374 1.1 cgd refresh(); 375 1.1 cgd while ((c = readch()) == killchar() || c == erasechar()) 376 1.1 cgd continue; 377 1.15 dsl if (islower((unsigned char)c)) 378 1.15 dsl c = toupper((unsigned char)c); 379 1.15 dsl if (isprint((unsigned char)c) && !isspace((unsigned char)c)) { 380 1.1 cgd addch(c); 381 1.1 cgd refresh(); 382 1.1 cgd } 383 1.1 cgd switch (c) { 384 1.1 cgd case 'P': /* Pick */ 385 1.1 cgd Movetype = M_DRAW; 386 1.1 cgd goto ret; 387 1.1 cgd case 'U': /* Use Card */ 388 1.1 cgd case 'D': /* Discard Card */ 389 1.1 cgd if ((Card_no = getcard()) < 0) 390 1.1 cgd break; 391 1.1 cgd Movetype = (c == 'U' ? M_PLAY : M_DISCARD); 392 1.1 cgd goto ret; 393 1.1 cgd case 'O': /* Order */ 394 1.1 cgd Order = !Order; 395 1.1 cgd if (Window == W_SMALL) { 396 1.1 cgd if (!Order) 397 1.1 cgd mvwaddstr(Score, 12, 21, 398 1.1 cgd "o: order hand"); 399 1.1 cgd else 400 1.1 cgd mvwaddstr(Score, 12, 21, 401 1.1 cgd "o: stop ordering"); 402 1.1 cgd wclrtoeol(Score); 403 1.1 cgd } 404 1.1 cgd Movetype = M_ORDER; 405 1.1 cgd goto ret; 406 1.1 cgd case 'Q': /* Quit */ 407 1.7 lukem rub(0); /* Same as a rubout */ 408 1.1 cgd break; 409 1.1 cgd case 'W': /* Window toggle */ 410 1.1 cgd Window = nextwin(Window); 411 1.1 cgd newscore(); 412 1.1 cgd prscore(TRUE); 413 1.1 cgd wrefresh(Score); 414 1.1 cgd break; 415 1.1 cgd case 'R': /* Redraw screen */ 416 1.1 cgd case CTRL('L'): 417 1.1 cgd wrefresh(curscr); 418 1.1 cgd break; 419 1.1 cgd case 'S': /* Save game */ 420 1.1 cgd On_exit = FALSE; 421 1.1 cgd save(); 422 1.1 cgd break; 423 1.1 cgd case 'E': /* Extrapolate */ 424 1.1 cgd #ifdef EXTRAP 425 1.1 cgd if (last_ex) 426 1.1 cgd break; 427 1.1 cgd Finished = TRUE; 428 1.1 cgd if (Window != W_FULL) 429 1.1 cgd newscore(); 430 1.1 cgd prscore(FALSE); 431 1.1 cgd wrefresh(Score); 432 1.1 cgd last_ex = TRUE; 433 1.1 cgd Finished = FALSE; 434 1.1 cgd #else 435 1.1 cgd error("%c: command not implemented", c); 436 1.1 cgd #endif 437 1.1 cgd break; 438 1.1 cgd case '\r': /* Ignore RETURNs and */ 439 1.1 cgd case '\n': /* Line Feeds */ 440 1.1 cgd case ' ': /* Spaces */ 441 1.1 cgd case '\0': /* and nulls */ 442 1.1 cgd break; 443 1.1 cgd #ifdef DEBUG 444 1.1 cgd case 'Z': /* Debug code */ 445 1.1 cgd if (!Debug && outf == NULL) { 446 1.1 cgd char buf[MAXPATHLEN]; 447 1.14 jdc char *sp; 448 1.1 cgd 449 1.1 cgd prompt(FILEPROMPT); 450 1.1 cgd leaveok(Board, FALSE); 451 1.1 cgd refresh(); 452 1.14 jdc over: 453 1.1 cgd sp = buf; 454 1.1 cgd while ((*sp = readch()) != '\n') { 455 1.1 cgd if (*sp == killchar()) 456 1.1 cgd goto over; 457 1.1 cgd else if (*sp == erasechar()) { 458 1.1 cgd if (--sp < buf) 459 1.1 cgd sp = buf; 460 1.1 cgd else { 461 1.1 cgd addch('\b'); 462 1.1 cgd if (*sp < ' ') 463 1.1 cgd addch('\b'); 464 1.1 cgd clrtoeol(); 465 1.1 cgd } 466 1.1 cgd } 467 1.1 cgd else 468 1.1 cgd addstr(unctrl(*sp++)); 469 1.1 cgd refresh(); 470 1.1 cgd } 471 1.1 cgd *sp = '\0'; 472 1.1 cgd leaveok(Board, TRUE); 473 1.1 cgd if ((outf = fopen(buf, "w")) == NULL) 474 1.7 lukem warn("%s", buf); 475 1.18 plunky setbuf(outf, NULL); 476 1.1 cgd } 477 1.1 cgd Debug = !Debug; 478 1.1 cgd break; 479 1.1 cgd #endif 480 1.1 cgd default: 481 1.1 cgd error("unknown command: %s", unctrl(c)); 482 1.1 cgd break; 483 1.1 cgd } 484 1.1 cgd } 485 1.1 cgd ret: 486 1.1 cgd leaveok(Board, TRUE); 487 1.1 cgd } 488 1.7 lukem 489 1.1 cgd /* 490 1.1 cgd * return whether or not the player has picked 491 1.1 cgd */ 492 1.17 dholland static int 493 1.16 dholland haspicked(const PLAY *pp) 494 1.6 jtc { 495 1.7 lukem int card; 496 1.1 cgd 497 1.1 cgd if (Topcard <= Deck) 498 1.1 cgd return TRUE; 499 1.1 cgd switch (pp->hand[Card_no]) { 500 1.1 cgd case C_GAS_SAFE: case C_SPARE_SAFE: 501 1.1 cgd case C_DRIVE_SAFE: case C_RIGHT_WAY: 502 1.1 cgd card = 1; 503 1.1 cgd break; 504 1.1 cgd default: 505 1.1 cgd card = 0; 506 1.1 cgd break; 507 1.1 cgd } 508 1.1 cgd return (pp->hand[card] != C_INIT); 509 1.1 cgd } 510 1.1 cgd 511 1.7 lukem void 512 1.16 dholland account(CARD card) 513 1.6 jtc { 514 1.7 lukem CARD oppos; 515 1.1 cgd 516 1.1 cgd if (card == C_INIT) 517 1.1 cgd return; 518 1.1 cgd ++Numseen[card]; 519 1.1 cgd if (Play == COMP) 520 1.1 cgd switch (card) { 521 1.1 cgd case C_GAS_SAFE: 522 1.1 cgd case C_SPARE_SAFE: 523 1.1 cgd case C_DRIVE_SAFE: 524 1.1 cgd oppos = opposite(card); 525 1.1 cgd Numgos += Numcards[oppos] - Numseen[oppos]; 526 1.1 cgd break; 527 1.1 cgd case C_CRASH: 528 1.1 cgd case C_FLAT: 529 1.1 cgd case C_EMPTY: 530 1.1 cgd case C_STOP: 531 1.1 cgd Numgos++; 532 1.1 cgd break; 533 1.1 cgd } 534 1.1 cgd } 535 1.1 cgd 536 1.7 lukem void 537 1.16 dholland prompt(int promptno) 538 1.1 cgd { 539 1.10 jsm static const char *const names[] = { 540 1.1 cgd ">>:Move:", 541 1.1 cgd "Really?", 542 1.1 cgd "Another hand?", 543 1.1 cgd "Another game?", 544 1.1 cgd "Save game?", 545 1.1 cgd "Same file?", 546 1.1 cgd "file:", 547 1.1 cgd "Extension?", 548 1.1 cgd "Overwrite file?", 549 1.1 cgd }; 550 1.1 cgd static int last_prompt = -1; 551 1.1 cgd 552 1.1 cgd if (promptno == last_prompt) 553 1.1 cgd move(MOVE_Y, MOVE_X + strlen(names[promptno]) + 1); 554 1.1 cgd else { 555 1.1 cgd move(MOVE_Y, MOVE_X); 556 1.1 cgd if (promptno == MOVEPROMPT) 557 1.1 cgd standout(); 558 1.1 cgd addstr(names[promptno]); 559 1.1 cgd if (promptno == MOVEPROMPT) 560 1.1 cgd standend(); 561 1.1 cgd addch(' '); 562 1.1 cgd last_prompt = promptno; 563 1.1 cgd } 564 1.1 cgd clrtoeol(); 565 1.1 cgd } 566 1.1 cgd 567 1.7 lukem void 568 1.16 dholland sort(CARD *hand) 569 1.1 cgd { 570 1.7 lukem CARD *cp, *tp; 571 1.7 lukem CARD temp; 572 1.1 cgd 573 1.1 cgd cp = hand; 574 1.1 cgd hand += HAND_SZ; 575 1.1 cgd for ( ; cp < &hand[-1]; cp++) 576 1.1 cgd for (tp = cp + 1; tp < hand; tp++) 577 1.1 cgd if (*cp > *tp) { 578 1.1 cgd temp = *cp; 579 1.1 cgd *cp = *tp; 580 1.1 cgd *tp = temp; 581 1.1 cgd } 582 1.1 cgd } 583