xref: /netbsd-src/games/robots/main.c (revision 02e7c0b99a693f449acda45780965a219fd37ff8)
1*02e7c0b9Schristos /*	$NetBSD: main.c,v 1.34 2022/06/27 18:48:49 christos Exp $	*/
26045e6e0Scgd 
361f28255Scgd /*
46045e6e0Scgd  * Copyright (c) 1980, 1993
56045e6e0Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
329007937fSlukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
342fe2731dSlukem __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
352fe2731dSlukem  The Regents of the University of California.  All rights reserved.");
3661f28255Scgd #endif /* not lint */
3761f28255Scgd 
3861f28255Scgd #ifndef lint
396045e6e0Scgd #if 0
406045e6e0Scgd static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 5/31/93";
416045e6e0Scgd #else
42*02e7c0b9Schristos __RCSID("$NetBSD: main.c,v 1.34 2022/06/27 18:48:49 christos Exp $");
436045e6e0Scgd #endif
4461f28255Scgd #endif /* not lint */
4561f28255Scgd 
46a4cc1f4fSdholland #include <ctype.h>
47a4cc1f4fSdholland #include <curses.h>
48*02e7c0b9Schristos #include <string.h>
49a4cc1f4fSdholland #include <err.h>
50a4cc1f4fSdholland #include <errno.h>
51a4cc1f4fSdholland #include <fcntl.h>
52a4cc1f4fSdholland #include <signal.h>
53a4cc1f4fSdholland #include <stdlib.h>
548a0aa42dSdholland #include <time.h>
55a4cc1f4fSdholland #include <unistd.h>
5661f28255Scgd #include "robots.h"
5761f28255Scgd 
581b1c2fdcSchristos extern const char *Scorefile;
591b1c2fdcSchristos extern int Max_per_uid;
601b1c2fdcSchristos 
615305281bSdholland static bool another(void);
625305281bSdholland 
639007937fSlukem int
main(int argc,char ** argv)64f5d4590cSdholland main(int argc, char **argv)
6561f28255Scgd {
66f5d4590cSdholland 	const char *word;
679007937fSlukem 	bool show_only;
685367f340Sjsm 	int score_wfd; /* high score writable file descriptor */
695367f340Sjsm 	int score_err = 0; /* hold errno from score file open */
70f5d4590cSdholland 	int maximum = 0;
714b76b450Schristos 	int ch, i;
725367f340Sjsm 
735367f340Sjsm 	score_wfd = open(Scorefile, O_RDWR);
745367f340Sjsm 	if (score_wfd < 0)
755367f340Sjsm 		score_err = errno;
765367f340Sjsm 	else if (score_wfd < 3)
775367f340Sjsm 		exit(1);
785367f340Sjsm 
795367f340Sjsm 	/* Revoke setgid privileges */
80f9eca697Smycroft 	setgid(getgid());
8161f28255Scgd 
82a4cc1f4fSdholland 	show_only = false;
8318dfb39eSchristos 	Num_games = 1;
84f5d4590cSdholland 
85f5d4590cSdholland 	while ((ch = getopt(argc, argv, "Aajnrst")) != -1) {
86f5d4590cSdholland 		switch (ch) {
87f5d4590cSdholland 		    case 'A':
88f5d4590cSdholland 			Auto_bot = true;
89f5d4590cSdholland 			break;
90f5d4590cSdholland 		    case 'a':
91f5d4590cSdholland 			Start_level = 4;
92f5d4590cSdholland 			break;
93f5d4590cSdholland 		    case 'j':
94f5d4590cSdholland 			Jump = true;
95f5d4590cSdholland 			break;
96f5d4590cSdholland 		    case 'n':
97f5d4590cSdholland 			Num_games++;
98f5d4590cSdholland 			break;
99f5d4590cSdholland 		    case 'r':
100f5d4590cSdholland 			Real_time = true;
101f5d4590cSdholland 			break;
102f5d4590cSdholland 		    case 's':
103f5d4590cSdholland 			show_only = true;
104f5d4590cSdholland 			break;
105f5d4590cSdholland 		    case 't':
106f5d4590cSdholland 			Teleport = true;
107f5d4590cSdholland 			break;
108f5d4590cSdholland 		    default:
109f5d4590cSdholland 			errx(1,
110f5d4590cSdholland 			    "Usage: robots [-Aajnrst] [maximum] [scorefile]");
111f5d4590cSdholland 			break;
112f5d4590cSdholland 		}
113f5d4590cSdholland 	}
114f5d4590cSdholland 
115f5d4590cSdholland 	for (i = optind; i < argc; i++) {
116f5d4590cSdholland 		word = argv[i];
117f5d4590cSdholland 		if (isdigit((unsigned char)word[0])) {
118f5d4590cSdholland 			maximum = atoi(word);
119f5d4590cSdholland 		} else {
120f5d4590cSdholland 			Scorefile = word;
121f5d4590cSdholland 			Max_per_uid = maximum;
1225367f340Sjsm 			if (score_wfd >= 0)
1235367f340Sjsm 				close(score_wfd);
1245367f340Sjsm 			score_wfd = open(Scorefile, O_RDWR);
1255367f340Sjsm 			if (score_wfd < 0)
1265367f340Sjsm 				score_err = errno;
12761f28255Scgd #ifdef FANCY
128f5d4590cSdholland 			word = strrchr(Scorefile, '/');
129f5d4590cSdholland 			if (word == NULL)
130f5d4590cSdholland 				word = Scorefile;
131f5d4590cSdholland 			if (strcmp(word, "pattern_roll") == 0)
132a4cc1f4fSdholland 				Pattern_roll = true;
133f5d4590cSdholland 			else if (strcmp(word, "stand_still") == 0)
134a4cc1f4fSdholland 				Stand_still = true;
13561f28255Scgd 			if (Pattern_roll || Stand_still)
136a4cc1f4fSdholland 				Teleport = true;
13761f28255Scgd #endif
13861f28255Scgd 		}
13961f28255Scgd 	}
14061f28255Scgd 
14161f28255Scgd 	if (show_only) {
14261f28255Scgd 		show_score();
14361f28255Scgd 		exit(0);
14461f28255Scgd 		/* NOTREACHED */
14561f28255Scgd 	}
14661f28255Scgd 
1475367f340Sjsm 	if (score_wfd < 0) {
1485367f340Sjsm 		errno = score_err;
1495367f340Sjsm 		warn("%s", Scorefile);
1505367f340Sjsm 		warnx("High scores will not be recorded!");
1515367f340Sjsm 		sleep(2);
1525367f340Sjsm 	}
1535367f340Sjsm 
154432ec044Sdrochner 	if (!initscr())
155432ec044Sdrochner 		errx(0, "couldn't initialize screen");
15661f28255Scgd 	signal(SIGINT, quit);
157d82bd70cSblymn 	cbreak();
15861f28255Scgd 	noecho();
15961f28255Scgd 	nonl();
16061f28255Scgd 	if (LINES != Y_SIZE || COLS != X_SIZE) {
16161f28255Scgd 		if (LINES < Y_SIZE || COLS < X_SIZE) {
16261f28255Scgd 			endwin();
16361f28255Scgd 			printf("Need at least a %dx%d screen\n",
16461f28255Scgd 			    Y_SIZE, X_SIZE);
16561f28255Scgd 			exit(1);
16661f28255Scgd 		}
16761f28255Scgd 		delwin(stdscr);
16861f28255Scgd 		stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
16961f28255Scgd 	}
17061f28255Scgd 
17161f28255Scgd 	if (Real_time)
17261f28255Scgd 		signal(SIGALRM, move_robots);
17361f28255Scgd 	do {
17418dfb39eSchristos 		while (Num_games--) {
17561f28255Scgd 			init_field();
17661f28255Scgd 			for (Level = Start_level; !Dead; Level++) {
17761f28255Scgd 				make_level();
17861f28255Scgd 				play_level();
17918dfb39eSchristos 				if (Auto_bot)
18018dfb39eSchristos 					sleep(1);
18161f28255Scgd 			}
18261f28255Scgd 			move(My_pos.y, My_pos.x);
18361f28255Scgd 			printw("AARRrrgghhhh....");
18461f28255Scgd 			refresh();
18518dfb39eSchristos 			if (Auto_bot)
18618dfb39eSchristos 				sleep(1);
1875367f340Sjsm 			score(score_wfd);
18818dfb39eSchristos 			if (Auto_bot)
18918dfb39eSchristos 				sleep(1);
19018dfb39eSchristos 			refresh();
19118dfb39eSchristos 		}
1925c54ba1bSjsm 		Num_games = 1;
19318dfb39eSchristos 	} while (!Auto_bot && another());
1949007937fSlukem 	quit(0);
1959007937fSlukem 	/* NOTREACHED */
1969007937fSlukem 	return(0);
19761f28255Scgd }
19861f28255Scgd 
19961f28255Scgd /*
20061f28255Scgd  * quit:
20161f28255Scgd  *	Leave the program elegantly.
20261f28255Scgd  */
20361f28255Scgd void
quit(int dummy __unused)20430870bd5Sdholland quit(int dummy __unused)
20561f28255Scgd {
20661f28255Scgd 	endwin();
20761f28255Scgd 	exit(0);
20861f28255Scgd 	/* NOTREACHED */
20961f28255Scgd }
21061f28255Scgd 
21161f28255Scgd /*
21261f28255Scgd  * another:
21361f28255Scgd  *	See if another game is desired
21461f28255Scgd  */
2155305281bSdholland static bool
another(void)21630870bd5Sdholland another(void)
21761f28255Scgd {
2189007937fSlukem 	int y;
21961f28255Scgd 
22061f28255Scgd #ifdef FANCY
22161f28255Scgd 	if ((Stand_still || Pattern_roll) && !Newscore)
222a4cc1f4fSdholland 		return true;
22361f28255Scgd #endif
22461f28255Scgd 
22561f28255Scgd 	if (query("Another game?")) {
22661f28255Scgd 		if (Full_clear) {
22761f28255Scgd 			for (y = 1; y <= Num_scores; y++) {
22861f28255Scgd 				move(y, 1);
22961f28255Scgd 				clrtoeol();
23061f28255Scgd 			}
23161f28255Scgd 			refresh();
23261f28255Scgd 		}
233a4cc1f4fSdholland 		return true;
23461f28255Scgd 	}
235a4cc1f4fSdholland 	return false;
23661f28255Scgd }
237