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