|
|
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.