xref: /openbsd-src/games/monop/execute.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: execute.c,v 1.4 2000/06/30 16:00:04 millert Exp $	*/
2 /*	$NetBSD: execute.c,v 1.3 1995/03/23 08:34:38 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1980, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)execute.c	8.1 (Berkeley) 5/31/93";
40 #else
41 static char rcsid[] = "$OpenBSD: execute.c,v 1.4 2000/06/30 16:00:04 millert Exp $";
42 #endif
43 #endif /* not lint */
44 
45 #include	"monop.ext"
46 #include	<sys/types.h>
47 #include	<sys/stat.h>
48 #include	<sys/time.h>
49 #include	<err.h>
50 #include 	<fcntl.h>
51 #include	<stdlib.h>
52 #include	<unistd.h>
53 
54 #define	SEGSIZE	8192
55 
56 typedef	struct stat	STAT;
57 typedef	struct tm	TIME;
58 
59 static char	buf[257];
60 
61 static bool	new_play;	/* set if move on to new player		*/
62 
63 static void	show_move __P((void));
64 
65 /*
66  *	This routine takes user input and puts it in buf
67  */
68 void
69 getbuf()
70 {
71 	char	*sp;
72 	int	tmpin, i;
73 
74 	i = 0;
75 	sp = buf;
76 	while (((tmpin = getchar()) != '\n') && (i < sizeof(buf)) &&
77 	    (tmpin != EOF)) {
78 		*sp++ = tmpin;
79 		i++;
80 	}
81 	if (tmpin == EOF) {
82 		printf("user closed input stream, quitting...\n");
83                 exit(0);
84 	}
85 	*sp = '\0';
86 }
87 /*
88  *	This routine executes the given command by index number
89  */
90 void
91 execute(com_num)
92 	int	com_num;
93 {
94 	new_play = FALSE;	/* new_play is true if fixing	*/
95 	(*func[com_num])();
96 	notify();
97 	force_morg();
98 	if (new_play)
99 		next_play();
100 	else if (num_doub)
101 		printf("%s rolled doubles.  Goes again\n", cur_p->name);
102 }
103 /*
104  *	This routine moves a piece around.
105  */
106 void
107 do_move()
108 {
109 	int	r1, r2;
110 	bool	was_jail;
111 
112 	new_play = was_jail = FALSE;
113 	printf("roll is %d, %d\n", r1 = roll(1, 6), r2 = roll(1, 6));
114 	if (cur_p->loc == JAIL) {
115 		was_jail++;
116 		if (!move_jail(r1, r2)) {
117 			new_play++;
118 			goto ret;
119 		}
120 	}
121 	else {
122 		if (r1 == r2 && ++num_doub == 3) {
123 			printf("That's 3 doubles.  You go to jail\n");
124 			goto_jail();
125 			new_play++;
126 			goto ret;
127 		}
128 		move(r1 + r2);
129 	}
130 	if (r1 != r2 || was_jail)
131 		new_play++;
132 ret:
133 	return;
134 }
135 /*
136  *	This routine moves a normal move
137  */
138 void
139 move(rl)
140 	int	rl;
141 {
142 	int	old_loc;
143 
144 	old_loc = cur_p->loc;
145 	cur_p->loc = (cur_p->loc + rl) % N_SQRS;
146 	if (cur_p->loc < old_loc && rl > 0) {
147 		cur_p->money += 200;
148 		printf("You pass %s and get $200\n", board[0].name);
149 	}
150 	show_move();
151 }
152 /*
153  *	This routine shows the results of a move
154  */
155 static void
156 show_move()
157 {
158 	SQUARE	*sqp;
159 
160 	sqp = &board[cur_p->loc];
161 	printf("That puts you on %s\n", sqp->name);
162 	switch (sqp->type) {
163 	case SAFE:
164 		printf("That is a safe place\n");
165 		break;
166 	case CC:
167 		cc();
168 		break;
169 	case CHANCE:
170 		chance();
171 		break;
172 	case INC_TAX:
173 		inc_tax();
174 		break;
175 	case GOTO_J:
176 		goto_jail();
177 		break;
178 	case LUX_TAX:
179 		lux_tax();
180 		break;
181 	case PRPTY:
182 	case RR:
183 	case UTIL:
184 		if (sqp->owner < 0) {
185 			printf("That would cost $%d\n", sqp->cost);
186 			if (getyn("Do you want to buy? ") == 0) {
187 				buy(player, sqp);
188 				cur_p->money -= sqp->cost;
189 			}
190 			else if (num_play > 2)
191 				bid();
192 		}
193 		else if (sqp->owner == player)
194 			printf("You own it.\n");
195 		else
196 			rent(sqp);
197 	}
198 }
199 /*
200  *	This routine saves the current game for use at a later date
201  */
202 void
203 save()
204 {
205 	char		*sp;
206 	int		outf, num;
207 	time_t		t;
208 	struct stat	sb;
209 	char		*start, *end;
210 
211 	printf("Which file do you wish to save it in? ");
212 	getbuf();
213 
214 	/*
215 	 * check for existing files, and confirm overwrite if needed
216 	 */
217 
218 	if (stat(buf, &sb) == 0
219 	    && getyn("File exists.  Do you wish to overwrite? ") > 0)
220 		return;
221 
222 	if ((outf=creat(buf, 0644)) < 0) {
223 		warn("%s", buf);
224 		return;
225 	}
226 	printf("\"%s\" ", buf);
227 	time(&t);			/* get current time		*/
228 	strcpy(buf, ctime(&t));
229 	for (sp = buf; *sp != '\n'; sp++)
230 		continue;
231 	*sp = '\0';
232 #if 0
233 	start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE;
234 #else
235 	start = 0;
236 #endif
237 	end = sbrk(0);
238 	while (start < end) {		/* write out entire data space */
239 		num = start + 16 * 1024 > end ? end - start : 16 * 1024;
240 		write(outf, start, num);
241 		start += num;
242 	}
243 	close(outf);
244 	printf("[%s]\n", buf);
245 }
246 /*
247  *	This routine restores an old game from a file
248  */
249 void
250 restore()
251 {
252 	printf("Which file do you wish to restore from? ");
253 	getbuf();
254 	rest_f(buf);
255 }
256 /*
257  *	This does the actual restoring.  It returns TRUE if the
258  *	backup was successful, else FALSE.
259  */
260 int
261 rest_f(file)
262 	char	*file;
263 {
264 	char	*sp;
265 	int	inf, num;
266 	char	*start, *end;
267 	STAT	sbuf;
268 
269 	if ((inf = open(file, O_RDONLY)) < 0) {
270 		warn("%s", file);
271 		return FALSE;
272 	}
273 	printf("\"%s\" ", file);
274 	if (fstat(inf, &sbuf) < 0)		/* get file stats	*/
275 		err(1, "%s", file);
276 #if 0
277 	start = (((int) etext + (SEGSIZE-1)) / SEGSIZE ) * SEGSIZE;
278 #else
279 	start = 0;
280 #endif
281 	brk(end = start + sbuf.st_size);
282 	while (start < end) {		/* write out entire data space */
283 		num = start + 16 * 1024 > end ? end - start : 16 * 1024;
284 		read(inf, start, num);
285 		start += num;
286 	}
287 	close(inf);
288 	strcpy(buf, ctime(&sbuf.st_mtime));
289 	for (sp = buf; *sp != '\n'; sp++)
290 		continue;
291 	*sp = '\0';
292 	printf("[%s]\n", buf);
293 	return TRUE;
294 }
295