Home | History | Annotate | Line # | Download | only in mille
move.c revision 1.18.42.1
      1  1.18.42.1  christos /*	$NetBSD: move.c,v 1.18.42.1 2019/06/10 22:05:11 christos 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.18.42.1  christos __RCSID("$NetBSD: move.c,v 1.18.42.1 2019/06/10 22:05:11 christos 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.18.42.1  christos 		/* 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.18.42.1  christos 		/* 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.18.42.1  christos 		/* 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