// BILL.CPP - "driver" function for RARS 
// By Bill Benedict, Jan. 1995 
// Modified from the driver 'Kernign' since it was the fastest :)
// This code may or may not be easy to read.. it is still similar to
// Mitchell Timin's code.
// (see CNTRL0.CPP for better comments)
// adapted to ver. 0.39 3/6/95 by M. Timin

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "car.h"

extern double width;
extern const double CARWID;
extern char* glob_name;

con_vec bill(situation s)
{
   const char name[] = "Bill";
   static int init_flag = 1;
   con_vec result;
   double alpha, vc, rad;
   double steer_gain = .2;
   const double steer_damp = .48;
   const double normalane = 70.0;
   static int lane_time = 0;
   static int lane_change = -10;

   static double lane = 70;    // determines right-left position on straigtaway
   const double corn_con = 7.0;
   static double corn_spd = 70.0;

   if(init_flag)  {
	  strcpy(glob_name, name);
	  init_flag = 0;
	  result.alpha = result.vc = 0;
	  return result;
   }

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

   if(s.cur_rad == 0.0 && s.nex_rad != 0.0)
	  corn_spd = corn_con * sqrt(s.nex_rad > 0.0 ? s.nex_rad : -s.nex_rad);
   else
	  corn_spd = corn_con * sqrt(s.cur_rad > 0.0 ? s.cur_rad : -s.cur_rad);

   // maybe choose a different lane: (to help in passing)
   if(!s.dead_ahead) {
	  if (lane_time <= 0) {
	lane_time=-1;
	lane = normalane;
	  }
   }
   else if (lane_time <= 0){
	  // pick a different lane:
	  if(lane >= 80)               // pick a new lane somehow:
	 lane_change = -10;
	  else if(lane <= -80)
	 lane_change = 10;
	  lane += lane_change;
	  lane_time=100;

   }
   if (lane_time >=0 ){
	 lane_time--;

   }
//Code below will buzz when someone is ahead of the driver..
// it is only here to facilitate testing of the dead_ahead stuff
// and is borland specific.  Use at your own discretion.
//if(s.dead_ahead) {sound(20);delay(2);nosound();}

   if((s.cur_rad == 0) && ((s.to_end/s.cur_len > .2) || (s.v < corn_spd))) {
	  alpha = .25 * steer_gain * (s.to_lft - s.to_rgt - lane) / width;
	  if(s.dead_ahead)
	  alpha *= 4.0;
	}
   else {
	  if(s.cur_rad == 0) rad=s.nex_rad;
	  else rad=s.cur_rad;

	  if(rad > 0.0)   {
	alpha = steer_gain * (3 * (s.to_lft -
			 (s.nex_rad < 0.0 ? width/3 : 1.6*CARWID)
					) / width + .05 * width/s.to_rgt);
	  if(s.dead_ahead)
	 alpha *= .7;

	  }
	  else  {
	alpha = -steer_gain * (3 * (s.to_rgt -
				   (s.nex_rad > 0.0 ? width/3 : 1.6*CARWID)
						 ) / width  + .05 * width/s.to_lft);
	  if(s.dead_ahead)
	 alpha *= .7;
	  }
   }
   alpha -= steer_damp * s.vn / s.v;  // This is damping, to prevent oscillation

   if(s.cur_rad == 0)         // If we are on a straightaway,
	  if(s.to_end/s.cur_len > .14)      // if we are far from the end:
	 vc = s.v + 85/s.v;        // keep accellerating near full power
	  else  {                 // otherwise,
	 vc = corn_spd;           // maintain cornering speed, braking at first
	 // this next formula will not work if a rt. turn follows the straight:
	 alpha += .4 * (s.cur_len/(s.to_end + s.cur_len) - (1/1.25 ));
	  }
   else            // if we're in the curve, maintain speed, +
	  vc = corn_spd + 1.2 / (s.to_end + .6);

   result.vc = vc;   result.alpha = alpha;
   return result;
}                                                              // v;
