(linenum→info "unix/slp.c:2238")

bsd-games/2.17/atc/update.c

    1: /*      $NetBSD: update.c,v 1.12 2003/08/07 09:36:55 agc Exp $       */
    2: 
    3: /*-
    4:  * Copyright (c) 1990, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    6:  *
    7:  * This code is derived from software contributed to Berkeley by
    8:  * Ed James.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  * 3. Neither the name of the University nor the names of its contributors
   19:  *    may be used to endorse or promote products derived from this software
   20:  *    without specific prior written permission.
   21:  *
   22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32:  * SUCH DAMAGE.
   33:  */
   34: 
   35: /*
   36:  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
   37:  *
   38:  * Copy permission is hereby granted provided that this notice is
   39:  * retained on all partial or complete copies.
   40:  *
   41:  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
   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 /* not lint */
   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:         /* put some planes in the air */
   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:         /* do altitude change and basic movement */
   85:         for (pp = air.head; pp != NULL; pp = pp->next) {
   86:                 /* type 0 only move every other turn */
   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:                          * Allow for circle commands
  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:                         /* "this is impossible" */
  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:          * Traverse the list once, deleting the planes that are gone.
  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:          * Check every other update.  Actually, only add on even updates.
  210:          * Otherwise, prop jobs show up *on* entrance.  Remember that
  211:          * we don't update props on odd updates.
  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:         /* loop until we get a plane not near another */
  326:         for (i = 0; i < num_starts; i++) {
  327:                 /* loop till we get a different start point */
  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: }
Syntax (Markdown)