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