Home | History | Annotate | Line # | Download | only in mille
move.c revision 1.13.2.1
      1  1.13.2.1      jmc /*	$NetBSD: move.c,v 1.13.2.1 2004/04/08 22:02:36 jmc 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.13.2.1      jmc __RCSID("$NetBSD: move.c,v 1.13.2.1 2004/04/08 22:02:36 jmc 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.13.2.1      jmc #ifdef DEBUG
     44  1.13.2.1      jmc #include <sys/param.h>
     45  1.13.2.1      jmc #endif
     46  1.13.2.1      jmc 
     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.7    lukem void
     60       1.1      cgd domove()
     61       1.1      cgd {
     62       1.7    lukem 	PLAY	*pp;
     63       1.7    lukem 	int	i, j;
     64       1.7    lukem 	bool	goodplay;
     65       1.1      cgd 
     66       1.1      cgd 	pp = &Player[Play];
     67  1.13.2.1      jmc 	for (i = 0, j = 0; i < HAND_SZ; i++)
     68  1.13.2.1      jmc 		if (pp->hand[i] != -1)
     69  1.13.2.1      jmc 			j++;
     70  1.13.2.1      jmc 	if (!j) {
     71  1.13.2.1      jmc 		nextplay();
     72  1.13.2.1      jmc 		return;
     73  1.13.2.1      jmc 	}
     74       1.1      cgd 	if (Play == PLAYER)
     75       1.1      cgd 		getmove();
     76       1.1      cgd 	else
     77       1.1      cgd 		calcmove();
     78       1.1      cgd 	Next = FALSE;
     79       1.1      cgd 	goodplay = TRUE;
     80       1.1      cgd 	switch (Movetype) {
     81       1.1      cgd 	  case M_DISCARD:
     82       1.1      cgd 		if (haspicked(pp)) {
     83       1.1      cgd 			if (pp->hand[Card_no] == C_INIT)
     84       1.1      cgd 				if (Card_no == 6)
     85       1.1      cgd 					Finished = TRUE;
     86       1.1      cgd 				else
     87       1.1      cgd 					error("no card there");
     88       1.1      cgd 			else {
     89      1.11      jsm 				if (is_safety(pp->hand[Card_no])) {
     90       1.1      cgd 					error("discard a safety?");
     91       1.1      cgd 					goodplay = FALSE;
     92       1.1      cgd 					break;
     93       1.1      cgd 				}
     94       1.1      cgd 				Discard = pp->hand[Card_no];
     95       1.1      cgd 				pp->hand[Card_no] = C_INIT;
     96       1.1      cgd 				Next = TRUE;
     97       1.1      cgd 				if (Play == PLAYER)
     98       1.1      cgd 					account(Discard);
     99       1.1      cgd 			}
    100       1.1      cgd 		}
    101       1.1      cgd 		else
    102       1.1      cgd 			error("must pick first");
    103       1.1      cgd 		break;
    104       1.1      cgd 	  case M_PLAY:
    105       1.1      cgd 		goodplay = playcard(pp);
    106       1.1      cgd 		break;
    107       1.1      cgd 	  case M_DRAW:
    108       1.1      cgd 		Card_no = 0;
    109       1.1      cgd 		if (Topcard <= Deck)
    110       1.1      cgd 			error("no more cards");
    111       1.1      cgd 		else if (haspicked(pp))
    112       1.1      cgd 			error("already picked");
    113       1.1      cgd 		else {
    114       1.1      cgd 			pp->hand[0] = *--Topcard;
    115       1.1      cgd #ifdef DEBUG
    116       1.1      cgd 			if (Debug)
    117       1.1      cgd 				fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
    118       1.1      cgd #endif
    119       1.1      cgd acc:
    120       1.1      cgd 			if (Play == COMP) {
    121       1.1      cgd 				account(*Topcard);
    122      1.11      jsm 				if (is_safety(*Topcard))
    123       1.1      cgd 					pp->safety[*Topcard-S_CONV] = S_IN_HAND;
    124       1.1      cgd 			}
    125       1.1      cgd 			if (pp->hand[1] == C_INIT && Topcard > Deck) {
    126       1.1      cgd 				Card_no = 1;
    127       1.1      cgd 				pp->hand[1] = *--Topcard;
    128       1.1      cgd #ifdef DEBUG
    129       1.1      cgd 				if (Debug)
    130       1.1      cgd 					fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
    131       1.1      cgd #endif
    132       1.1      cgd 				goto acc;
    133       1.1      cgd 			}
    134       1.1      cgd 			pp->new_battle = FALSE;
    135       1.1      cgd 			pp->new_speed = FALSE;
    136       1.1      cgd 		}
    137       1.1      cgd 		break;
    138       1.1      cgd 
    139       1.1      cgd 	  case M_ORDER:
    140       1.1      cgd 		break;
    141       1.1      cgd 	}
    142       1.1      cgd 	/*
    143       1.1      cgd 	 * move blank card to top by one of two methods.  If the
    144       1.1      cgd 	 * computer's hand was sorted, the randomness for picking
    145       1.1      cgd 	 * between equally valued cards would be lost
    146       1.1      cgd 	 */
    147       1.1      cgd 	if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
    148       1.1      cgd 		sort(pp->hand);
    149       1.1      cgd 	else
    150       1.1      cgd 		for (i = 1; i < HAND_SZ; i++)
    151       1.1      cgd 			if (pp->hand[i] == C_INIT) {
    152       1.1      cgd 				for (j = 0; pp->hand[j] == C_INIT; j++)
    153       1.1      cgd 					if (j >= HAND_SZ) {
    154       1.1      cgd 						j = 0;
    155       1.1      cgd 						break;
    156       1.1      cgd 					}
    157       1.1      cgd 				pp->hand[i] = pp->hand[j];
    158       1.1      cgd 				pp->hand[j] = C_INIT;
    159       1.1      cgd 			}
    160       1.1      cgd 	if (Topcard <= Deck)
    161       1.1      cgd 		check_go();
    162       1.1      cgd 	if (Next)
    163       1.1      cgd 		nextplay();
    164       1.1      cgd }
    165       1.1      cgd 
    166       1.1      cgd /*
    167       1.1      cgd  *	Check and see if either side can go.  If they cannot,
    168       1.1      cgd  * the game is over
    169       1.1      cgd  */
    170       1.7    lukem void
    171       1.7    lukem check_go()
    172       1.7    lukem {
    173       1.7    lukem 	CARD	card;
    174       1.7    lukem 	PLAY	*pp, *op;
    175       1.7    lukem 	int	i;
    176       1.1      cgd 
    177       1.1      cgd 	for (pp = Player; pp < &Player[2]; pp++) {
    178       1.1      cgd 		op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
    179       1.1      cgd 		for (i = 0; i < HAND_SZ; i++) {
    180       1.1      cgd 			card = pp->hand[i];
    181      1.11      jsm 			if (is_safety(card) || canplay(pp, op, card)) {
    182       1.1      cgd #ifdef DEBUG
    183       1.1      cgd 				if (Debug) {
    184       1.1      cgd 					fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
    185      1.12      jsm 					fprintf(outf, "is_safety(card) = %d, ", is_safety(card));
    186       1.1      cgd 					fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
    187       1.1      cgd 				}
    188       1.1      cgd #endif
    189       1.1      cgd 				return;
    190       1.1      cgd 			}
    191       1.1      cgd #ifdef DEBUG
    192       1.1      cgd 			else if (Debug)
    193       1.1      cgd 				fprintf(outf, "CHECK_GO: cannot play %s\n",
    194       1.1      cgd 				    C_name[card]);
    195       1.1      cgd #endif
    196       1.1      cgd 		}
    197       1.1      cgd 	}
    198       1.1      cgd 	Finished = TRUE;
    199       1.1      cgd }
    200       1.1      cgd 
    201       1.7    lukem int
    202       1.1      cgd playcard(pp)
    203       1.7    lukem 	PLAY	*pp;
    204       1.1      cgd {
    205       1.7    lukem 	int	v;
    206       1.7    lukem 	CARD	card;
    207       1.1      cgd 
    208       1.1      cgd 	/*
    209       1.1      cgd 	 * check and see if player has picked
    210       1.1      cgd 	 */
    211       1.1      cgd 	switch (pp->hand[Card_no]) {
    212       1.1      cgd 	  default:
    213       1.1      cgd 		if (!haspicked(pp))
    214       1.1      cgd mustpick:
    215       1.1      cgd 			return error("must pick first");
    216       1.1      cgd 	  case C_GAS_SAFE:	case C_SPARE_SAFE:
    217       1.1      cgd 	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
    218       1.1      cgd 		break;
    219       1.1      cgd 	}
    220       1.1      cgd 
    221       1.1      cgd 	card = pp->hand[Card_no];
    222       1.1      cgd #ifdef DEBUG
    223       1.1      cgd 	if (Debug)
    224       1.1      cgd 		fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
    225       1.1      cgd #endif
    226       1.1      cgd 	Next = FALSE;
    227       1.1      cgd 	switch (card) {
    228       1.1      cgd 	  case C_200:
    229       1.1      cgd 		if (pp->nummiles[C_200] == 2)
    230       1.1      cgd 			return error("only two 200's per hand");
    231       1.1      cgd 	  case C_100:	case C_75:
    232       1.1      cgd 		if (pp->speed == C_LIMIT)
    233       1.1      cgd 			return error("limit of 50");
    234       1.1      cgd 	  case C_50:
    235       1.1      cgd 		if (pp->mileage + Value[card] > End)
    236       1.1      cgd 			return error("puts you over %d", End);
    237       1.1      cgd 	  case C_25:
    238       1.1      cgd 		if (!pp->can_go)
    239       1.1      cgd 			return error("cannot move now");
    240       1.1      cgd 		pp->nummiles[card]++;
    241       1.1      cgd 		v = Value[card];
    242       1.1      cgd 		pp->total += v;
    243       1.1      cgd 		pp->hand_tot += v;
    244       1.1      cgd 		if ((pp->mileage += v) == End)
    245       1.1      cgd 			check_ext(FALSE);
    246       1.1      cgd 		break;
    247       1.1      cgd 
    248       1.1      cgd 	  case C_GAS:	case C_SPARE:	case C_REPAIRS:
    249       1.1      cgd 		if (pp->battle != opposite(card))
    250       1.1      cgd 			return error("can't play \"%s\"", C_name[card]);
    251       1.1      cgd 		pp->battle = card;
    252       1.1      cgd 		if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
    253       1.1      cgd 			pp->can_go = TRUE;
    254       1.1      cgd 		break;
    255       1.1      cgd 
    256       1.1      cgd 	  case C_GO:
    257       1.1      cgd 		if (pp->battle != C_INIT && pp->battle != C_STOP
    258      1.11      jsm 		    && !is_repair(pp->battle))
    259       1.1      cgd 			return error("cannot play \"Go\" on a \"%s\"",
    260       1.1      cgd 			    C_name[pp->battle]);
    261       1.1      cgd 		pp->battle = C_GO;
    262       1.1      cgd 		pp->can_go = TRUE;
    263       1.1      cgd 		break;
    264       1.1      cgd 
    265       1.1      cgd 	  case C_END_LIMIT:
    266       1.1      cgd 		if (pp->speed != C_LIMIT)
    267       1.1      cgd 			return error("not limited");
    268       1.1      cgd 		pp->speed = C_END_LIMIT;
    269       1.1      cgd 		break;
    270       1.1      cgd 
    271       1.1      cgd 	  case C_EMPTY:	case C_FLAT:	case C_CRASH:
    272       1.1      cgd 	  case C_STOP:
    273       1.1      cgd 		pp = &Player[other(Play)];
    274       1.1      cgd 		if (!pp->can_go)
    275       1.1      cgd 			return error("opponent cannot go");
    276       1.1      cgd 		else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
    277       1.1      cgd protected:
    278       1.1      cgd 			return error("opponent is protected");
    279       1.1      cgd 		pp->battle = card;
    280       1.1      cgd 		pp->new_battle = TRUE;
    281       1.1      cgd 		pp->can_go = FALSE;
    282       1.1      cgd 		pp = &Player[Play];
    283       1.1      cgd 		break;
    284       1.1      cgd 
    285       1.1      cgd 	  case C_LIMIT:
    286       1.1      cgd 		pp = &Player[other(Play)];
    287       1.1      cgd 		if (pp->speed == C_LIMIT)
    288       1.1      cgd 			return error("opponent has limit");
    289       1.1      cgd 		if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
    290       1.1      cgd 			goto protected;
    291       1.1      cgd 		pp->speed = C_LIMIT;
    292       1.1      cgd 		pp->new_speed = TRUE;
    293       1.1      cgd 		pp = &Player[Play];
    294       1.1      cgd 		break;
    295       1.1      cgd 
    296       1.1      cgd 	  case C_GAS_SAFE:	case C_SPARE_SAFE:
    297       1.1      cgd 	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
    298       1.1      cgd 		if (pp->battle == opposite(card)
    299       1.1      cgd 		    || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
    300      1.11      jsm 			if (!(card == C_RIGHT_WAY && !is_repair(pp->battle))) {
    301       1.1      cgd 				pp->battle = C_GO;
    302       1.1      cgd 				pp->can_go = TRUE;
    303       1.1      cgd 			}
    304       1.1      cgd 			if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
    305       1.1      cgd 				pp->speed = C_INIT;
    306       1.1      cgd 			if (pp->new_battle
    307       1.1      cgd 			    || (pp->new_speed && card == C_RIGHT_WAY)) {
    308       1.1      cgd 				pp->coups[card - S_CONV] = TRUE;
    309       1.1      cgd 				pp->total += SC_COUP;
    310       1.1      cgd 				pp->hand_tot += SC_COUP;
    311       1.1      cgd 				pp->coupscore += SC_COUP;
    312       1.1      cgd 			}
    313       1.1      cgd 		}
    314       1.1      cgd 		/*
    315       1.1      cgd 		 * if not coup, must pick first
    316       1.1      cgd 		 */
    317       1.1      cgd 		else if (pp->hand[0] == C_INIT && Topcard > Deck)
    318       1.1      cgd 			goto mustpick;
    319       1.1      cgd 		pp->safety[card - S_CONV] = S_PLAYED;
    320       1.1      cgd 		pp->total += SC_SAFETY;
    321       1.1      cgd 		pp->hand_tot += SC_SAFETY;
    322       1.1      cgd 		if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
    323       1.1      cgd 			pp->total += SC_ALL_SAFE;
    324       1.1      cgd 			pp->hand_tot += SC_ALL_SAFE;
    325       1.1      cgd 		}
    326       1.1      cgd 		if (card == C_RIGHT_WAY) {
    327       1.1      cgd 			if (pp->speed == C_LIMIT)
    328       1.1      cgd 				pp->speed = C_INIT;
    329       1.1      cgd 			if (pp->battle == C_STOP || pp->battle == C_INIT) {
    330       1.1      cgd 				pp->can_go = TRUE;
    331       1.1      cgd 				pp->battle = C_INIT;
    332       1.1      cgd 			}
    333      1.11      jsm 			if (!pp->can_go && is_repair(pp->battle))
    334       1.1      cgd 				pp->can_go = TRUE;
    335       1.1      cgd 		}
    336       1.1      cgd 		Next = -1;
    337       1.1      cgd 		break;
    338       1.1      cgd 
    339       1.1      cgd 	  case C_INIT:
    340       1.1      cgd 		error("no card there");
    341       1.1      cgd 		Next = -1;
    342       1.1      cgd 		break;
    343       1.1      cgd 	}
    344       1.1      cgd 	if (pp == &Player[PLAYER])
    345       1.1      cgd 		account(card);
    346       1.1      cgd 	pp->hand[Card_no] = C_INIT;
    347       1.5  thorpej 	Next = (Next == (bool)-1 ? FALSE : TRUE);
    348       1.1      cgd 	return TRUE;
    349       1.1      cgd }
    350       1.1      cgd 
    351       1.7    lukem void
    352       1.1      cgd getmove()
    353       1.1      cgd {
    354       1.7    lukem 	char	c;
    355       1.1      cgd #ifdef EXTRAP
    356       1.1      cgd 	static bool	last_ex = FALSE;	/* set if last command was E */
    357       1.1      cgd 
    358       1.1      cgd 	if (last_ex) {
    359       1.1      cgd 		undoex();
    360       1.1      cgd 		prboard();
    361       1.1      cgd 		last_ex = FALSE;
    362       1.1      cgd 	}
    363       1.1      cgd #endif
    364       1.1      cgd 	for (;;) {
    365       1.1      cgd 		prompt(MOVEPROMPT);
    366       1.1      cgd 		leaveok(Board, FALSE);
    367       1.1      cgd 		refresh();
    368       1.1      cgd 		while ((c = readch()) == killchar() || c == erasechar())
    369       1.1      cgd 			continue;
    370       1.1      cgd 		if (islower(c))
    371       1.1      cgd 			c = toupper(c);
    372       1.1      cgd 		if (isprint(c) && !isspace(c)) {
    373       1.1      cgd 			addch(c);
    374       1.1      cgd 			refresh();
    375       1.1      cgd 		}
    376       1.1      cgd 		switch (c) {
    377       1.1      cgd 		  case 'P':		/* Pick */
    378       1.1      cgd 			Movetype = M_DRAW;
    379       1.1      cgd 			goto ret;
    380       1.1      cgd 		  case 'U':		/* Use Card */
    381       1.1      cgd 		  case 'D':		/* Discard Card */
    382       1.1      cgd 			if ((Card_no = getcard()) < 0)
    383       1.1      cgd 				break;
    384       1.1      cgd 			Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
    385       1.1      cgd 			goto ret;
    386       1.1      cgd 		  case 'O':		/* Order */
    387       1.1      cgd 			Order = !Order;
    388       1.1      cgd 			if (Window == W_SMALL) {
    389       1.1      cgd 				if (!Order)
    390       1.1      cgd 					mvwaddstr(Score, 12, 21,
    391       1.1      cgd 						  "o: order hand");
    392       1.1      cgd 				else
    393       1.1      cgd 					mvwaddstr(Score, 12, 21,
    394       1.1      cgd 						  "o: stop ordering");
    395       1.1      cgd 				wclrtoeol(Score);
    396       1.1      cgd 			}
    397       1.1      cgd 			Movetype = M_ORDER;
    398       1.1      cgd 			goto ret;
    399       1.1      cgd 		  case 'Q':		/* Quit */
    400       1.7    lukem 			rub(0);		/* Same as a rubout */
    401       1.1      cgd 			break;
    402       1.1      cgd 		  case 'W':		/* Window toggle */
    403       1.1      cgd 			Window = nextwin(Window);
    404       1.1      cgd 			newscore();
    405       1.1      cgd 			prscore(TRUE);
    406       1.1      cgd 			wrefresh(Score);
    407       1.1      cgd 			break;
    408       1.1      cgd 		  case 'R':		/* Redraw screen */
    409       1.1      cgd 		  case CTRL('L'):
    410       1.1      cgd 			wrefresh(curscr);
    411       1.1      cgd 			break;
    412       1.1      cgd 		  case 'S':		/* Save game */
    413       1.1      cgd 			On_exit = FALSE;
    414       1.1      cgd 			save();
    415       1.1      cgd 			break;
    416       1.1      cgd 		  case 'E':		/* Extrapolate */
    417       1.1      cgd #ifdef EXTRAP
    418       1.1      cgd 			if (last_ex)
    419       1.1      cgd 				break;
    420       1.1      cgd 			Finished = TRUE;
    421       1.1      cgd 			if (Window != W_FULL)
    422       1.1      cgd 				newscore();
    423       1.1      cgd 			prscore(FALSE);
    424       1.1      cgd 			wrefresh(Score);
    425       1.1      cgd 			last_ex = TRUE;
    426       1.1      cgd 			Finished = FALSE;
    427       1.1      cgd #else
    428       1.1      cgd 			error("%c: command not implemented", c);
    429       1.1      cgd #endif
    430       1.1      cgd 			break;
    431       1.1      cgd 		  case '\r':		/* Ignore RETURNs and	*/
    432       1.1      cgd 		  case '\n':		/* Line Feeds		*/
    433       1.1      cgd 		  case ' ':		/* Spaces		*/
    434       1.1      cgd 		  case '\0':		/* and nulls		*/
    435       1.1      cgd 			break;
    436       1.1      cgd #ifdef DEBUG
    437       1.1      cgd 		  case 'Z':		/* Debug code */
    438       1.1      cgd 			if (!Debug && outf == NULL) {
    439       1.1      cgd 				char	buf[MAXPATHLEN];
    440  1.13.2.1      jmc 				char	*sp;
    441       1.1      cgd 
    442       1.1      cgd 				prompt(FILEPROMPT);
    443       1.1      cgd 				leaveok(Board, FALSE);
    444       1.1      cgd 				refresh();
    445  1.13.2.1      jmc over:
    446       1.1      cgd 				sp = buf;
    447       1.1      cgd 				while ((*sp = readch()) != '\n') {
    448       1.1      cgd 					if (*sp == killchar())
    449       1.1      cgd 						goto over;
    450       1.1      cgd 					else if (*sp == erasechar()) {
    451       1.1      cgd 						if (--sp < buf)
    452       1.1      cgd 							sp = buf;
    453       1.1      cgd 						else {
    454       1.1      cgd 							addch('\b');
    455       1.1      cgd 							if (*sp < ' ')
    456       1.1      cgd 							    addch('\b');
    457       1.1      cgd 							clrtoeol();
    458       1.1      cgd 						}
    459       1.1      cgd 					}
    460       1.1      cgd 					else
    461       1.1      cgd 						addstr(unctrl(*sp++));
    462       1.1      cgd 					refresh();
    463       1.1      cgd 				}
    464       1.1      cgd 				*sp = '\0';
    465       1.1      cgd 				leaveok(Board, TRUE);
    466       1.1      cgd 				if ((outf = fopen(buf, "w")) == NULL)
    467       1.7    lukem 					warn("%s", buf);
    468       1.1      cgd 				setbuf(outf, (char *)NULL);
    469       1.1      cgd 			}
    470       1.1      cgd 			Debug = !Debug;
    471       1.1      cgd 			break;
    472       1.1      cgd #endif
    473       1.1      cgd 		  default:
    474       1.1      cgd 			error("unknown command: %s", unctrl(c));
    475       1.1      cgd 			break;
    476       1.1      cgd 		}
    477       1.1      cgd 	}
    478       1.1      cgd ret:
    479       1.1      cgd 	leaveok(Board, TRUE);
    480       1.1      cgd }
    481       1.7    lukem 
    482       1.1      cgd /*
    483       1.1      cgd  * return whether or not the player has picked
    484       1.1      cgd  */
    485       1.7    lukem int
    486       1.1      cgd haspicked(pp)
    487      1.10      jsm 	const PLAY	*pp;
    488       1.6      jtc {
    489       1.7    lukem 	int	card;
    490       1.1      cgd 
    491       1.1      cgd 	if (Topcard <= Deck)
    492       1.1      cgd 		return TRUE;
    493       1.1      cgd 	switch (pp->hand[Card_no]) {
    494       1.1      cgd 	  case C_GAS_SAFE:	case C_SPARE_SAFE:
    495       1.1      cgd 	  case C_DRIVE_SAFE:	case C_RIGHT_WAY:
    496       1.1      cgd 		card = 1;
    497       1.1      cgd 		break;
    498       1.1      cgd 	  default:
    499       1.1      cgd 		card = 0;
    500       1.1      cgd 		break;
    501       1.1      cgd 	}
    502       1.1      cgd 	return (pp->hand[card] != C_INIT);
    503       1.1      cgd }
    504       1.1      cgd 
    505       1.7    lukem void
    506       1.1      cgd account(card)
    507       1.7    lukem 	CARD	card;
    508       1.6      jtc {
    509       1.7    lukem 	CARD	oppos;
    510       1.1      cgd 
    511       1.1      cgd 	if (card == C_INIT)
    512       1.1      cgd 		return;
    513       1.1      cgd 	++Numseen[card];
    514       1.1      cgd 	if (Play == COMP)
    515       1.1      cgd 		switch (card) {
    516       1.1      cgd 		  case C_GAS_SAFE:
    517       1.1      cgd 		  case C_SPARE_SAFE:
    518       1.1      cgd 		  case C_DRIVE_SAFE:
    519       1.1      cgd 			oppos = opposite(card);
    520       1.1      cgd 			Numgos += Numcards[oppos] - Numseen[oppos];
    521       1.1      cgd 			break;
    522       1.1      cgd 		  case C_CRASH:
    523       1.1      cgd 		  case C_FLAT:
    524       1.1      cgd 		  case C_EMPTY:
    525       1.1      cgd 		  case C_STOP:
    526       1.1      cgd 			Numgos++;
    527       1.1      cgd 			break;
    528       1.1      cgd 		}
    529       1.1      cgd }
    530       1.1      cgd 
    531       1.7    lukem void
    532       1.1      cgd prompt(promptno)
    533       1.7    lukem 	int	promptno;
    534       1.1      cgd {
    535      1.10      jsm 	static const char	*const names[] = {
    536       1.1      cgd 				">>:Move:",
    537       1.1      cgd 				"Really?",
    538       1.1      cgd 				"Another hand?",
    539       1.1      cgd 				"Another game?",
    540       1.1      cgd 				"Save game?",
    541       1.1      cgd 				"Same file?",
    542       1.1      cgd 				"file:",
    543       1.1      cgd 				"Extension?",
    544       1.1      cgd 				"Overwrite file?",
    545       1.1      cgd 			};
    546       1.1      cgd 	static int	last_prompt = -1;
    547       1.1      cgd 
    548       1.1      cgd 	if (promptno == last_prompt)
    549       1.1      cgd 		move(MOVE_Y, MOVE_X + strlen(names[promptno]) + 1);
    550       1.1      cgd 	else {
    551       1.1      cgd 		move(MOVE_Y, MOVE_X);
    552       1.1      cgd 		if (promptno == MOVEPROMPT)
    553       1.1      cgd 			standout();
    554       1.1      cgd 		addstr(names[promptno]);
    555       1.1      cgd 		if (promptno == MOVEPROMPT)
    556       1.1      cgd 			standend();
    557       1.1      cgd 		addch(' ');
    558       1.1      cgd 		last_prompt = promptno;
    559       1.1      cgd 	}
    560       1.1      cgd 	clrtoeol();
    561       1.1      cgd }
    562       1.1      cgd 
    563       1.7    lukem void
    564       1.1      cgd sort(hand)
    565       1.7    lukem 	CARD	*hand;
    566       1.1      cgd {
    567       1.7    lukem 	CARD	*cp, *tp;
    568       1.7    lukem 	CARD	temp;
    569       1.1      cgd 
    570       1.1      cgd 	cp = hand;
    571       1.1      cgd 	hand += HAND_SZ;
    572       1.1      cgd 	for ( ; cp < &hand[-1]; cp++)
    573       1.1      cgd 		for (tp = cp + 1; tp < hand; tp++)
    574       1.1      cgd 			if (*cp > *tp) {
    575       1.1      cgd 				temp = *cp;
    576       1.1      cgd 				*cp = *tp;
    577       1.1      cgd 				*tp = temp;
    578       1.1      cgd 			}
    579       1.1      cgd }
    580