/* c_jovian_ai.hh 1.9 95/12/28 00:41:43 */


// xspacewarp by Greg Walker (gow@math.orst.edu)

// This is free software. Non-profit redistribution and/or modification
// is allowed and welcome.


// parameters and inline functions to use for artificial intelligence
// routines.

#ifndef _JOVIAN_AI_
#define _JOVIAN_AI_


#include <stdlib.h>		// rand()
#include "common.hh"
#include "params.hh"
#include "globals.hh"


// If the endever or a base being raided is in the same sector
// as a jovian, then the jovian moves or shoots (on average)
// every FASTFIGHT seconds in the highest skill level of game
// and every SLOWFIGHT seconds in lowest level of the
// game. Values for other skill levels are interpolated.

#define FASTFIGHT  app_data.jovian_max_fight_frequency
#define SLOWFIGHT  app_data.jovian_min_fight_frequency
			      

// When a sector contains a base but not the endever, there is a
// possibility of an attack or "raid" on the base. This constant
// is the average time in seconds before some jovian somewhere
// in the universe mounts a raid. FASTRAID is for the highest
// skill level, SLOWRAID is for the lowest skill level. Values
// for other skill levels are interpolated.

#define FASTRAID  app_data.jovian_max_raid_frequency
#define SLOWRAID  app_data.jovian_min_raid_frequency


// If neither a base nor the endever is around, then this is the
// average number of seconds until some jovian somewhere in the
// universe leaps to a sector containing a base or the
// endever. FASTLEAP is for the highest skill level, SLOWLEAP is
// for the lowest skill level. Values for other skill levels are
// interpolated.

#define FASTLEAP  app_data.jovian_max_leap_frequency
#define SLOWLEAP  app_data.jovian_min_leap_frequency
		       

// Fit a cubic Lagrange interpolation polynomial through the following
// four points to determine whether to shoot the target.
//
// P0_Y = P(shoot target | squared dist to target is P0_X)
// P1_Y = P(shoot target | squared dist to target is P1_X)
// P2_Y = P(shoot target | squared dist to target is P2_X)
// P3_Y = P(shoot target | squared dist to target is P3_X)

#define P0_X (float) 0 
#define P0_Y (float) 0.5 
#define P1_X (float) SECTDIAGSQ/4
#define P1_Y (float) 0.5
#define P2_X (float) SECTDIAGSQ/2
#define P2_Y (float) 0.5
#define P3_X (float) SECTDIAGSQ
#define P3_Y (float) 0.5


// parameters for determining whether a jovian will run away
// rather than fight. If the ion thruster energy is less than
// RETREAT_TRUST and the warpdrive energy is less than RETREAT_WARP
// and the faser energy is less than RETREAT_FASER and the shield
// energy is less than RETREAT_SHIELDS, then the jovian turns
// tail with probability RETREAT_PROB.

#define RETREAT_THRUST  app_data.jovian_thrust_retreat_energy
#define RETREAT_WARP  app_data.jovian_warp_retreat_energy
#define RETREAT_FASER  app_data.jovian_faser_retreat_energy
#define RETREAT_SHIELD  app_data.jovian_shield_retreat_energy
#define RETREAT_PROB  app_data.jovian_retreat_probability
#define RETREAT_SPEED  app_data.jovian_retreat_speed // float. retreat rate


// If a Jovian fires at a target and its faser is blocked by a
// star or some other obstacle, then the "mustmove" flag is set.
// If the jov, the target and the obstacle lie along a vertical
// line and the "mustmove" flag is set, then the jov will need
// to move horizontally FORCEDHORIZ steps in some consistent
// horizontal direction to clear the obstacle. Similarly, if the
// jov, target and obstacle lie on a horizontal line and
// "mustmove" is set, then the jov will need to move FORCEDVERT
// steps in a consistent vertical direction to clear the
// target. At the very minimum, FORCEDHORIZ should be at least 3
// and FORCEDVERT should at least be 1. By making FORCEDHORIZ
// and FORCEDVERT larger than these minimums, it will be more
// likely that the jov will be able to fire its faser around the
// obstacle.

#define FORCEDHORIZ  4
#define FORCEDVERT  2


// generate uniform random floats in [0, (RANDMAX-1)/RANDMAX]

inline float f_rand(void) {return ((float)(rand()%RANDMAX)/(float)RANDMAX);}

// Given a time, (float) s, in seconds, time_to_prob() returns a
// float in [0,1] such that if a rand number, (float) r, is
// generated from 0 to 1 every JOVINT millisecs, then r <=
// time_to_prob(s) on average once every s seconds.
//
// Note JOVINT/1000 <= s <= JOVINT*RANDMAX/1000
// That is, once every JOVINT/1000 seconds is as frequent as
// an event can occur, and once every JOVINT*RANDMAX/1000
// seconds is the rarest an event can be.

inline float time_to_prob(float s)
{return (max(min((float)JOVINT/(s*(float)1000), (float)1), (float)0));}


#endif             // _JOVIAN_AI_

// end
