|
|
1.1 root 1: /*
2: * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
3: *
4: * Copy permission is hereby granted provided that this notice is
5: * retained on all partial or complete copies.
6: *
7: * For more info on this and all of my stuff, mail [email protected].
8: */
9:
10: #ifndef lint
11: static char sccsid[] = "@(#)update.c 1.3 (Berkeley) 12/26/87";
12: #endif not lint
13:
14: #include "include.h"
15:
16: update()
17: {
18: int i, dir_diff, mask, unclean;
19: PLANE *pp, *p1, *p2, *p;
20:
21: #ifdef BSD
22: mask = sigblock(sigmask(SIGINT));
23: #endif
24: #ifdef SYSV
25: alarm(0);
26: signal(SIGALRM, update);
27: #endif
28:
29: clock++;
30:
31: erase_all();
32:
33: /* put some planes in the air */
34: do {
35: unclean = 0;
36: for (pp = ground.head; pp != NULL; pp = pp->next) {
37: if (pp->new_altitude > 0) {
38: delete(&ground, pp);
39: append(&air, pp);
40: unclean = 1;
41: break;
42: }
43: }
44: } while (unclean);
45:
46: /* do altitude change and basic movement */
47: for (pp = air.head; pp != NULL; pp = pp->next) {
48: /* type 0 only move every other turn */
49: if (pp->plane_type == 0 && clock & 1)
50: continue;
51:
52: pp->fuel--;
53: if (pp->fuel < 0)
54: loser(pp, "ran out of fuel.");
55:
56: pp->altitude += SGN(pp->new_altitude - pp->altitude);
57:
58: if (!pp->delayd) {
59: dir_diff = pp->new_dir - pp->dir;
60: /*
61: * Allow for circle commands
62: */
63: if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
64: if (dir_diff > MAXDIR/2)
65: dir_diff -= MAXDIR;
66: else if (dir_diff < -(MAXDIR/2))
67: dir_diff += MAXDIR;
68: }
69: if (dir_diff > 2)
70: dir_diff = 2;
71: else if (dir_diff < -2)
72: dir_diff = -2;
73: pp->dir += dir_diff;
74: if (pp->dir >= MAXDIR)
75: pp->dir -= MAXDIR;
76: else if (pp->dir < 0)
77: pp->dir += MAXDIR;
78: }
79: pp->xpos += displacement[pp->dir].dx;
80: pp->ypos += displacement[pp->dir].dy;
81:
82: if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
83: pp->ypos == sp->beacon[pp->delayd_no].y) {
84: pp->delayd = 0;
85: if (pp->status == S_UNMARKED)
86: pp->status = S_MARKED;
87: }
88:
89: switch (pp->dest_type) {
90: case T_AIRPORT:
91: if (pp->xpos == sp->airport[pp->dest_no].x &&
92: pp->ypos == sp->airport[pp->dest_no].y &&
93: pp->altitude == 0) {
94: if (pp->dir != sp->airport[pp->dest_no].dir)
95: loser(pp, "landed in the wrong direction.");
96: else {
97: pp->status = S_GONE;
98: continue;
99: }
100: }
101: break;
102: case T_EXIT:
103: if (pp->xpos == sp->exit[pp->dest_no].x &&
104: pp->ypos == sp->exit[pp->dest_no].y) {
105: if (pp->altitude != 9)
106: loser(pp, "exited at the wrong altitude.");
107: else {
108: pp->status = S_GONE;
109: continue;
110: }
111: }
112: break;
113: default:
114: loser(pp, "has a bizarre destination, get help!");
115: }
116: if (pp->altitude > 9)
117: /* "this is impossible" */
118: loser(pp, "exceded flight ceiling.");
119: if (pp->altitude <= 0) {
120: for (i = 0; i < sp->num_airports; i++)
121: if (pp->xpos == sp->airport[i].x &&
122: pp->ypos == sp->airport[i].y) {
123: if (pp->dest_type == T_AIRPORT)
124: loser(pp,
125: "landed at the wrong airport.");
126: else
127: loser(pp,
128: "landed instead of exited.");
129: }
130: loser(pp, "crashed on the ground.");
131: }
132: if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
133: pp->ypos < 1 || pp->ypos >= sp->height - 1) {
134: for (i = 0; i < sp->num_exits; i++)
135: if (pp->xpos == sp->exit[i].x &&
136: pp->ypos == sp->exit[i].y) {
137: if (pp->dest_type == T_EXIT)
138: loser(pp,
139: "exited via the wrong exit.");
140: else
141: loser(pp,
142: "exited instead of landed.");
143: }
144: loser(pp, "illegally left the flight arena.");
145: }
146: }
147:
148: /*
149: * Traverse the list once, deleting the planes that are gone.
150: */
151: for (pp = air.head; pp != NULL; pp = p2) {
152: p2 = pp->next;
153: if (pp->status == S_GONE) {
154: safe_planes++;
155: delete(&air, pp);
156: }
157: }
158:
159: draw_all();
160:
161: for (p1 = air.head; p1 != NULL; p1 = p1->next)
162: for (p2 = p1->next; p2 != NULL; p2 = p2->next)
163: if (too_close(p1, p2, 1)) {
164: static char buf[80];
165:
166: (void)sprintf(buf, "collided with plane '%c'.",
167: name(p2));
168: loser(p1, buf);
169: }
170: /*
171: * Check every other update. Actually, only add on even updates.
172: * Otherwise, prop jobs show up *on* entrance. Remember that
173: * we don't update props on odd updates.
174: */
175: if ((rand() % sp->newplane_time) == 0)
176: addplane();
177:
178: #ifdef BSD
179: sigsetmask(mask);
180: #endif
181: #ifdef SYSV
182: alarm(sp->update_secs);
183: #endif
184: }
185:
186: char *
187: command(pp)
188: PLANE *pp;
189: {
190: static char buf[50], *bp, *comm_start;
191: char *index();
192:
193: buf[0] = '\0';
194: bp = buf;
195: (void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,
196: (pp->fuel < LOWFUEL) ? '*' : ' ',
197: (pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
198:
199: comm_start = bp = index(buf, '\0');
200: if (pp->altitude == 0)
201: (void)sprintf(bp, "Holding @ A%d", pp->orig_no);
202: else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
203: strcpy(bp, "Circle");
204: else if (pp->new_dir != pp->dir)
205: (void)sprintf(bp, "%d", dir_deg(pp->new_dir));
206:
207: bp = index(buf, '\0');
208: if (pp->delayd)
209: (void)sprintf(bp, " @ B%d", pp->delayd_no);
210:
211: bp = index(buf, '\0');
212: if (*comm_start == '\0' &&
213: (pp->status == S_UNMARKED || pp->status == S_IGNORED))
214: strcpy(bp, "---------");
215: return (buf);
216: }
217:
218: /* char */
219: name(p)
220: PLANE *p;
221: {
222: if (p->plane_type == 0)
223: return ('A' + p->plane_no);
224: else
225: return ('a' + p->plane_no);
226: }
227:
228: number(l)
229: {
230: if (l < 'a' && l > 'z' && l < 'A' && l > 'Z')
231: return (-1);
232: else if (l >= 'a' && l <= 'z')
233: return (l - 'a');
234: else
235: return (l - 'A');
236: }
237:
238: next_plane()
239: {
240: static int last_plane = -1;
241: PLANE *pp;
242: int found, start_plane = last_plane;
243:
244: do {
245: found = 0;
246: last_plane++;
247: if (last_plane >= 26)
248: last_plane = 0;
249: for (pp = air.head; pp != NULL; pp = pp->next)
250: if (pp->plane_no == last_plane) {
251: found++;
252: break;
253: }
254: if (!found)
255: for (pp = ground.head; pp != NULL; pp = pp->next)
256: if (pp->plane_no == last_plane) {
257: found++;
258: break;
259: }
260: } while (found && last_plane != start_plane);
261: if (last_plane == start_plane)
262: return (-1);
263: return (last_plane);
264: }
265:
266: addplane()
267: {
268: PLANE p, *pp, *p1;
269: int i, num_starts, close, rnd, rnd2, pnum;
270:
271: bzero(&p, sizeof (p));
272:
273: p.status = S_MARKED;
274: p.plane_type = random() % 2;
275:
276: num_starts = sp->num_exits + sp->num_airports;
277: rnd = random() % num_starts;
278:
279: if (rnd < sp->num_exits) {
280: p.dest_type = T_EXIT;
281: p.dest_no = rnd;
282: } else {
283: p.dest_type = T_AIRPORT;
284: p.dest_no = rnd - sp->num_exits;
285: }
286:
287: /* loop until we get a plane not near another */
288: for (i = 0; i < num_starts; i++) {
289: /* loop till we get a different start point */
290: while ((rnd2 = random() % num_starts) == rnd)
291: ;
292: if (rnd2 < sp->num_exits) {
293: p.orig_type = T_EXIT;
294: p.orig_no = rnd2;
295: p.xpos = sp->exit[rnd2].x;
296: p.ypos = sp->exit[rnd2].y;
297: p.new_dir = p.dir = sp->exit[rnd2].dir;
298: p.altitude = p.new_altitude = 7;
299: close = 0;
300: for (p1 = air.head; p1 != NULL; p1 = p1->next)
301: if (too_close(p1, &p, 4)) {
302: close++;
303: break;
304: }
305: if (close)
306: continue;
307: } else {
308: p.orig_type = T_AIRPORT;
309: p.orig_no = rnd2 - sp->num_exits;
310: p.xpos = sp->airport[p.orig_no].x;
311: p.ypos = sp->airport[p.orig_no].y;
312: p.new_dir = p.dir = sp->airport[p.orig_no].dir;
313: p.altitude = p.new_altitude = 0;
314: }
315: p.fuel = sp->width + sp->height;
316: break;
317: }
318: if (i >= num_starts)
319: return (-1);
320: pnum = next_plane();
321: if (pnum < 0)
322: return (-1);
323: p.plane_no = pnum;
324:
325: pp = newplane();
326: bcopy(&p, pp, sizeof (p));
327:
328: if (pp->orig_type == T_AIRPORT)
329: append(&ground, pp);
330: else
331: append(&air, pp);
332:
333: return (pp->dest_type);
334: }
335:
336: PLANE *
337: findplane(n)
338: {
339: PLANE *pp;
340:
341: for (pp = air.head; pp != NULL; pp = pp->next)
342: if (pp->plane_no == n)
343: return (pp);
344: for (pp = ground.head; pp != NULL; pp = pp->next)
345: if (pp->plane_no == n)
346: return (pp);
347: return (NULL);
348: }
349:
350: too_close(p1, p2, dist)
351: PLANE *p1, *p2;
352: {
353: if (ABS(p1->altitude - p2->altitude) <= dist &&
354: ABS(p1->xpos - p2->xpos) <= dist && ABS(p1->ypos - p2->ypos) <= dist)
355: return (1);
356: else
357: return (0);
358: }
359:
360: dir_deg(d)
361: {
362: switch (d) {
363: case 0: return (0);
364: case 1: return (45);
365: case 2: return (90);
366: case 3: return (135);
367: case 4: return (180);
368: case 5: return (225);
369: case 6: return (270);
370: case 7: return (315);
371: default:
372: return (-1);
373: }
374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.