Example #1
0
  con_vec drive(situation& s)
  {
    con_vec result;                     

    if( s.starting )
    {
      result.fuel_amount = MAX_FUEL;
      RequestedPitStop = false;

      result.alpha = 0.0;
      result.vc = s.v + 50;
      return result;
    }


    if( JoyStick.GetStatus(js) )
    {
      // steering
      if( js.x > 5000 )           // right
        result.alpha = -0.1;
      else if( js.x < -5000 )      // left
        result.alpha = 0.1;
      else                        // straight
        result.alpha = 0.0;

      // speed
      if( js.button1 )            // accelerate
        result.vc = s.v + 50;
      else                        // hold speed
        result.vc = s.v;

      if( js.button2 )            // brake
      {
        // simple ABS
        if( result.alpha == 0.0 )
          result.vc = 0.0;
        else
          result.vc = s.v * 0.9;
      }

      // pit stop
      if( js.button3 )
      {
        RequestedPitStop = true;
      }

      if( RequestedPitStop )
      {
        // if is comming out of pits
        if( s.out_pits == 1)
        {
          RequestedPitStop = false;
        }
        else
        {
          // Request pit stop
          result.request_pit = 1;
          result.fuel_amount = MAX_FUEL;
          result.repair_amount = MAX_DAMAGE;
        }
      }
    }


    // use an internal function to get back on track when stuck
    if( s.out_pits!=1 && stuck( s.backward, s.v, s.vn, s.to_lft, s.to_rgt, &result.alpha, &result.vc ) )
    {
      return result;
    }

		return result;
	}
Example #2
0
void BaseCreatureEntity::animatePhysics(float delay)
{
	velocity.x *= viscosity;
	velocity.y *= viscosity;

	float velx = velocity.x;
	float vely = velocity.y;

	if (specialState[SpecialStateSlow].active)
  {
    velx *= specialState[SpecialStateSlow].param1;
    vely *= specialState[SpecialStateSlow].param1;
  }

	if (recoil.active)
  {
    if (recoil.stun)
    {
      velx = 0.0f;
      vely = 0.0f;
    }
    velx += recoil.velocity.x;
    vely += recoil.velocity.y;
  }

  spin *= viscosity;
	angle += spin * delay;

	if (isCollidingWithMap())
  {
    stuck();
  }
  else
  {
    if ((int)velx > 0)
    {
        x += velx * delay;

        if (collideWithMap(DIRECTION_LEFT))
        {
            x = (float)((int)x);
            while (collideWithMap(DIRECTION_LEFT))
                x--;
            collideMapRight();
        }
        else if (x > map->getWidth() * tileWidth + offsetX)
        {
            exitMap(DIRECTION_RIGHT);
        }
    }
    else if ((int)velx < 0)
    {
        x += velx * delay;

        if (collideWithMap(DIRECTION_RIGHT))
        {
            x = (float)((int)x);
            while (collideWithMap(DIRECTION_RIGHT))
                x++;
            collideMapLeft();
        }
        else if (x < offsetX)
        {
            exitMap(DIRECTION_LEFT);
        }
    }
  }

    vely += weight * delay;
    if ( vely > maxY) vely = maxY;

    if ((int)vely > 0)
    {
        y += vely * delay;

        if (collideWithMap(DIRECTION_BOTTOM))
        {
            y = (float)((int)y);
            while (collideWithMap(DIRECTION_BOTTOM))
                y--;
            collideMapBottom();
        }
    }
    else if ((int)vely < 0)
    {
        y += vely * delay;

        if (collideWithMap(DIRECTION_TOP))
        {
            y = (float)((int)y);
            while (collideWithMap(DIRECTION_TOP))
                y++;
            collideMapTop();
        }
    }

    if (lifetime > 0)
    {
        if (age >= lifetime) dyingFromAge();
    }
    age += delay;
}
void CollidingSpriteEntity::animate(float delay)
{
  velocity.x *= viscosity;
  velocity.y *= viscosity;

  spin *= viscosity;
  angle += spin * delay;

  velocity.y += weight * delay;

  if ((int)velocity.x > 0)
  {
    x += velocity.x * delay;

    if (collideWithMap(DIRECTION_LEFT))
    {
      x = (float)((int)x);
      while (collideWithMap(DIRECTION_LEFT))
        x--;
      collideMapRight();
    }
    else if (x > map->getWidth() * tileWidth + offsetX)
    {
      exitMap(DIRECTION_RIGHT);
    }
  }
  else if ((int)velocity.x < 0)
  {
    x += velocity.x * delay;

    if (collideWithMap(DIRECTION_RIGHT))
    {
      x = (float)((int)x);
      while (collideWithMap(DIRECTION_RIGHT))
        x++;
      collideMapLeft();
    }
    else if (x < offsetX)
    {
      exitMap(DIRECTION_LEFT);
    }
  }

  velocity.y += weight * delay;
  if ( velocity.y > maxY) velocity.y = maxY;

  if (isCollidingWithMap())
  {
    stuck();
  }
  else
  {
    if ((int)velocity.y > 0)
    {
      y += velocity.y * delay;

      if (collideWithMap(DIRECTION_BOTTOM))
      {
        y = (float)((int)y);
        while (collideWithMap(DIRECTION_BOTTOM))
          y--;
        collideMapBottom();
      }
    }
    else if ((int)velocity.y < 0)
    {
      y += velocity.y * delay;

      if (collideWithMap(DIRECTION_TOP))
      {
        y = (float)((int)y);
        while (collideWithMap(DIRECTION_TOP))
          y++;
        collideMapTop();
      }
    }
  }

  // for platforming
  /*   if ((int)weight == 0)
     {
         if (!(isOnGround()))
         {
             makeFall();
         }
     }*/

  if (lifetime > 0)
  {
    if (age >= lifetime) isDying = true;
  }
  age += delay;
}
Example #4
0
con_vec Ralph2(situation &s)
{
static int firstcall = 1;
con_vec result = CON_VEC_EMPTY;   // This is what is returned.
double ideal_alpha;
int segnum, nxtseg, nxtnxtseg;


if (firstcall)
  {                               //  this is the very first call
  my_name_is("Ralph2");            //  this lets everyone know who
                                  //  we are.

  firstcall = 0;                  //  theres only one first call

  return result;                  //  must return an answer
  }

if (s.starting)
  {
  track = get_track_description();
  }

if(stuck(s.backward, s.v,s.vn, s.to_lft,s.to_rgt,
&result.alpha,&result.vc))
  return result;

getabsxy(s.seg_ID, s.to_lft, s.to_rgt, s.to_end);

// point A
segnum = s.seg_ID;
nxtseg = (segnum+1)%track.NSEG;
nxtnxtseg = (nxtseg+1)%track.NSEG;

if (s.cur_rad == 0.0)
  ideal_alpha = angleforcurve(nxtseg, s.v);
 else
  {
  // look for either an s curve or a situation where we have
  // an  s curve with a straight in the middle
  ideal_alpha = angleforcurve(segnum, s.v);

  if (curveradiuslow(nxtseg) != 0)
    {  // one curve following another.
  
    //  now we look to see if we have an s-curve situation
    if (curveradiuslow(segnum) * curveradiuslow(nxtseg)  < 0)
      {
      double nextcurvealpha = angleforcurve(nxtseg, s.v);

      // can we see next curve
      if (
          (curveradiuslow(segnum) > 0 &&  nextcurvealpha < ideal_alpha)
          ||
          (curveradiuslow(segnum) < 0 &&  nextcurvealpha > ideal_alpha)
         )
        ideal_alpha = nextcurvealpha;
      }
    }
   else
    {
       // not an s curve, check for opposite direction curves with
       // an intervening straight

    if (curveradiuslow(segnum) * curveradiuslow(nxtnxtseg)  < 0)
      {
      double nextcurvealpha = angleforcurve(nxtnxtseg, s.v);

      // can we see next curve
      if (
          (curveradiuslow(segnum) > 0 &&  nextcurvealpha < ideal_alpha)
          ||
          (curveradiuslow(segnum) < 0 &&  nextcurvealpha > ideal_alpha)
         )
        ideal_alpha = nextcurvealpha;
      }

    }

  }

result.alpha = ideal_alpha - gc_dot;
// point B

getspeed(s, result);
link_alpha_and_vc(s, result);
avoidcars2(s, result);

if(s.starting) result.fuel_amount = MAX_FUEL;
result.request_pit = 0;
 if (s.stage != QUALIFYING && (s.damage > 25000 || s.fuel < 10))
     {
     result.request_pit = 1;
     result.repair_amount=s.damage;
     result.fuel_amount = MAX_FUEL;
     }
	
return result;
}
Example #5
0
char Agent::percept()
{
	int x = head().X;
	int y = head().Y;
	//cout << "head : " << x << " , " << y << endl;
	string moves;
    if(Team()==1)
        moves="drul"; //harkat da jahate padsaat gard
    else
        moves="uldr"; // harkat da jahate saat gard

	for (int i =0;i<map->MapSize.X;i++)
		for (int j =0;j<map->MapSize.Y;j++)
			mark[i][j]=false; //hameye mark haro false mikone! hamaro pak mikone

	for (int i =0;i<map->MapSize.X;i++)
		for (int j =0;j<map->MapSize.Y;j++)
			enemy_mark[i][j]=false; //hameye enemy_mark haro false mikone! hamaro pak mikone

	
	for (int i =0;i<4;i++)
		for (int j =0;j<4;j++)
			score[i][j]=0; //hameye score haro 0 mikone


	for (int move=0;move<4;move++) // emtiaz dehi be har harekat
	{
		Point here_now;	here_now.X=nextX(x,moves[move]); here_now.Y=nextY(y,moves[move]); 
		//mark[here_now.X][here_now.Y]=true;//jaii ke mire!
		if (isEmpty(here_now.X,here_now.Y)) // age por bood ke hichi!
		{
			//cout << "x and y now :" << here_now.X << " , "<<here_now.Y;
			score[move][1]=painting(here_now,'m')+1; //chand ta khoone mitoone bere
			//cout << "painting of " << moves[move] <<" is : "<< score[move][1] << endl;


			Point enemy_head=ehead(); //sare yaroo ro mirize to enemy_head
			int enemy_score[4]={0}; // emtiaz haro hame 0 mokine!
			enemy_mark[here_now.X][here_now.Y]=true; //injaii ro ke alan hast mark mikone!
			for (int enemy_move=0;enemy_move<4;enemy_move++) //baraye har harekat harif mikhad emtiaz hesab bokone
			{
				Point enemy_pos;	enemy_pos.X=nextX(enemy_head.X,moves[enemy_move]);	enemy_pos.Y=nextY(enemy_head.Y,moves[enemy_move]); 
				enemy_mark[enemy_pos.X][enemy_pos.Y]=true;
				if (isEmpty(enemy_pos.X,enemy_pos.Y))
				{
					enemy_score[enemy_move]=painting(enemy_pos,'e');
					//cout << "\t painting enemy " << moves[enemy_move] << " is : "<< enemy_score[enemy_move] << endl;
					//cout << "\t"<< "enemy pos: "<< enemy_pos.X << " , " << enemy_pos.Y << endl;
					for (int i =0;i<map->MapSize.Y;i++) //enemy mark ro 0 mikone
						for (int j =0;j<map->MapSize.X;j++)
							enemy_mark[i][j]=false; //hameye enemy_mark haro false mikone! hamaro pak mikone
				}
			}

			int minus=findmin(enemy_score,4,0);
			for (int i=0;i<4;i++)
			{
				if (enemy_score[i]!=0) enemy_score[i]=enemy_score[i]-minus;
				score[move][2]+=enemy_score[i];
				//cout << "\t now enemy score of " << moves[i] <<" is " << enemy_score[i] <<endl;
			}
			

			score[move][3]=getdistance(here_now,ehead());
			if (score[move][3] <= 1) {/*cout << "nazdiiiiiiiiiiik!"<<endl;*/ stuck(); }

			for (int i =0;i<map->MapSize.Y;i++)
				for (int j =0;j<map->MapSize.X;j++)
					mark[i][j]=false; //hameye mark haro false mikone!
		}
	}

	int min=10000;
	for (int i=0;i<4;i++)
		if (score[i][1]<min && score[i][1]!=0)
			min = score[i][1];


	for (int i=0;i<4;i++)
		if (score[i][1]!=0)
		{
			score[i][1]=score[i][1]-min;
			//cout << "now the painting of " <<moves[i] << " is : " << score[i][1] <<"and the min is " << min <<endl;
		}

		min=10000;
		int min_id;
		for (int i=0;i<4;i++)
			if (score[i][3]<min && score[i][3]!=0)
			{
				min = score[i][3];
				min_id=i;
			}

		
		for (int i=0;i<4;i++)
		{
			if (i!=min_id)
				score[i][3]=0;
			else
				score[i][3]=2; ///////////////////////////////////////////////////////////////////////////////////////////////////
		}

		//cout << "now the closest is : "<< moves[min_id] << " Point : " << score[min_id][3] << endl;


	//jamm score ha
	for (int move=0;move<4;move++)
	{
		score[move][0]+=score[move][1]+score[move][3]-score[move][2];
	}
	
	int max_char_id=0;
	int max_score=0;
	for (int move=0;move<4;move++)
	{
		if (max_score<score[move][0])
		{
			//cout <<"score move "<< moves[move] <<" is bigger than previouse :"<< score[move][0] <<endl;
			max_score = score[move][0];
			max_char_id = move;
		}
	}
	cout << "our algorithm output: "<< moves[max_char_id] <<endl << "\t and the score is " << max_score<<endl ;
	if (max_score!=0) 
		return moves[max_char_id];
	return stuck();
	//return stuck();
}
Example #6
0
  con_vec drive(situation &s)       // This is the robot "driver" function:
  {
    con_vec result = CON_VEC_EMPTY; // This is what is returned.
    double alpha, vc;             // components of result
    double bias;                  // added to servo's alpha result when entering curve
    double speed;                 // target speed for curve (next curve if straightaway)
    double speed_next = 0.0;      // target speed for next curve when in a curve, fps.
    double width;                 // track width, feet
    double to_end;                // distance to end of present segment in feet.
    static double lane;           // target distance from left wall, feet
    static double lane0;          // value of lane during early part of straightaway
    static int rad_was = 0;       // 0, 1, or -1 to indicate type of previous segment
    static double lane_inc = 0.0; // an adjustment to "lane", for passing

    // service routine in the host software to handle getting unstuck from
    // from crashes and pileups:
    if(stuck(s.backward, s.v,s.vn, s.to_lft,s.to_rgt, &result.alpha,&result.vc))
      return result;

    width = s.to_lft + s.to_rgt;  // compute width of track

    // This is a little trick so that the car will not try to change lanes
    // during the "dragout" at the start of the race.  We set "lane" to
    // whatever position we have been placed by the host.
    if(s.starting)                // will be true only once
      lane = lane0 = s.to_lft;    // better not to change lanes during "dragout"

    // Set "lane" during curves.  This robot sets "lane" during curves to
    // try to maintain a small fixed distance to the inner rail.
    if(s.cur_rad > 0.0)           // turning left
    {
      lane = MARGIN;
      rad_was = 1;                // set this appropriate to curve.
    }
    else if(s.cur_rad < 0.0)      // turning right
    {
      lane = width - MARGIN;
      rad_was = -1;               // set this appropriate to curve.
    }
    else                          // straightaway:
    {
      // We will let the car go down the straigtaway in whatever "lane" it
      // comes out of the turn.
      if(rad_was)                 // If we just came out of a turn, then:
      {
        lane = s.to_lft;          // set "lane" where we are now.
        if(lane < .5 * width)     // but maybe push it a little more to right?
          lane += MARG2;          // (add MARG2 if we were to left of center)
        lane0 = lane;             // save a copy of the new "lane" value.
        rad_was = 0;              // set this appropriate to straightaway.
      }
      // This is for the transition from straight to left turn.  If we are
      // in a transition zone near the end of the straight, then set lane to
      // a linear function of s.to_end.  During this zone, "lane" will change
      // from "lane0" upon entering the zone to MARG2 upon reaching the end
      // of the straightaway.  ENT_SLOPE is the change in lane per change in
      // s.to_end.
      if(s.to_end < (lane0 - MARG2) / ENT_SLOPE)
        lane = MARG2 + ENT_SLOPE * s.to_end;
    }

    // set the bias:
    // Bias is an additive term in the steering servo, so that the servo
    // doesn't have to "hunt" much for the correct alpha value.  It is an
    // estimate of the alpha value that would be found by the servo if there
    // was plenty of settling time.  It is zero for straightaways.
    // Also, for convenience, we call the corn_spd() function here.  On
    // the straightaway, we call it to find out the correct speed for the
    // corner ahead, using s.nex_rad for the radius.  In the curve we of
    // course use the radius of the curve we are in.  But also, we call it
    // for the next segment, to find out our target speed for the end of
    // the current segment, which we call speed_next.
    if(s.cur_rad == 0.0)
    {
      bias = 0.0;
      if(s.nex_rad > 0.0)
        speed = corn_spd(s.nex_rad + MARGIN);
      else if(s.nex_rad < 0.0)
        speed = corn_spd(-s.nex_rad + MARGIN);
      else
        speed = 250.0;  // This should not execute, for a normal track file
    }
    else                     // we are in a curve:
    {
      if(s.nex_rad == 0.0)
        speed_next = 250.0;
      else
        speed_next = corn_spd(fabs(s.nex_rad) + MARGIN);
      speed = corn_spd(fabs(s.cur_rad) + MARGIN + fabs(lane_inc));
      bias = (s.v*s.v/(speed*speed)) * atan(BIG_SLIP / speed);
      if(s.cur_rad < 0.0)   // bias must be negative for right turn
        bias = -bias;
    }

    // set alpha:  (This line is the complete steering servo.)
    alpha = STEER_GAIN * (s.to_lft - lane)/width - DAMP_GAIN * s.vn/s.v + bias;

    // set vc:
    if(s.cur_rad == 0.0)              // If we are on a straightaway,
    {                                          // if we are far from the end,
      if(s.to_end > CritDist(s.v, speed, BRAKE_ACCEL))
         vc = s.v + 50.0;                           // pedal to the metal!
      else                      // otherwise, adjust speed for the coming turn:
      {
         if(s.v > TOO_FAST * speed)             // if we're a little too fast,
           vc = s.v - BRAKE_SLIP;                // brake hard.
         else if(s.v < speed/TOO_FAST)         // if we're a little too slow,
           vc = 1.1 * speed;          // accelerate hard.
         else                               // if we are very close to speed,
           vc = .5 * (s.v + speed);   // approach the speed gently.
      }
    }
    else       // This is when we are in a curve:  (seek correct speed)
    {
      // calculate distance to end of curve:
      if(s.cur_rad > 0.0)
        to_end = s.to_end * (s.cur_rad + MARGIN);
      else
        to_end = -s.to_end * (s.cur_rad - MARGIN);
      // compute required braking distance and compare:
      // This is to slow us down for then next curve, if necessary:
      if(to_end <= CritDist(s.v, speed_next, BRK_CRV_ACC))
        vc = s.v - BRK_CRV_SLIP;
      // but if there is a straight, or a faster curve next, then
      // we may want to accelerate:
      else if(to_end/width < CURVE_END && speed_next > speed)
        vc = .5 * (s.v + speed_next)/cos(alpha);
      else   // normally, just calculate vc to maintain speed in corner
        vc = .5 * (s.v + speed)/cos(alpha);
    }

    // Passing and anti-collision code:
    // This code first tries to predict a collision; if no collision is
    // predicted, it does nothing.  Collision prediction is approximate, and
    // is based on linear extrapolation.  This can work because it is
    // repeated eighteen times per second of simulated time.
    // If a collision is predicted, then it gradually changes the
    // lane_inc static variable which changes alpha.
    // The hope is to steer around the car.  When no collision is
    // predicted then lane_inc is gradually brought back to zero.
    // If a crash is about to occur, medium hard braking occurs.
    double x, y, vx, vy, dot, vsqr, c_time, y_close, x_close;
    int kount;     // counts cars that are in danger of collision
    kount = 0;
    for(int i=0;i<3;i++) if (s.nearby[i].who<16)  // if there is a close car
    {
      y=s.nearby[i].rel_y;         // get forward distance (center-to-center)
      x=s.nearby[i].rel_x;         // get right distance
      vx=s.nearby[i].rel_xdot;     // get forward relative speed
      vy=s.nearby[i].rel_ydot;     // get lateral relative speed
      // if the cars are getting closer, then the dot product of the relative
      // position and velocity vectors will be negative.
      dot = x * vx + y * vy;     // compute dot product of vectors
      if(dot > -0.1)            // no action if car is not approaching.
        continue;
      vsqr = vx*vx + vy*vy;      // compute relative speed squared
      // Time to closest approach is dot product divided by speed squared:
      c_time = -dot / vsqr;     // compute time to closest approach
      if(c_time > 3.0)          // ignore if over three seconds
        continue;
      /* If the execution gets this far, it means that there is a car
      ahead of you, and getting closer, and less than 3.0 seconds
      away.  Evaluate the situation more carefully to decide if
      evasive action is warranted: */
      x_close = x + c_time * vx;      // x coord at closest approach
      y_close = y + c_time * vy;      // y coord at closest approach
      /*  Due to the length of the cars, a collision will occur if
          x changes sign while y is less than CARLEN.  This
          can happen before the center-to-center distance reaches its
          point of closest approach. */
      // check if collision would occur prior to closest approach
      // if so, reduce c_time, re-calculate x_close and y_close:
      if(x_close * x < 0.0 && y < 1.1 * CARLEN)
      {
        c_time = (fabs(x) - CARWID) / fabs(vx);
        x_close = x + c_time * vx;      // x coord at closest approach
        y_close = y + c_time * vy;      // y coord at closest approach
      }
      // Will it be a hit or a miss?
      if(fabs(x_close) > 2 * CARWID || fabs(y_close) > 1.25 * CARLEN)
        continue;            // this when a miss is predicted
      // If we get here there is a collision predicted
      ++kount;    // This counts how many cars are in the way.
      if(kount > 1 || c_time < .85)  // if more than one problem car, or if
        vc = s.v - BRK_CRV_SLIP;    // car within .85 sec of collision, brake!
      // steer to avoid the other car:
      // if there is room, we try to pass with least x deviation
      if(s.cur_rad > 0.0)
        if(x_close < 0.0 || s.to_lft < MARGIN)  // avoid scraping the inside
          lane_inc += DELTA_LANE;
        else
          lane_inc -= DELTA_LANE;
      else if(s.cur_rad < 0.0)
        if(x_close > 0.0 || s.to_rgt < MARGIN)
          lane_inc -= DELTA_LANE;
        else
          lane_inc += DELTA_LANE;
      else if(x_close < 0.0)      // on straights, pass with least x deviation
        lane_inc += DELTA_LANE;
      else
        lane_inc -= DELTA_LANE;
      if(lane_inc > .25 * width)  // limit the lane alteration to 1/4 width:
        lane_inc = .25 * width;
      else if(lane_inc < -.25 * width)
        lane_inc = -.25 * width;
    }

    // Here we gradually reduce lane_inc to zero if no collision is predicted:
    if(!kount)
      if(lane_inc > .1)
        lane_inc -= .5*DELTA_LANE;
      else if(lane_inc < -.001)
        lane_inc += .5*DELTA_LANE;

    // lane_inc represents an adjustment to the lane variable.  This is
    // accomplished by changing alpha an amount equal to that which the
    // steering servo would have done had lane actually been changed.
    result.vc = vc;   result.alpha = alpha - STEER_GAIN * lane_inc / width;

    // Pit: if the fuel is too low
    //  Fuel: full
    //  Damage: repair all
    if( s.fuel<10.0 )
    {
      result.request_pit   = 1;
      result.repair_amount = s.damage;
      result.fuel_amount = MAX_FUEL;
    }

    return result;
  }
Example #7
0
  con_vec drive(situation &s) 
  { 
    con_vec result = CON_VEC_EMPTY;    // This is what is returned. 
    double alpha, vc;                  // components of result 
    static double lane = -10000;       // an absurd value to show not initialized 
    double bias, speed, width; 

    if( s.starting )
    {
      result.fuel_amount = MAX_FUEL;     // fuel when starting
    }

    // service routine in the host software to handle getting unstuck from 
    // from crashes and pileups: 
    if(stuck(s.backward, s.v,s.vn, s.to_lft,s.to_rgt, &result.alpha,&result.vc)) 
      return result; 

    width = s.to_lft + s.to_rgt;       // compute width of track 

    // This is a little trick so that the car will not try to change lanes 
    // during the "dragout" at the start of the race.  We set "lane" to 
    // whatever position we have been placed by the host. 
    if(lane < -9000)                   // will be true only once 
      lane = s.to_lft;                 // better not to change lanes at the start 

    // Set "lane" during curves.  This robot sets "lane" during curves to 
    // try to maintain a fixed distance to the inner rail. 
    // For straightaways, we leave "lane" unchanged until later. 
    if(s.cur_rad > 0.0)                // turning left 
      lane = DIST_FROM_INSIDE; 
    else if(s.cur_rad < 0.0)           // turning right 
      lane = width - DIST_FROM_INSIDE; 

    // set the bias: 
    // Bias is an additive term in the steering servo, so that the servo 
    // doesn't have to "hunt" much for the correct alpha value.  It is an 
    // estimate of the alpha value that would be found by the servo if there 
    // was plenty of settling time.  It is zero for straightaways. 
    // Also, for convenience, we call the corn_spd() function here.  On 
    // the straightaway, we call it to find out the correct speed for the 
    // corner ahead, using s.nex_rad for the radius.  In the curve we of 
    // course use the radius of the curve we are in. 
    if(s.cur_rad == 0.0) 
    { 
      bias = 0.0; 
      speed = corn_spd(s.nex_rad + DIST_FROM_INSIDE); 
    } 
    else  
    { 
      speed = corn_spd(s.cur_rad + DIST_FROM_INSIDE); 
      // See initial paragraphs for discussion of this formula. 
      bias = (s.v*s.v/(speed*speed)) * atan(BIG_SLIP / speed); 
      if(s.cur_rad < 0.0)   // bias must be negative for right turn 
        bias = -bias; 
    } 

    // set alpha:  (This line is the complete steering servo.) 
    alpha = STEER_GAIN * (s.to_lft - lane)/width - DAMP_GAIN * s.vn/s.v + bias; 

    // set vc:  When nearing end of straight, change "lane" for the turn, also. 
    if(s.cur_rad == 0.0)              // If we are on a straightaway, 
    {
      if(s.to_end > ACCEL_FRACTION * s.cur_len)  // if we are far from the end, 
      {
        vc = s.v + 50.0;                           // pedal to the metal! 
      }
      else                      // otherwise, adjust speed for the coming turn: 
      {
        if(s.v > 1.02 * speed)         // if we're 2% too fast, 
          vc = .95 * s.v;              // brake hard. 
        else if(s.v < .98 * speed)     // if we're 2% too slow, 
          vc = 1.05 * speed;           // accelerate hard. 
        else                           // if we are very close to speed, 
          vc = .5 * (s.v + speed);     // approach the speed gently. 
        // approach the lane you want for the turn: 
        if(s.nex_rad > 0.0) 
          lane = DIST_FROM_INSIDE; 
        else 
          lane = width - DIST_FROM_INSIDE; 
      } 
    } 
    else       // This is when we are in a curve:  (seek correct speed) 
    {
      vc = .5 * (s.v + speed)/cos(alpha);   // to maintain speed in corner 
    } 

    // During the acceleration portion of a straightaway, the lane variable 
    // is not changed by the code above.  Hence the code below changes it a 
    // little at a time until there is no car dead_ahead.  This code here has 
    // no affect at all in the turns, nor in the braking portion 
    // of the straight. 
    if(s.dead_ahead)                   // Change the lane a little if someone's 
      if(s.to_lft > s.to_rgt)          // in your way. 
        lane -= DELTA_LANE;            // lane must be a static variable 
      else 
        lane += DELTA_LANE; 

    result.vc = vc;   result.alpha = alpha; 

    // Pit: if the fuel is too low
    //  Fuel: full
    //  Damage: repair all
    if( s.fuel<10.0 ) 
    {
      result.request_pit   = 1;
      result.repair_amount = s.damage;
      result.fuel_amount = MAX_FUEL;
    }

    return result; 
  } 
Example #8
0
con_vec Djoefe (situation & s) 
{
  
  const char name[] = "Djoefe";	// This is the robot driver's name!
  static int init_flag = 1;	// cleared by first call
  con_vec result;		// This is what is returned.
  double alpha, vc;		// components of result
  static double lane = -10000;	// an absurd value to show not initialized
  double bias, speed, width, to_end;
  double speed_next= 0.0;
  
  static double fuel_total = 0;
  static double fuel_last;

  double aftaft_bd, after_bd, bd_now;
    
  // Load the optimization stuff for this track
#ifdef OPTIMIZE
  static int optinit = 0;
  if(optinit==0)
  {
    // Reload the population from the data file
    const char* optfile = "djoefe.opt";
    data.load(optfile,Population,GeneticLength,SetTrackData);
    cout << "\nOptimizing for track in " << optfile << endl;

    optinit = 1;
  }
#endif //OPTIMIZE

  if (init_flag == 1)
  {				// first time only, copy name:
    my_name_is (name);	// copy the name string into the host program
    init_flag = 0;
    result.alpha = result.vc = 0;
    
    return result;  
  }

  // set fuel for qualifications  
  if (s.starting && s.stage == QUALIFYING)
    result.fuel_amount = 20;
    
  // estimate available friction:
  useful_friction = 0.975 * my_friction - 0.2 * s.damage * s.damage / 9e8;
  
  // drive carefully on first laps:
  //    if(lap_count - s.laps_to_go < 2 && s.position >= 4)
  //        useful_friction *= .9*my_friction;
    
  // service routine in the host software to handle getting unstuck from
  // from crashes and pileups:
#ifndef OPTIMIZE
  if (stuck (s.backward, s.v, s.vn, s.to_lft, s.to_rgt, &result.alpha, &result.vc))
    return result;
#endif //OPTIMIZE

  width = s.to_lft + s.to_rgt;	// compute width of track

  
  // This is a little trick so that the car will not try to change lanes
  // during the "dragout" at the start of the race.  We set "lane" to
  // whatever position we have been placed by the host.
    if (lane < -9000)		// will be true only once
    {
      fuel_last = s.fuel;	// setup fuel counter

#ifndef OPTIMIZE
      set_track_data ();
#endif

      lane = s.to_lft;	// better not to change lanes at the start
      slip = BIG_SLIP;
      t = get_track_description ();
      
      if( !args.m_iSurface )		// friction model 0:
	my_friction = slip / (slip + 2.5);
      else			// friction model 1:
	my_friction = 1.05 * (1.0 - exp (-slip / 2.5));      
    }
  
#ifdef OPTIMIZE
  if(s.starting)
  {
    // Figure out a nice estimate of the MPH, or how far we
    // got around the track
    double mph = optimizedata::mph(lastlaptime,t.length,lastdamage,lastdistance);

    if(no_display)
    {
      cout << " Mph: " << mph
           << endl;
    }

    // Tell the optimizer what the last MPH was
    data.step(mph);
    AbortRace = 0;
  }
#endif //OPTIMIZE
    
    // Curve control 1
    // a) If we are in a curve, go to the inside
    // b) If we are exiting the curve into a straight then "slide" out of the curve

    // Sharp left
    if (s.cur_rad > 0.0 && s.cur_rad < straight_radius)	
    {
      if (is_nex_straight (s) && s.to_end <= s.cur_len * (1 - out_of_curve))
      {
        lane = width - dist_from_outside;
      }
      else
      {
	lane = dist_from_inside;
      }
      
    }
    // Sharp right
    else if (s.cur_rad < 0.0 && s.cur_rad > -straight_radius)
    {
      if (is_nex_straight (s) && s.to_end <= s.cur_len * (1 - out_of_curve))
      {
          lane = dist_from_outside;
      }
      else
      {
	  lane = width - dist_from_inside;
      }
    }
    
  // set the bias:
  // Bias is an additive term in the steering servo, so that the servo
  // doesn't have to "hunt" much for the correct alpha value.  It is an
  // estimate of the alpha value that would be found by the servo if there
  // was plenty of settling time.  It is zero for straightaways.
  // Also, for convenience, we call the corn_spd() function here.  On
  // the straightaway, we call it to find out the correct speed for the
  // corner ahead, using s.nex_rad for the radius.  In the curve we of
  // course use the radius of the curve we are in.  But also, we call it
  // for the next segment, to find out our target speed for the end of
  // the current segment, which we call speed_next.
    if (s.cur_rad == 0.0)
    {
	bias = 0.0;
     
	if (!is_nex_straight (s))
	  speed = curvespeed (s, fabs(s.nex_rad) + width * predict_width);	
        else
	  speed = 250.0;
    }
    else
    {
	if (is_nex_straight(s))
	  speed_next = 250.0;
	else
	  speed_next = curvespeed (s, fabs (s.nex_rad) + width * predict_width);
      	
	if(!is_curr_straight(s))
	  speed = curvespeed (s, fabs (s.cur_rad) + width * predict_width);
	else
	  speed = 250;
	
	bias = (s.v * s.v / (speed * speed)) * atan (BIG_SLIP / speed);	
      
	if (s.cur_rad < 0.0)	// bias must be negative for right turn
	  bias = -bias;
    }
    
  // set alpha:  (This line is the complete steering servo.)
    alpha = steer_gain * (s.to_lft - lane) / width - damp_gain * s.vn / s.v + bias;
  
  
  // set vc:  When nearing end of straight, change "lane" for the turn, also.
    if (s.cur_rad == 0.0)
    {				// If we are on a straightaway,
      
      // if we are far from the end,
      if (s.to_end * ignore_slowdown > find_bd (s, speed))
      {
	vc = s.v + 50.0;	// pedal to the metal!
      }
      else
      {			// otherwise, adjust speed for the coming turn:
	  if (s.v > 1.02 * speed)	// if we're 2% too fast,
	    vc = brake_ratio * s.v;	// brake hard.
	  else if (s.v < .98 * speed)	// if we're 2% too slow,
	    vc = 1.1 * speed;	// accelerate hard. 1.1
	  else			// if we are very close to speed,
	    vc = .5 * (s.v + speed);	// approach the speed gently.
       }
      
      // Start diving into the corner

      if(s.to_end < (start_dive * s.v * width))
	{
	  if (s.nex_rad > 0.0)	// left
	    lane = dist_from_inside;
	  else
	    lane = width - dist_from_inside;  
	}
      else
	{
	  if (!is_nex_straight(s) && ((s.cur_len * dive_setup_dist) >= s.to_end))
	    {
	      if (s.nex_rad > 0.0)
		lane = width - dist_for_dive;
	      else if (s.nex_rad < 0.0)
		lane = dist_for_dive;
	    }
	}
      
    }
    else
    {				
      // This is when we are in a curve:  (seek correct speed)
      // calculate vc to maintain speed in corner
      speed = curvespeed (s, fabs (s.cur_rad) + width * predict_width);
      
      vc = .5 * (s.v + speed);	

      // calculate distance to end of curve
      if (s.cur_rad > 0.0)
	  to_end = s.to_end * (s.cur_rad + width * predict_width);
      else	
	  to_end = -s.to_end * (s.cur_rad - width * predict_width);
      
      // compute required braking distance and compare:
      if (to_end <= find_bd (s, speed_next))
      {
	vc = s.v - brake_curve_slip;
      }

      if (is_nex_straight (s) && s.to_end <= s.cur_len * (1 - out_of_curve))
      {  
	vc = s.v * 1.1;  
      }
    }

    // New speed limiter if curve after next is tricky

    // calculate the braking distance we will need to slow down from the
    // speed we now have to the speed in the segment after the next

    aftaft_bd = find_bd(s, crvspeed(s.aftaft_rad));

    after_bd = find_bd(s, crvspeed(s.after_rad));

    if (aftaft_bd > (curve_length(s.nex_len, s.nex_rad) 
		    + curve_length(s.after_len, s.after_rad)))
      {
	bd_now = aftaft_bd - (curve_length(s.nex_len, s.nex_rad) +
			      curve_length(s.after_len, s.after_rad));

	if (bd_now > curve_length(s.to_end, s.cur_rad))
	  {
	    vc = s.v * brake_ratio;
	  }
      }
    // else here ? not sure...
    if (after_bd > (curve_length(s.nex_len, s.nex_rad)))  
      {
	// We will have to start braking in this segment.

	// When = Total - lenght of next curve
	bd_now = after_bd - curve_length(s.nex_len, s.nex_rad);

	if (bd_now > curve_length(s.to_end, s.cur_rad))
	  {   
	    vc = s.v * brake_ratio; 
	  }
      }

#ifndef BFOPT
    // Gotta love this passing code... ;-)
    if (s.dead_ahead)		// Change the lane a little if someone's
      if (s.to_lft > s.to_rgt)	// in your way.
	lane -= DELTA_LANE;	// lane must be a static variable
      else
	lane += DELTA_LANE;
  
    
    if (s.lap_flag)
    {    
	if (s.fuel > fuel_last)
	{			
	  // we refueled...use previous as estimate
	  fuel_total += fuel_total / (s.laps_done - 1); 
	}
	else
	{
	  fuel_total += fuel_last - s.fuel;
	}
	fuel_last = s.fuel;
    }
  
    result.request_pit = 0;

    
    if (s.stage != QUALIFYING && (s.damage > 20000) && (s.laps_to_go > 5))  
    {
      result.request_pit = 1;
      result.repair_amount = max(s.damage, (unsigned)s.laps_to_go * 1000);
      result.fuel_amount = max(0,((fuel_total / s.laps_done) * (s.laps_to_go + 1)) - s.fuel);
    }
  
    if (s.stage != QUALIFYING && s.fuel < (fuel_total / (s.laps_done - 1)) && s.laps_done > 1)
    {
      result.request_pit = 1;
      result.fuel_amount = (fuel_total / s.laps_done) * (s.laps_to_go + 1);
      result.repair_amount = (int)result.fuel_amount * 10;
    }  

#endif
    result.alpha = alpha;
  
    result.vc = vc;
    
    traction_control(s, result);
    
#ifdef OPTIMIZE  // Pitting during optimizing is done differently

  // Keep track of the data from the last lap
  lastlaptime = s.lap_time;
  lastdamage = s.damage;
  lastdistance = s.distance;
  
//   result.fuel_amount = 150;
   result.request_pit = 0;

   // If we are damaged or are too close to the edge, abort the
   // race by deliberate crashing
   /*   if((s.damage)||
      (s.to_lft<EdgeLimit)||
      (s.to_rgt<EdgeLimit))
      AbortRace = 1;*/

   if(AbortRace)
   {
     result.vc = 250.;
     result.alpha = 0.;
   }
#endif //OPTIMIZE

#ifdef SKIDMARKS
    extern int skidmarks;
    skidmarks = 1;

    extern int designated;
    designated = 0;
#endif

    return result;
}