1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44: #include <sys/cdefs.h>
45: #ifndef lint
46: #if 0
47: static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 5/31/93";
48: #else
49: __RCSID("$NetBSD: update.c,v 1.12 2003/08/07 09:36:55 agc Exp $");
50: #endif
51: #endif
52:
53: #include "include.h"
54:
55: void
56: update(dummy)
57: int dummy __attribute__((__unused__));
58: {
59: int i, dir_diff, unclean;
60: PLANE *pp, *p1, *p2;
61:
62: #ifdef SYSV
63: alarm(0);
64: signal(SIGALRM, update);
65: #endif
66:
67: clck++;
68:
69: erase_all();
70:
71:
72: do {
73: unclean = 0;
74: for (pp = ground.head; pp != NULL; pp = pp->next) {
75: if (pp->new_altitude > 0) {
76: delete(&ground, pp);
77: append(&air, pp);
78: unclean = 1;
79: break;
80: }
81: }
82: } while (unclean);
83:
84:
85: for (pp = air.head; pp != NULL; pp = pp->next) {
86:
87: if (pp->plane_type == 0 && clck & 1)
88: continue;
89:
90: pp->fuel--;
91: if (pp->fuel < 0)
92: loser(pp, "ran out of fuel.");
93:
94: pp->altitude += SGN(pp->new_altitude - pp->altitude);
95:
96: if (!pp->delayd) {
97: dir_diff = pp->new_dir - pp->dir;
98:
99:
100:
101: if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
102: if (dir_diff > MAXDIR/2)
103: dir_diff -= MAXDIR;
104: else if (dir_diff < -(MAXDIR/2))
105: dir_diff += MAXDIR;
106: }
107: if (dir_diff > 2)
108: dir_diff = 2;
109: else if (dir_diff < -2)
110: dir_diff = -2;
111: pp->dir += dir_diff;
112: if (pp->dir >= MAXDIR)
113: pp->dir -= MAXDIR;
114: else if (pp->dir < 0)
115: pp->dir += MAXDIR;
116: }
117: pp->xpos += displacement[pp->dir].dx;
118: pp->ypos += displacement[pp->dir].dy;
119:
120: if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
121: pp->ypos == sp->beacon[pp->delayd_no].y) {
122: pp->delayd = 0;
123: if (pp->status == S_UNMARKED)
124: pp->status = S_MARKED;
125: }
126:
127: switch (pp->dest_type) {
128: case T_AIRPORT:
129: if (pp->xpos == sp->airport[pp->dest_no].x &&
130: pp->ypos == sp->airport[pp->dest_no].y &&
131: pp->altitude == 0) {
132: if (pp->dir != sp->airport[pp->dest_no].dir)
133: loser(pp, "landed in the wrong direction.");
134: else {
135: pp->status = S_GONE;
136: continue;
137: }
138: }
139: break;
140: case T_EXIT:
141: if (pp->xpos == sp->exit[pp->dest_no].x &&
142: pp->ypos == sp->exit[pp->dest_no].y) {
143: if (pp->altitude != 9)
144: loser(pp, "exited at the wrong altitude.");
145: else {
146: pp->status = S_GONE;
147: continue;
148: }
149: }
150: break;
151: default:
152: loser(pp, "has a bizarre destination, get help!");
153: }
154: if (pp->altitude > 9)
155:
156: loser(pp, "exceded flight ceiling.");
157: if (pp->altitude <= 0) {
158: for (i = 0; i < sp->num_airports; i++)
159: if (pp->xpos == sp->airport[i].x &&
160: pp->ypos == sp->airport[i].y) {
161: if (pp->dest_type == T_AIRPORT)
162: loser(pp,
163: "landed at the wrong airport.");
164: else
165: loser(pp,
166: "landed instead of exited.");
167: }
168: loser(pp, "crashed on the ground.");
169: }
170: if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
171: pp->ypos < 1 || pp->ypos >= sp->height - 1) {
172: for (i = 0; i < sp->num_exits; i++)
173: if (pp->xpos == sp->exit[i].x &&
174: pp->ypos == sp->exit[i].y) {
175: if (pp->dest_type == T_EXIT)
176: loser(pp,
177: "exited via the wrong exit.");
178: else
179: loser(pp,
180: "exited instead of landed.");
181: }
182: loser(pp, "illegally left the flight arena.");
183: }
184: }
185:
186:
187:
188:
189: for (pp = air.head; pp != NULL; pp = p2) {
190: p2 = pp->next;
191: if (pp->status == S_GONE) {
192: safe_planes++;
193: delete(&air, pp);
194: }
195: }
196:
197: draw_all();
198:
199: for (p1 = air.head; p1 != NULL; p1 = p1->next)
200: for (p2 = p1->next; p2 != NULL; p2 = p2->next)
201: if (too_close(p1, p2, 1)) {
202: static char buf[80];
203:
204: (void)sprintf(buf, "collided with plane '%c'.",
205: name(p2));
206: loser(p1, buf);
207: }
208:
209:
210:
211:
212:
213: if ((rand() % sp->newplane_time) == 0)
214: addplane();
215:
216: #ifdef SYSV
217: alarm(sp->update_secs);
218: #endif
219: }
220:
221: const char *
222: command(pp)
223: const PLANE *pp;
224: {
225: static char buf[50], *bp, *comm_start;
226:
227: buf[0] = '\0';
228: bp = buf;
229: (void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,
230: (pp->fuel < LOWFUEL) ? '*' : ' ',
231: (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
232:
233: comm_start = bp = strchr(buf, '\0');
234: if (pp->altitude == 0)
235: (void)sprintf(bp, "Holding @ A%d", pp->orig_no);
236: else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
237: strcpy(bp, "Circle");
238: else if (pp->new_dir != pp->dir)
239: (void)sprintf(bp, "%d", dir_deg(pp->new_dir));
240:
241: bp = strchr(buf, '\0');
242: if (pp->delayd)
243: (void)sprintf(bp, " @ B%d", pp->delayd_no);
244:
245: bp = strchr(buf, '\0');
246: if (*comm_start == '\0' &&
247: (pp->status == S_UNMARKED || pp->status == S_IGNORED))
248: strcpy(bp, "---------");
249: return (buf);
250: }
251:
252: char
253: name(p)
254: const PLANE *p;
255: {
256: if (p->plane_type == 0)
257: return ('A' + p->plane_no);
258: else
259: return ('a' + p->plane_no);
260: }
261:
262: int
263: number(l)
264: char l;
265: {
266: if (l < 'a' && l > 'z' && l < 'A' && l > 'Z')
267: return (-1);
268: else if (l >= 'a' && l <= 'z')
269: return (l - 'a');
270: else
271: return (l - 'A');
272: }
273:
274: int
275: next_plane()
276: {
277: static int last_plane = -1;
278: PLANE *pp;
279: int found, start_plane = last_plane;
280:
281: do {
282: found = 0;
283: last_plane++;
284: if (last_plane >= 26)
285: last_plane = 0;
286: for (pp = air.head; pp != NULL; pp = pp->next)
287: if (pp->plane_no == last_plane) {
288: found++;
289: break;
290: }
291: if (!found)
292: for (pp = ground.head; pp != NULL; pp = pp->next)
293: if (pp->plane_no == last_plane) {
294: found++;
295: break;
296: }
297: } while (found && last_plane != start_plane);
298: if (last_plane == start_plane)
299: return (-1);
300: return (last_plane);
301: }
302:
303: int
304: addplane()
305: {
306: PLANE p, *pp, *p1;
307: int i, num_starts, close, rnd, rnd2, pnum;
308:
309: memset(&p, 0, sizeof (p));
310:
311: p.status = S_MARKED;
312: p.plane_type = random() % 2;
313:
314: num_starts = sp->num_exits + sp->num_airports;
315: rnd = random() % num_starts;
316:
317: if (rnd < sp->num_exits) {
318: p.dest_type = T_EXIT;
319: p.dest_no = rnd;
320: } else {
321: p.dest_type = T_AIRPORT;
322: p.dest_no = rnd - sp->num_exits;
323: }
324:
325:
326: for (i = 0; i < num_starts; i++) {
327:
328: while ((rnd2 = random() % num_starts) == rnd)
329: ;
330: if (rnd2 < sp->num_exits) {
331: p.orig_type = T_EXIT;
332: p.orig_no = rnd2;
333: p.xpos = sp->exit[rnd2].x;
334: p.ypos = sp->exit[rnd2].y;
335: p.new_dir = p.dir = sp->exit[rnd2].dir;
336: p.altitude = p.new_altitude = 7;
337: close = 0;
338: for (p1 = air.head; p1 != NULL; p1 = p1->next)
339: if (too_close(p1, &p, 4)) {
340: close++;
341: break;
342: }
343: if (close)
344: continue;
345: } else {
346: p.orig_type = T_AIRPORT;
347: p.orig_no = rnd2 - sp->num_exits;
348: p.xpos = sp->airport[p.orig_no].x;
349: p.ypos = sp->airport[p.orig_no].y;
350: p.new_dir = p.dir = sp->airport[p.orig_no].dir;
351: p.altitude = p.new_altitude = 0;
352: }
353: p.fuel = sp->width + sp->height;
354: break;
355: }
356: if (i >= num_starts)
357: return (-1);
358: pnum = next_plane();
359: if (pnum < 0)
360: return (-1);
361: p.plane_no = pnum;
362:
363: pp = newplane();
364: if (pp == NULL)
365: loser(NULL, "Out of memory!");
366: memcpy(pp, &p, sizeof (p));
367:
368: if (pp->orig_type == T_AIRPORT)
369: append(&ground, pp);
370: else
371: append(&air, pp);
372:
373: return (pp->dest_type);
374: }
375:
376: PLANE *
377: findplane(n)
378: int n;
379: {
380: PLANE *pp;
381:
382: for (pp = air.head; pp != NULL; pp = pp->next)
383: if (pp->plane_no == n)
384: return (pp);
385: for (pp = ground.head; pp != NULL; pp = pp->next)
386: if (pp->plane_no == n)
387: return (pp);
388: return (NULL);
389: }
390:
391: int
392: too_close(p1, p2, dist)
393: const PLANE *p1, *p2;
394: int dist;
395: {
396: if (ABS(p1->altitude - p2->altitude) <= dist &&
397: ABS(p1->xpos - p2->xpos) <= dist && ABS(p1->ypos - p2->ypos) <= dist)
398: return (1);
399: else
400: return (0);
401: }
402:
403: int
404: dir_deg(d)
405: int d;
406: {
407: switch (d) {
408: case 0: return (0);
409: case 1: return (45);
410: case 2: return (90);
411: case 3: return (135);
412: case 4: return (180);
413: case 5: return (225);
414: case 6: return (270);
415: case 7: return (315);
416: default:
417: return (-1);
418: }
419: }