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

Defined functions

addplane defined in line 257; used 2 times
command defined in line 177; used 3 times
dir_deg defined in line 351; used 1 times
findplane defined in line 327; used 3 times
name defined in line 210; used 4 times
next_plane defined in line 229; used 1 times
number defined in line 219; used 1 times
too_close defined in line 341; used 2 times
update defined in line 16; used 3 times

Defined variables

sccsid defined in line 11; never used
Last modified: 1999-10-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3510
Valid CSS Valid XHTML 1.0 Strict