xref: /netbsd-src/games/robots/main.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: main.c,v 1.21 2004/11/05 21:30:32 dsl Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
35 	The Regents of the University of California.  All rights reserved.\n");
36 #endif /* not lint */
37 
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 5/31/93";
41 #else
42 __RCSID("$NetBSD: main.c,v 1.21 2004/11/05 21:30:32 dsl Exp $");
43 #endif
44 #endif /* not lint */
45 
46 # include	"robots.h"
47 
48 int main(int, char **);
49 
50 extern const char	*Scorefile;
51 extern int	Max_per_uid;
52 
53 int
54 main(ac, av)
55 	int	ac;
56 	char	**av;
57 {
58 	const char	*sp;
59 	bool	bad_arg;
60 	bool	show_only;
61 	int		score_wfd; /* high score writable file descriptor */
62 	int		score_err = 0; /* hold errno from score file open */
63 
64 	score_wfd = open(Scorefile, O_RDWR);
65 	if (score_wfd < 0)
66 		score_err = errno;
67 	else if (score_wfd < 3)
68 		exit(1);
69 
70 	/* Revoke setgid privileges */
71 	setgid(getgid());
72 
73 	show_only = FALSE;
74 	Num_games = 1;
75 	if (ac > 1) {
76 		bad_arg = FALSE;
77 		for (++av; ac > 1 && *av[0]; av++, ac--)
78 			if (av[0][0] != '-')
79 				if (isdigit((unsigned char)av[0][0]))
80 					Max_per_uid = atoi(av[0]);
81 				else {
82 					Scorefile = av[0];
83 					if (score_wfd >= 0)
84 						close(score_wfd);
85 					score_wfd = open(Scorefile, O_RDWR);
86 					if (score_wfd < 0)
87 						score_err = errno;
88 # ifdef	FANCY
89 					sp = strrchr(Scorefile, '/');
90 					if (sp == NULL)
91 						sp = Scorefile;
92 					if (strcmp(sp, "pattern_roll") == 0)
93 						Pattern_roll = TRUE;
94 					else if (strcmp(sp, "stand_still") == 0)
95 						Stand_still = TRUE;
96 					if (Pattern_roll || Stand_still)
97 						Teleport = TRUE;
98 # endif
99 				}
100 			else
101 				for (sp = &av[0][1]; *sp; sp++)
102 					switch (*sp) {
103 					  case 'A':
104 						Auto_bot = TRUE;
105 						break;
106 					  case 's':
107 						show_only = TRUE;
108 						break;
109 					  case 'r':
110 						Real_time = TRUE;
111 						break;
112 					  case 'a':
113 						Start_level = 4;
114 						break;
115 					  case 'n':
116 						Num_games++;
117 						break;
118 					  case 'j':
119 						Jump = TRUE;
120 						break;
121 					  case 't':
122 						Teleport = TRUE;
123 						break;
124 
125 					  default:
126 						fprintf(stderr, "robots: unknown option: %c\n", *sp);
127 						bad_arg = TRUE;
128 						break;
129 					}
130 		if (bad_arg) {
131 			exit(1);
132 			/* NOTREACHED */
133 		}
134 	}
135 
136 	if (show_only) {
137 		show_score();
138 		exit(0);
139 		/* NOTREACHED */
140 	}
141 
142 	if (score_wfd < 0) {
143 		errno = score_err;
144 		warn("%s", Scorefile);
145 		warnx("High scores will not be recorded!");
146 		sleep(2);
147 	}
148 
149 	initscr();
150 	signal(SIGINT, quit);
151 	cbreak();
152 	noecho();
153 	nonl();
154 	if (LINES != Y_SIZE || COLS != X_SIZE) {
155 		if (LINES < Y_SIZE || COLS < X_SIZE) {
156 			endwin();
157 			printf("Need at least a %dx%d screen\n",
158 			    Y_SIZE, X_SIZE);
159 			exit(1);
160 		}
161 		delwin(stdscr);
162 		stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
163 	}
164 
165 	srand(getpid());
166 	if (Real_time)
167 		signal(SIGALRM, move_robots);
168 	do {
169 		while (Num_games--) {
170 			init_field();
171 			for (Level = Start_level; !Dead; Level++) {
172 				make_level();
173 				play_level();
174 				if (Auto_bot)
175 					sleep(1);
176 			}
177 			move(My_pos.y, My_pos.x);
178 			printw("AARRrrgghhhh....");
179 			refresh();
180 			if (Auto_bot)
181 				sleep(1);
182 			score(score_wfd);
183 			if (Auto_bot)
184 				sleep(1);
185 			refresh();
186 		}
187 		Num_games = 1;
188 	} while (!Auto_bot && another());
189 	quit(0);
190 	/* NOTREACHED */
191 	return(0);
192 }
193 
194 /*
195  * quit:
196  *	Leave the program elegantly.
197  */
198 void
199 quit(dummy)
200 	int dummy __attribute__((__unused__));
201 {
202 	endwin();
203 	exit(0);
204 	/* NOTREACHED */
205 }
206 
207 /*
208  * another:
209  *	See if another game is desired
210  */
211 bool
212 another()
213 {
214 	int	y;
215 
216 #ifdef	FANCY
217 	if ((Stand_still || Pattern_roll) && !Newscore)
218 		return TRUE;
219 #endif
220 
221 	if (query("Another game?")) {
222 		if (Full_clear) {
223 			for (y = 1; y <= Num_scores; y++) {
224 				move(y, 1);
225 				clrtoeol();
226 			}
227 			refresh();
228 		}
229 		return TRUE;
230 	}
231 	return FALSE;
232 }
233