fixed clear lastline when quitting
[unix-history] / usr / src / games / sail / pl_1.c
CommitLineData
c77f0542 1#ifndef lint
a466c703 2static char *sccsid = "@(#)pl_1.c 2.3 83/11/02";
c77f0542 3#endif
7fc06086 4
c77f0542
CL
5#include "player.h"
6#include <sys/types.h>
6c17b19a 7#include <sys/wait.h>
c77f0542 8
b3a57661 9int choke(), child();
c77f0542 10
a466c703
EW
11static char hasdriver;
12
b3a57661
EW
13/*ARGSUSED*/
14main(argc, argv)
15int argc;
16char **argv;
c77f0542 17{
b3a57661 18 char nodrive = 0, randomize = 0, debug = 0;
b3a57661 19 extern char _sobuf[];
c77f0542 20
b3a57661 21 setbuf(stdout, _sobuf);
9224751f 22 isplayer = 1;
7fc06086 23
b3a57661
EW
24 while (*++argv && **argv == '-')
25 switch (*++*argv) {
26 case 'd':
27 nodrive = 1;
28 break;
29 case 'D':
30 debug++;
31 break;
32 case 'x':
33 randomize = 1;
34 break;
35 default:
36 printf("Unknown flag '%s'\n",*argv);
37 break;
7fc06086 38 }
b3a57661
EW
39 if (*argv)
40 game = atoi(*argv);
41 else
42 game = -1;
43 initialize(nodrive, randomize, debug);
44 Signal("Aye aye, Sir", (struct ship *)0);
fe0cae24 45 play();
c77f0542
CL
46}
47
bba7bfeb
BJ
48initialize(nodriver, randomize, debug)
49char randomize, nodriver, debug;
c77f0542 50{
b3a57661
EW
51 register struct File *fp;
52 register struct ship *sp;
6c17b19a 53 char captain[80];
7fc06086 54 char message[60];
b3a57661 55 int load;
7fc06086 56 register int n;
7fc06086 57 char *nameptr;
b3a57661 58 int nat[NNATION];
c77f0542 59
b3a57661 60 (void) srand(getpid());
c77f0542 61
7fc06086 62 if (game < 0) {
b3a57661
EW
63 (void) puts("Choose a scenario:\n");
64 (void) puts("\n\tNUMBER\tSHIPS\tIN PLAY\tTITLE");
65 for (n = 0; n < NSCENE; n++) {
6c17b19a
EW
66 /* ( */
67 printf("\t%d):\t%d\t%s\t%s\n", n, scene[n].vessels,
68 sync_exists(n) ? "YES" : "no",
69 scene[n].name);
7fc06086 70 }
c77f0542 71reprint:
7fc06086 72 printf("\nScenario number? ");
b3a57661
EW
73 (void) fflush(stdout);
74 (void) scanf("%d", &game);
75 while (getchar() != '\n')
76 ;
7fc06086 77 }
b3a57661
EW
78 if (game < 0 || game >= NSCENE) {
79 (void) puts("Very funny.");
7fc06086
BJ
80 exit(1);
81 }
b3a57661
EW
82 cc = &scene[game];
83 ls = cc->ship + cc->vessels;
84
b3a57661
EW
85 for (n = 0; n < NNATION; n++)
86 nat[n] = 0;
87 foreachship(sp) {
88 sp->file = (struct File *) calloc(1, sizeof (struct File));
89 if (sp->file == NULL) {
90 (void) puts("OUT OF MEMORY");
7fc06086
BJ
91 exit(0);
92 }
b3a57661 93 sp->file->stern = nat[sp->nationality]++;
0c30e1ed
EW
94 sp->file->dir = sp->shipdir;
95 sp->file->row = sp->shiprow;
96 sp->file->col = sp->shipcol;
c77f0542 97 }
0c30e1ed
EW
98 windspeed = cc->windspeed;
99 winddir = cc->winddir;
6c17b19a 100
a466c703
EW
101 (void) signal(SIGHUP, choke);
102 (void) signal(SIGINT, choke);
103 (void) signal(SIGQUIT, choke);
104
105 hasdriver = sync_exists(game);
106 if (sync_open() < 0) {
107 perror("sail: syncfile");
108 exit(1);
109 }
110
111 if (hasdriver) {
b3a57661
EW
112 (void) puts("Synchronizing with the other players...");
113 (void) fflush(stdout);
114 Sync();
6c17b19a
EW
115 }
116 for (;;) {
117 foreachship(sp)
118 if (sp->file->captain[0] == 0 && !sp->file->struck
119 && sp->file->captured == 0)
b3a57661 120 break;
b3a57661
EW
121 if (sp >= ls) {
122 (void) puts("All ships taken in that scenario.");
123 foreachship(sp)
124 free((char *)sp->file);
6c17b19a 125 sync_close(0);
7fc06086 126 people = 0;
7fc06086
BJ
127 goto reprint;
128 }
ef6b2809 129 if (randomize) {
6c17b19a 130 player = sp - cc->ship;
7fc06086 131 } else {
6c17b19a
EW
132 printf("%s\n\n", cc->name);
133 foreachship(sp)
134 printf(" %2d: %-10s %-15s (%-2d pts) %s\n",
135 sp - SHIP(0),
136 countryname[sp->nationality],
137 sp->shipname,
138 sp->specs->pts,
139 saywhat(sp, 1));
140 printf("\nWhich ship (0-%d)? ", cc->vessels-1);
141 (void) fflush(stdout);
142 if (scanf("%d", &player) != 1 || player < 0
143 || player >= cc->vessels) {
144 while (getchar() != '\n')
145 ;
146 (void) puts("Say what?");
147 player = -1;
148 } else
149 while (getchar() != '\n')
150 ;
7fc06086 151 }
6c17b19a
EW
152 if (player < 0)
153 continue;
154 Sync();
155 fp = SHIP(player)->file;
156 if (fp->captain[0] || fp->struck || fp->captured != 0)
157 (void) puts("That ship is taken.");
158 else
159 break;
c77f0542 160 }
7fc06086 161
b3a57661
EW
162 ms = SHIP(player);
163 mf = ms->file;
164 mc = ms->specs;
7fc06086 165
6c17b19a 166 Write(W_BEGIN, ms, 0, 0, 0, 0, 0);
b3a57661 167 Sync();
a466c703
EW
168
169 (void) signal(SIGCHLD, child);
170 if (!hasdriver && !nodriver) {
171 char num[10];
172 (void) sprintf(num, "%d", game);
173 switch (fork()) {
174 case 0:
175 execl(DRIVER1, DRIVERNAME, num, 0);
176 execl(DRIVER2, DRIVERNAME, num, 0);
177 execl(DRIVER3, DRIVERNAME, num, 0);
178 perror(DRIVERNAME);
179 exit(1);
180 break;
181 case -1:
182 perror("fork");
183 leave(LEAVE_QUIT);
184 break;
185 default:
186 hasdriver++;
187 }
188 }
189
b3a57661
EW
190 printf("Your ship is the %s, a %d gun %s (%s crew).\n",
191 ms->shipname, mc->guns, classname[mc->class],
192 qualname[mc->qual]);
193 if ((nameptr = (char *) getenv("SAILNAME")) && *nameptr)
194 (void) strncpy(captain, nameptr, sizeof captain);
7fc06086 195 else {
b3a57661
EW
196 (void) printf("Your name, Captain? ");
197 (void) fflush(stdout);
198 (void) gets(captain);
199 if (!*captain)
200 (void) strcpy(captain, "no name");
c77f0542 201 }
b3a57661 202 captain[sizeof captain - 1] = '\0';
6c17b19a 203 Write(W_CAPTAIN, ms, 1, (int)captain, 0, 0, 0);
b3a57661 204 for (n = 0; n < 2; n++) {
6c17b19a
EW
205 char buf[10];
206
b3a57661
EW
207 printf("\nInitial broadside %s (grape, chain, round, double): ",
208 n ? "right" : "left");
209 (void) fflush(stdout);
6c17b19a
EW
210 (void) scanf("%s", buf);
211 switch (*buf) {
7fc06086 212 case 'g':
b3a57661 213 load = L_GRAPE;
7fc06086
BJ
214 break;
215 case 'c':
b3a57661 216 load = L_CHAIN;
7fc06086
BJ
217 break;
218 case 'r':
b3a57661 219 load = L_ROUND;
7fc06086
BJ
220 break;
221 case 'd':
b3a57661 222 load = L_DOUBLE;
7fc06086 223 break;
b3a57661
EW
224 default:
225 load = L_ROUND;
7fc06086 226 }
b3a57661
EW
227 if (n) {
228 mf->loadR = load;
229 mf->readyR = R_LOADED|R_INITIAL;
7fc06086 230 } else {
b3a57661
EW
231 mf->loadL = load;
232 mf->readyL = R_LOADED|R_INITIAL;
7fc06086 233 }
c77f0542 234 }
7fc06086 235
b3a57661 236 initscreen();
fe0cae24 237 draw_board();
b3a57661
EW
238 (void) sprintf(message, "Captain %s assuming command", captain);
239 Write(W_SIGNAL, ms, 1, (int)message, 0, 0, 0);
b3a57661 240 newturn();
c77f0542
CL
241}
242
a466c703
EW
243/*
244 * If we get here before a ship is chosen, then ms == 0 and
245 * we don't want to update the score file, or do any Write's either.
246 * We can assume the sync file is already created and may need
247 * to be removed.
248 */
b3a57661
EW
249leave(conditions)
250int conditions;
c77f0542 251{
b3a57661 252 FILE *fp;
ef6b2809 253 int persons;
b3a57661 254 float net;
b3a57661
EW
255 char message[60];
256 register int n;
257 struct logs log[10], temp;
c77f0542 258
b3a57661
EW
259 (void) signal(SIGHUP, SIG_IGN);
260 (void) signal(SIGINT, SIG_IGN);
261 (void) signal(SIGQUIT, SIG_IGN);
262 (void) signal(SIGALRM, SIG_IGN);
263 (void) signal(SIGCHLD, SIG_IGN);
c77f0542 264
a466c703
EW
265 if (done_curses) {
266 Signal("It looks like you've had it!",
267 (struct ship *)0);
268 switch (conditions) {
269 case LEAVE_QUIT:
270 break;
271 case LEAVE_CAPTURED:
272 Signal("Your ship was captured.",
273 (struct ship *)0);
274 break;
275 case LEAVE_HURRICAN:
276 Signal("Hurricane! All ships destroyed.",
277 (struct ship *)0);
278 break;
279 case LEAVE_DRIVER:
280 /* don't clear 'hasdriver' here */
281 Signal("The driver died.", (struct ship *)0);
282 break;
283 default:
284 Signal("A funny thing happened (%d).",
285 (struct ship *)0, conditions);
286 }
287 } else {
288 switch (conditions) {
289 case LEAVE_QUIT:
290 break;
291 case LEAVE_DRIVER:
292 printf("The driver died.\n");
293 break;
294 case LEAVE_FORK:
295 hasdriver = 0;
296 printf("Can't fork.\n");
297 break;
298 default:
299 printf("A funny thing happened (%d).\n",
300 conditions);
301 }
302 }
303
304 if (ms != 0) {
b3a57661
EW
305 if (fp = fopen(LOGFILE, "r+")) {
306 net = (float)mf->points / mc->pts;
ef6b2809 307 persons = getw(fp);
b3a57661
EW
308 n = fread((char *)log, sizeof(struct logs), 10, fp);
309 for (; n < 10; n++)
310 log[n].l_name[0]
311 = log[n].l_uid
312 = log[n].l_shipnum
313 = log[n].l_gamenum
314 = log[n].l_netpoints = 0;
315 rewind(fp);
ef6b2809 316 if (persons < 0)
b3a57661
EW
317 (void) putw(1, fp);
318 else
ef6b2809 319 (void) putw(persons + 1, fp);
b3a57661
EW
320 for (n = 0; n < 10; n++)
321 if (net > (float) log[n].l_netpoints / scene[log[n].l_gamenum].ship[log[n].l_shipnum].specs->pts) {
322 (void) fwrite((char *)log,
323 sizeof (struct logs), n, fp);
6c17b19a 324 (void) strcpy(temp.l_name, mf->captain);
b3a57661
EW
325 temp.l_uid = getuid();
326 temp.l_shipnum = player;
327 temp.l_gamenum = game;
328 temp.l_netpoints = mf->points;
329 (void) fwrite((char *)&temp,
330 sizeof temp, 1, fp);
331 (void) fwrite((char *)&log[n],
332 sizeof (struct logs), 9-n, fp);
333 break;
334 }
335 (void) fclose(fp);
7fc06086 336 }
a466c703 337 makesignal(ms, "Captain %s relinquishing.", (struct ship *)0,
ef6b2809 338 mf->captain);
ef6b2809 339 Write(W_END, ms, 0, 0, 0, 0, 0);
6c17b19a 340 Sync();
b3a57661 341 }
a466c703 342 sync_close(!hasdriver);
fe0cae24 343 cleanupscreen();
b3a57661 344 exit(0);
7fc06086 345}
c77f0542 346
b3a57661 347choke()
c77f0542 348{
b3a57661 349 leave(LEAVE_QUIT);
c77f0542
CL
350}
351
b3a57661 352child()
c77f0542 353{
b3a57661
EW
354 union wait status;
355 int pid;
c77f0542 356
b3a57661
EW
357 (void) signal(SIGCHLD, SIG_IGN);
358 do {
359 pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
360 if (pid < 0 || pid > 0 && !WIFSTOPPED(status))
361 leave(LEAVE_DRIVER);
362 } while (pid != 0);
363 (void) signal(SIGCHLD, child);
c77f0542 364}