1 /* $NetBSD: main.c,v 1.34 2022/06/27 18:48:49 christos 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\
35 The Regents of the University of California. All rights reserved.");
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.34 2022/06/27 18:48:49 christos Exp $");
43 #endif
44 #endif /* not lint */
45
46 #include <ctype.h>
47 #include <curses.h>
48 #include <string.h>
49 #include <err.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <signal.h>
53 #include <stdlib.h>
54 #include <time.h>
55 #include <unistd.h>
56 #include "robots.h"
57
58 extern const char *Scorefile;
59 extern int Max_per_uid;
60
61 static bool another(void);
62
63 int
main(int argc,char ** argv)64 main(int argc, char **argv)
65 {
66 const char *word;
67 bool show_only;
68 int score_wfd; /* high score writable file descriptor */
69 int score_err = 0; /* hold errno from score file open */
70 int maximum = 0;
71 int ch, i;
72
73 score_wfd = open(Scorefile, O_RDWR);
74 if (score_wfd < 0)
75 score_err = errno;
76 else if (score_wfd < 3)
77 exit(1);
78
79 /* Revoke setgid privileges */
80 setgid(getgid());
81
82 show_only = false;
83 Num_games = 1;
84
85 while ((ch = getopt(argc, argv, "Aajnrst")) != -1) {
86 switch (ch) {
87 case 'A':
88 Auto_bot = true;
89 break;
90 case 'a':
91 Start_level = 4;
92 break;
93 case 'j':
94 Jump = true;
95 break;
96 case 'n':
97 Num_games++;
98 break;
99 case 'r':
100 Real_time = true;
101 break;
102 case 's':
103 show_only = true;
104 break;
105 case 't':
106 Teleport = true;
107 break;
108 default:
109 errx(1,
110 "Usage: robots [-Aajnrst] [maximum] [scorefile]");
111 break;
112 }
113 }
114
115 for (i = optind; i < argc; i++) {
116 word = argv[i];
117 if (isdigit((unsigned char)word[0])) {
118 maximum = atoi(word);
119 } else {
120 Scorefile = word;
121 Max_per_uid = maximum;
122 if (score_wfd >= 0)
123 close(score_wfd);
124 score_wfd = open(Scorefile, O_RDWR);
125 if (score_wfd < 0)
126 score_err = errno;
127 #ifdef FANCY
128 word = strrchr(Scorefile, '/');
129 if (word == NULL)
130 word = Scorefile;
131 if (strcmp(word, "pattern_roll") == 0)
132 Pattern_roll = true;
133 else if (strcmp(word, "stand_still") == 0)
134 Stand_still = true;
135 if (Pattern_roll || Stand_still)
136 Teleport = true;
137 #endif
138 }
139 }
140
141 if (show_only) {
142 show_score();
143 exit(0);
144 /* NOTREACHED */
145 }
146
147 if (score_wfd < 0) {
148 errno = score_err;
149 warn("%s", Scorefile);
150 warnx("High scores will not be recorded!");
151 sleep(2);
152 }
153
154 if (!initscr())
155 errx(0, "couldn't initialize screen");
156 signal(SIGINT, quit);
157 cbreak();
158 noecho();
159 nonl();
160 if (LINES != Y_SIZE || COLS != X_SIZE) {
161 if (LINES < Y_SIZE || COLS < X_SIZE) {
162 endwin();
163 printf("Need at least a %dx%d screen\n",
164 Y_SIZE, X_SIZE);
165 exit(1);
166 }
167 delwin(stdscr);
168 stdscr = newwin(Y_SIZE, X_SIZE, 0, 0);
169 }
170
171 if (Real_time)
172 signal(SIGALRM, move_robots);
173 do {
174 while (Num_games--) {
175 init_field();
176 for (Level = Start_level; !Dead; Level++) {
177 make_level();
178 play_level();
179 if (Auto_bot)
180 sleep(1);
181 }
182 move(My_pos.y, My_pos.x);
183 printw("AARRrrgghhhh....");
184 refresh();
185 if (Auto_bot)
186 sleep(1);
187 score(score_wfd);
188 if (Auto_bot)
189 sleep(1);
190 refresh();
191 }
192 Num_games = 1;
193 } while (!Auto_bot && another());
194 quit(0);
195 /* NOTREACHED */
196 return(0);
197 }
198
199 /*
200 * quit:
201 * Leave the program elegantly.
202 */
203 void
quit(int dummy __unused)204 quit(int dummy __unused)
205 {
206 endwin();
207 exit(0);
208 /* NOTREACHED */
209 }
210
211 /*
212 * another:
213 * See if another game is desired
214 */
215 static bool
another(void)216 another(void)
217 {
218 int y;
219
220 #ifdef FANCY
221 if ((Stand_still || Pattern_roll) && !Newscore)
222 return true;
223 #endif
224
225 if (query("Another game?")) {
226 if (Full_clear) {
227 for (y = 1; y <= Num_scores; y++) {
228 move(y, 1);
229 clrtoeol();
230 }
231 refresh();
232 }
233 return true;
234 }
235 return false;
236 }
237