Exemple #1
0
void
update(int dummy)
{
	int	i, dir_diff, unclean;
	PLANE	*pp, *p1, *p2;

	clck++;

	erase_all();

	/* put some planes in the air */
	do {
		unclean = 0;
		for (pp = ground.head; pp != NULL; pp = pp->next) {
			if (pp->new_altitude > 0) {
				delete(&ground, pp);
				append(&air, pp);
				unclean = 1;
				break;
			}
		}
	} while (unclean);

	/* do altitude change and basic movement */
	for (pp = air.head; pp != NULL; pp = pp->next) {
		/* type 0 only move every other turn */
		if (pp->plane_type == 0 && clck & 1)
			continue;

		pp->fuel--;
		if (pp->fuel < 0)
			loser(pp, "ran out of fuel.");

		pp->altitude += SGN(pp->new_altitude - pp->altitude);

		if (!pp->delayd) {
			dir_diff = pp->new_dir - pp->dir;
			/*
			 * Allow for circle commands
			 */
			if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
				if (dir_diff > MAXDIR/2)
					dir_diff -= MAXDIR;
				else if (dir_diff < -(MAXDIR/2))
					dir_diff += MAXDIR;
			}
			if (dir_diff > 2)
				dir_diff = 2;
			else if (dir_diff < -2)
				dir_diff = -2;
			pp->dir += dir_diff;
			if (pp->dir >= MAXDIR)
				pp->dir -= MAXDIR;
			else if (pp->dir < 0)
				pp->dir += MAXDIR;
		}
		pp->xpos += displacement[pp->dir].dx;
		pp->ypos += displacement[pp->dir].dy;

		if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
		    pp->ypos == sp->beacon[pp->delayd_no].y) {
			pp->delayd = 0;
			if (pp->status == S_UNMARKED)
				pp->status = S_MARKED;
		}

		switch (pp->dest_type) {
		case T_AIRPORT:
			if (pp->xpos == sp->airport[pp->dest_no].x &&
			    pp->ypos == sp->airport[pp->dest_no].y &&
			    pp->altitude == 0) {
				if (pp->dir != sp->airport[pp->dest_no].dir)
				    loser(pp, "landed in the wrong direction.");
				else {
				    pp->status = S_GONE;
				    continue;
				}
			}
			break;
		case T_EXIT:
			if (pp->xpos == sp->exit[pp->dest_no].x &&
			    pp->ypos == sp->exit[pp->dest_no].y) {
			    	if (pp->altitude != 9)
				    loser(pp, "exited at the wrong altitude.");
				else {
				    pp->status = S_GONE;
				    continue;
				}
			}
			break;
		default:
			loser(pp, "has a bizarre destination, get help!");
		}
		if (pp->altitude > 9)
			/* "this is impossible" */
			loser(pp, "exceeded flight ceiling.");
		if (pp->altitude <= 0) {
			for (i = 0; i < sp->num_airports; i++)
				if (pp->xpos == sp->airport[i].x &&
				    pp->ypos == sp->airport[i].y) {
					if (pp->dest_type == T_AIRPORT)
					    loser(pp, 
						"landed at the wrong airport.");
					else
					    loser(pp, 
						"landed instead of exited.");
				}
			loser(pp, "crashed on the ground.");
		}
		if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
		    pp->ypos < 1 || pp->ypos >= sp->height - 1) {
			for (i = 0; i < sp->num_exits; i++)
				if (pp->xpos == sp->exit[i].x &&
				    pp->ypos == sp->exit[i].y) {
					if (pp->dest_type == T_EXIT)
					    loser(pp, 
						"exited via the wrong exit.");
					else
					    loser(pp, 
						"exited instead of landed.");
				}
			loser(pp, "illegally left the flight arena.");
		}
	}

	/*
	 * Traverse the list once, deleting the planes that are gone.
	 */
	for (pp = air.head; pp != NULL; pp = p2) {
		p2 = pp->next;
		if (pp->status == S_GONE) {
			safe_planes++;
			delete(&air, pp);
		}
	}

	draw_all();

	for (p1 = air.head; p1 != NULL; p1 = p1->next)
		for (p2 = p1->next; p2 != NULL; p2 = p2->next)
			if (too_close(p1, p2, 1)) {
				static char	buf[80];

				(void)snprintf(buf, sizeof buf,
				    "collided with plane '%c'.",
				    name(p2));
				loser(p1, buf);
			}
	/*
	 * Check every other update.  Actually, only add on even updates.
	 * Otherwise, prop jobs show up *on* entrance.  Remember that
	 * we don't update props on odd updates.
	 */
	if ((atcrandom() % sp->newplane_time) == 0)
		addplane();
}
Exemple #2
0
local void line_minimize
(
  double vect[],
  double direction[],
  double *pval_min,
  double *psave_x0,
  double *psave_a,
  double (*pfunction)(double vect[])
)
{
  double ax,bx,cx,x0,fa,fb,fc,fx0;
  double a,b;
  double old_x0,old_a;
  int code;

  if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
  {
    printf("start line minimize.\n");
  }

  last_line_function_x_valid = FALSE;

  wn_copy_vect(buffer_vect,vect,num_vars);
  save_vect = vect;
  save_direction = direction;
  save_pfunction = pfunction;

  old_x0 = *psave_x0;
  old_a = *psave_a;

  bx = 0.0;
  fb = *pval_min;
  if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
  {
    printf("First point at %lg, function value = %lg\n", bx, fb);
  }

  if(old_x0 == 0.0)
  {
    old_x0 = 1.0;
  }

  ax = old_x0*wn_random_double_between(0.9,1.1);
  if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
  {
    printf("Second point at %lg (old_x0 = %lg)\n", ax, old_x0);
  }
  fa = line_function(ax);

  if(!(old_a > 0.0))
  {
    goto simple_parabola_fit;
  }

  /* the curvature along a search direction is constant for a 
     quadratic function, therefore, try to use the curvature
     from the last search */
  fit_parabola_2pa(&code,&x0,&b,old_a,ax,fa,bx,fb);
  if(
     (code != WN_SUCCESS)
       ||
     (!(wn_abs(x0)<MAX_EXPAND*wn_abs(old_x0)) && (*psave_x0 != 0.0))
       ||
     too_close(x0, ax) || too_close(x0, bx)
       ||
     !is_valid_number(x0) || !is_valid_number(ax) || !is_valid_number(bx)
    )
  {
    goto simple_parabola_fit;
  }   

  cx = x0;
  if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
  {
    printf("Third point at %lg\n", cx);
  }
  fc = line_function(cx);

  wn_fit_parabola_3p(&code,&a,&x0,&b,ax,fa,bx,fb,cx,fc);

  if((code != WN_SUCCESS)||(!(a > 0.0))||
     (!(wn_abs(x0)<MAX_EXPAND*wn_abs(old_x0))&&(*psave_x0 != 0.0)))
  {
    goto full_linesearch;
  }   

  if(!(b < fb))
  {
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
    {
      printf("Doing slow line search (parabola fit returned suspect min value).\n");
    }
    goto full_linesearch;
  }
  if((!(fc < fb))||(!(fc < fa)))
  {
    /* evaluate one more point */
    goto evaluate_x0;
  }

  /* is it economical to evaluate one more point? */
  if((fb-b) <= 1.5*(fb-fc))
  { 
    /* do not evaluate one more point */
    wn_swap(fb,fc,double);
    wn_swap(bx,cx,double);
    goto finish;
  }
  else
  {
    /* evaluate one more point */
    goto evaluate_x0;
  }

simple_parabola_fit:
  if(fa < fb)
  {
    cx = 2.0*ax*wn_random_double_between(0.8,1.2);
  }
  else
  {
    cx = -1.0*ax*wn_random_double_between(0.8,1.2);
  }

  fc = line_function(cx);

  wn_fit_parabola_3p(&code,&a,&x0,&b,ax,fa,bx,fb,cx,fc);

  if((code != WN_SUCCESS)||(!(a > 0.0))||
     (!(wn_abs(x0)<MAX_EXPAND*wn_abs(old_x0))&&(*psave_x0 != 0.0)))
  {

    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
    {
      printf("Parabola fit failed. Switching to slow line search mode.\n");
    }
    goto full_linesearch;
  }   

evaluate_x0:
  fx0 = line_function(x0);

  if(!(fx0 <= fb))
  {
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_ALL)
    {
      printf("Doing a slow line search because f(x0) is too large (x0 = %lg).\n", x0);
    }
    goto full_linesearch;
  }

  fb = fx0;
  bx = x0;

  if(!(fa <= fc))
  {
    wn_swap(fa,fc,double);
    wn_swap(ax,cx,double);
  }
  if(!(fb <= fa))
  {
    wn_swap(fb,fa,double);
    wn_swap(bx,ax,double);
  }

  goto finish;

full_linesearch: ;

  /*
  printf("now.\n");
  */
  do
  {
    if(ax == bx)
    {
      if(wn_random_bit())
      {
        ax += wn_random_double_between(-1.0,1.0);
        fa = line_function(ax);
      }
      else
      {
        bx += wn_random_double_between(-1.0,1.0);
        fb = line_function(bx);
      }
    }
    if(ax == cx)
    {
      if(wn_random_bit())
      {
        ax += wn_random_double_between(-1.0,1.0);
        fa = line_function(ax);
      }
      else
      {
        cx += wn_random_double_between(-1.0,1.0);
        fc = line_function(cx);
      }
    }
    if(bx == cx)
    {
      if(wn_random_bit())
      {
        bx += wn_random_double_between(-1.0,1.0);
        fb = line_function(bx);
      }
      else
      {
        cx += wn_random_double_between(-1.0,1.0);
        fc = line_function(cx);
      }
    }
  } while((ax == bx)||(ax == cx)||(bx == cx));
  wn_minimize_1d_raw(&code,&fa,&fb,&fc,&ax,&bx,&cx,fb,&line_function,1,20);
  /*
  printf("l = %lf\n",bx);
  */

finish: ;

  /*
  if(show_linesearch)
  {
    printf("ax=%lg,bx=%lg,cx=%lg,old_x0=%lg\n",ax,bx,cx,old_x0);
  }
  */

  wn_copy_vect(vect,buffer_vect,num_vars);

  /* compute *psave_x0 */
  if(wn_abs(bx) < MIN_CONTRACT*wn_abs(old_x0))
  {
    if(bx < 0.0)
    {
      *psave_x0 = -MIN_CONTRACT*wn_abs(old_x0);
    }
    else
    {
      *psave_x0 = MIN_CONTRACT*wn_abs(old_x0);
    }
  }
  else
  {
    *psave_x0 = bx;
  }

  /* compute *psave_a */
  wn_fit_parabola_3p(&code,&a,&x0,&b,ax,fa,bx,fb,cx,fc);

  if((code != WN_SUCCESS)||(!(a > 0.0)))
  {
    *psave_a = 0.0;
  }   
  else
  {
    *psave_a = a;
  }

  if(*pval_min == fb)
  {
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
    {
      printf("finish line minimize.\n");
      fflush(stdout);
    }
    return;  /* do not move if no improvement */
  }

  wn_add_scaled_vect(vect,direction,bx,num_vars);

  *pval_min = fb;

  if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
  {
    printf("finish line minimize.\n");
    fflush(stdout);
  }
}
Exemple #3
0
int
addplane(void)
{
	PLANE	p, *pp, *p1;
	int	i, num_starts, close, rnd, rnd2, pnum;

	memset(&p, 0, sizeof (p));

	p.status = S_MARKED;
	p.plane_type = atcrandom() % 2;

	num_starts = sp->num_exits + sp->num_airports;
	rnd = atcrandom() % num_starts;

	if (rnd < sp->num_exits) {
		p.dest_type = T_EXIT;
		p.dest_no = rnd;
	} else {
		p.dest_type = T_AIRPORT;
		p.dest_no = rnd - sp->num_exits;
	}

	/* loop until we get a plane not near another */
	for (i = 0; i < num_starts; i++) {
		/* loop till we get a different start point */
		while ((rnd2 = atcrandom() % num_starts) == rnd)
			;
		if (rnd2 < sp->num_exits) {
			p.orig_type = T_EXIT;
			p.orig_no = rnd2;
			p.xpos = sp->exit[rnd2].x;
			p.ypos = sp->exit[rnd2].y;
			p.new_dir = p.dir = sp->exit[rnd2].dir;
			p.altitude = p.new_altitude = 7;
			close = 0;
			for (p1 = air.head; p1 != NULL; p1 = p1->next)
				if (too_close(p1, &p, 4)) {
					close++;
					break;
				}
			if (close)
				continue;
		} else {
			p.orig_type = T_AIRPORT;
			p.orig_no = rnd2 - sp->num_exits;
			p.xpos = sp->airport[p.orig_no].x;
			p.ypos = sp->airport[p.orig_no].y;
			p.new_dir = p.dir = sp->airport[p.orig_no].dir;
			p.altitude = p.new_altitude = 0;
		}
		p.fuel = sp->width + sp->height;
		break;
	}
	if (i >= num_starts)
		return (-1);
	pnum = next_plane();
	if (pnum < 0)
		return (-1);
	p.plane_no = pnum;

	pp = newplane();
	memcpy(pp, &p, sizeof (p));

	if (pp->orig_type == T_AIRPORT)
		append(&ground, pp);
	else
		append(&air, pp);

	return (pp->dest_type);
}