

/* This file contains definitions of functions to create instances of each
feature type */


#include <stdio.h>
#include <math.h>
/*gn*/
#include <suntool/sunview.h>
/*gn*/
#include <suntool/panel.h>
/*gn*/
#include <suntool/canvas.h>
#include "structures.h"
#include "util_fns.h"
#include "env_spec.h"
#include "env_defs.h"
#include "ext_env_decs.h"


/* function to create an instance of cereal_food and return a pointer to it
as a result */
void get_cereal_food(number)
int number;
{

  int i, nft = CEREAL_FOOD_N;
  int *pc, *pr, c = 0, r = 0;
  CEREAL_FOOD *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

	/* have a probability of the cereal food occurring near water, else
	position it randomly anywhere */
	if (drand48() < CEREAL_FOOD_NEAR_WATER_PROB)
	  get_rnd_pos_near_water(pc, pr, nft, CEREAL_FOOD_TO_WATER_DIST);
	else
	  get_rnd_pos(pc, pr, nft);

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
    (void *) malloc(sizeof(CEREAL_FOOD));

    ptr = (CEREAL_FOOD *) env_arr[*pc][*pr].p_arr[nft];

    /* the conditions, ie suitability of the site for growth, can vary between
    0.2 and 1.0 (though most cereal food less nutritious than fruit food) */
    ptr->conditions = get_cereal_food_conditions();

    /* the food value is a measure of the amount of food to be obtained at the
    source at a particular time (factor to reduce value of cereal_food with
    respect to fruit_food).  It depends on the soil conditions and weather */
    ptr->value = get_cereal_food_value(ptr->conditions);

    /* the toxicity is a measure of how ill the food will make the animal when
    it is eaten */
    if (drand48() < CEREAL_FOOD_TOXICITY_PROB) {

      /* give the food source a toxicity */
      ptr->toxicity = get_cereal_food_toxicity();

      /* make the toxic entry in the ptr array not null so will be drawn */
      env_arr[*pc][*pr].p_arr[TOXIC_N] = (void *) NOT_NULL;

/*g*/      /* draw the toxic symbol onto the square */
/*g*/      add_to_square(TOXIC_N, *pc, *pr);
/*g*/
      /* give the toxic food source a time interval after which the
      ill-health will start to take effect */
	  ptr->toxicity_delay = get_cereal_food_toxicity_delay();
    }

    else
      ptr->toxicity = 0.0;

    /* increment the 'number of features' counter for the area of the array */ 
    env_arr[*pc][*pr].physical_f_count++;

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
  }
}


/* function to create an instance of cover and return a pointer to
it as a result */
void get_cover(number)
int number;
{

  int i, nft = COVER_N;
  static int cover_count;               /* used to keep instances in clumps
                                        when generated after start */
  int *pc, *pr, c = 0, r = 0;
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */
  COVER *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {
  
	/* have a probability of the cover occurring near water, else position
	it randomly anywhere */ 
	if (drand48() < COVER_NEAR_WATER_PROB)
	  get_rnd_pos_near_water(pc, pr, nft, COVER_TO_WATER_DIST);
	else
	  get_rnd_pos(pc, pr, nft);

    /* if this is the first instance of a cluster .... */
    if ((cover_count%COVER_CLUSTER_SIZE) == 0) {

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
      tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > COVER_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > COVER_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

        get_rnd_pos(pc, pr, nft);
        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
      (void *) malloc(sizeof(COVER));

    ptr = (COVER *) env_arr[*pc][*pr].p_arr[nft];

    /* give the instance of cover a thickness corresponding to the density
    of the vegetation that it is made up of.  The thickness will have
    proportionate effects on perception (of and by animal), the likelihood
    of a chased animal being caught and on the protection against the
    temperature extremes */
    ptr->thickness = get_cover_thickness();
 
    /* increment the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    /* make relevant changes to the temperature, ability to escape
    detection, perception, and ability to escape in square */
    env_arr[*pc][*pr].temp_factor -= (0.5 * ptr->thickness);
    env_arr[*pc][*pr].perception_factor -= ptr->thickness;
    env_arr[*pc][*pr].escape_factor += ptr->thickness;

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    ++cover_count;
  }
}


/* function to create an instance of dangerous_place and return a pointer to
it as a result */
void get_dangerous_places(number)
int number;
{

  int i, nft = DANGEROUS_PLACE_N;
  static int dangerous_place_count;     /* used to keep instances in clumps
                                        when generated after start */
  int *pc, *pr, c = 0, r = 0;
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {
  
	/* position the dangerous place (aka hazard) randomly anywhere */
	get_rnd_pos(pc, pr, nft);

    /* if this is the first instance of a cluster .... */
    if ((dangerous_place_count%DANGEROUS_PLACE_CLUSTER_SIZE) == 0) {

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
      tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > DANGEROUS_PLACE_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > DANGEROUS_PLACE_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

		get_rnd_pos(pc, pr, nft);
        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
      (void *) malloc(sizeof(DANGEROUS_PLACE));

    /* increment the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    /* make relevant changes to the temperature, ability to escape
    detection, perception, and ability to escape in square */
    env_arr[*pc][*pr].escape_factor = 0.4;

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    ++dangerous_place_count;
  }
}


/* function to create dens */
void get_dens(number)
int number;
{

  int i, nft = DEN_N;
  int *pc, *pr, c = 0, r = 0;
  int den_count;
  int num_attempts;
  int middle_c, middle_r;               /* coords of centre of environment */

  den_count = 0;

  pc = &c; pr = &r;

  middle_c = (ENV_ARR_COLS/2);
  middle_r = (ENV_ARR_ROWS/2);

  for (i = 0; i < number; ++i) {

	/* have a probability of the den occurring near water, else	position it
	randomly anywhere */
	if (drand48() < DEN_NEAR_WATER_PROB)
	  get_rnd_pos_near_water(pc, pr, nft, DEN_TO_WATER_DIST);
	else
	  get_rnd_pos(pc, pr, nft);

    num_attempts = 0;

    /* make sure the first den is positioned close to the environment centre*/
	while ((den_count == 0) &&
		   (((abs(middle_c-*pc)) > 2) || ((abs(middle_r-*pr)) > 2)) &&
		   (num_attempts < 5000)) {

	  if (drand48() < DEN_NEAR_WATER_PROB)
		get_rnd_pos_near_water(pc, pr, nft, DEN_TO_WATER_DIST);
	  else
		get_rnd_pos(pc, pr, nft);
      ++num_attempts;
    }

    /* if it proves impossible to put the first den right in the middle then
	put it still quite close */
    if (num_attempts > 1999)

      while (((abs(middle_c-*pc)) > 6) || ((abs(middle_r-*pr)) > 6))

        get_rnd_pos(pc, pr, nft);

	/* note down the first den's coordinates */
	if (den_count == 0) {

	  first_den_c = *pc;
	  first_den_r = *pr;
	}

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] = (void *) malloc(sizeof(DEN));

    /* increment the 'number of features' counter for the area of the array*/
    env_arr[*pc][*pr].physical_f_count++;

    /* make relevant changes to the temperature, ability to escape
    detection, perception, and ability to escape in square */
    env_arr[*pc][*pr].temp_factor = 0.7;
    env_arr[*pc][*pr].escape_factor = 1.0;

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    den_count++;
  }
}


/* function to create an instance of fruit_food and return a pointer to it as a
result */
void get_fruit_food(number)
int number;
{

  int i, nft = FRUIT_FOOD_N;
  static int fruit_food_count;          /* used to keep instances in clumps
                                        when generated after start */
  int *pc, *pr, c = 0, r = 0;
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */
  FRUIT_FOOD *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

	/* have a probability of the fruit food occurring near water, else
	position it randomly anywhere */
	if (drand48() < FRUIT_FOOD_NEAR_WATER_PROB)
	  get_rnd_pos_near_water(pc, pr, nft, FRUIT_FOOD_TO_WATER_DIST);
	else
	  get_rnd_pos(pc, pr, nft);

    /* if this is the first instance of a cluster .... */
    if ((fruit_food_count%FRUIT_FOOD_CLUSTER_SIZE) == 0) {

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
      tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > FRUIT_FOOD_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > FRUIT_FOOD_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

        get_rnd_pos(pc, pr, nft);
        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
      (void *) malloc(sizeof(FRUIT_FOOD));

    ptr = (FRUIT_FOOD *) env_arr[*pc][*pr].p_arr[nft];

    /* the conditions, ie suitability of the site for growth, can vary between
    0.2 and 1.0 */
    ptr->conditions = get_fruit_food_conditions();

    /* the cycle length is the time between successive appearances of fruit */
    ptr->cycle_length = get_fruit_food_cycle_length();

    /* the ripe time is the number of days in each cycle that the fruit trees
    bear fruit */
    ptr->ripe_time = get_fruit_food_ripe_time(ptr->cycle_length);

    /* the cycle state is a measure of where each particular fruit source is
    in its cycle.  This value can vary from 0 to (cycle_length - 1) */
    ptr->cycle_state = get_fruit_food_cycle_state(ptr->cycle_length);

    /* the food value is a measure of the amount of food to be obtained at the
    source at a particular time */
	ptr->value = get_fruit_food_value(ptr->cycle_state, ptr->ripe_time,
		ptr->conditions);

    /* the toxicity is a measure of how ill the food will make the animal when
    it is eaten */
    if (drand48() < FRUIT_FOOD_TOXICITY_PROB) {

      /* give the food source a toxicity */
      ptr->toxicity = get_fruit_food_toxicity();

      /* make the toxic entry in the ptr array not null so will be drawn */
      env_arr[*pc][*pr].p_arr[TOXIC_N] = (void *) NOT_NULL;

/*g*/      /* draw the toxic symbol onto the square */
/*g*/      add_to_square(TOXIC_N, *pc, *pr);
/*g*/
      /* give the toxic food source a time interval after which the
      ill-health will start to take effect */
	  ptr->toxicity_delay = get_fruit_food_toxicity_delay();
    }
    else
      ptr->toxicity = 0.0;

    /* increment the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    /* make relevant changes to the temperature, ability to escape
    detection, perception, and ability to escape in square (assume thickness
	proportional to conditions) */
    env_arr[*pc][*pr].temp_factor -= (0.5 * ptr->conditions);
    env_arr[*pc][*pr].perception_factor -= (0.5 * ptr->conditions);
    env_arr[*pc][*pr].escape_factor += (0.5 * ptr->conditions);

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    ++fruit_food_count;
  }
}


/* function to create an instance of irrelevant and return a pointer to
it as a result */ 
void get_irrelevants(number)
int number;
{

  int i, nft = IRRELEVANT_N;
  int *pc, *pr, c = 0, r = 0;
  static int irrelevant_count;  /* number generated so far */
  static int direction;         /* direction irrelevant will tend to move in*/
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */
  int num_of_pack;              /* position of pack in array of structures */
  int num_in_pack;              /* position of irrelevant in pack array */
  IRRELEVANT *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    /* if this animal is the pack leader */
    if ((irrelevant_count%IRRELEVANT_CLUSTER_SIZE) == 0) {

      /* if this instance is being generated at the begining (and so does
      not need to appear at the edge) .... */
      if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
        get_rnd_pos(pc, pr, nft);

      else      /* if instance is being generated later */
        get_rnd_side_pos(pc, pr, nft, 2);

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {      /* animal is not pack leader */

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
      tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > IRRELEVANT_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > IRRELEVANT_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

        /* if this instance is being generated at the begining (and so does
        not need to appear at the edge) .... */
        if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
          get_rnd_pos(pc, pr, nft);

        else      /* if instance is being generated later */
          get_rnd_side_pos(pc, pr, nft, 2);

        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    ptr = (IRRELEVANT *) malloc(sizeof(IRRELEVANT));
    ptr->next_ptr = (IRRELEVANT *) env_arr[*pc][*pr].p_arr[nft];
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    /* if this animal is the pack leader */
    if ((irrelevant_count%IRRELEVANT_CLUSTER_SIZE) == 0) {

      num_of_pack = current_num_irrelevant_packs;
      num_in_pack = 0;

      ptr->pack_leader = TRUE;
      ptr->pack_number = num_of_pack;

      irrelevant_pack[num_of_pack].pack_leader_c = *pc;
      irrelevant_pack[num_of_pack].pack_leader_r = *pr;
      irrelevant_pack[num_of_pack].num_pack_in_env = 1;
      irrelevant_pack[num_of_pack].pack_leader_in_env = TRUE;

      current_num_irrelevant_packs++;

      direction = (int) rnd(8.0);
    }

    else {      /* this instance is not the pack leader */
    
      num_of_pack = current_num_irrelevant_packs - 1;
      num_in_pack = irrelevant_pack[num_of_pack].num_pack_in_env;

      ptr->pack_leader = FALSE;
      ptr->pack_number = num_of_pack;

      irrelevant_pack[num_of_pack].num_pack_in_env++;
    }

	ptr->north_prob = get_irrelevant_north_prob(direction);
	ptr->east_prob = get_irrelevant_east_prob(direction);
	ptr->south_prob = get_irrelevant_south_prob(direction);
	ptr->west_prob = get_irrelevant_west_prob(direction);

    ++irrelevant_count;
  }
}


/* function to create an instance of landmark and return a pointer to it as a
result */
void get_landmarks(number)
int number;
{
  static int number_generated;
  int i, nft = LANDMARK_N;
  int *pc, *pr, c = 0, r = 0;
  LANDMARK *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

	/* position the landmark randomly anywhere */ 
	get_rnd_pos(pc, pr, nft);

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
	ptr = (LANDMARK *) malloc(sizeof(LANDMARK));
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

    /* increment the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    ptr->number = number_generated;

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/	    add_to_square(nft, *pc, *pr);
/*g*/
    number_generated++;
  }
}


/* function to create an instance of mate and return a pointer to it as a
result */
void get_mates(number)
int number;
{

  int i, nft = MATE_N;
  int *pc, *pr, c = 0, r = 0;
  int direction;                /* direction mate will tend to move in */
  MATE *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
      get_rnd_pos(pc, pr, nft);
    else
      get_rnd_side_pos(pc, pr, nft, 1);
      
    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    ptr = (MATE *) malloc(sizeof(MATE));
    ptr->next_ptr = (MATE *) env_arr[*pc][*pr].p_arr[nft];
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

    /* the mate can be receptive (`on heat') or not receptive */
    ptr->receptive = get_mate_receptive();

    /* have a flag to show whether the mate has just been courted or not */
    ptr->courted = get_mate_courted();

    direction = (int) rnd(8.0);

	ptr->north_prob = get_mate_north_prob(direction);
	ptr->east_prob = get_mate_east_prob(direction);
	ptr->south_prob = get_mate_south_prob(direction);
	ptr->west_prob = get_mate_west_prob(direction);

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
  }
}


/* function to create an instance of predator_1 and return a pointer to it as a
result */
void get_predator_1s(number)
int number;
{

  int i, nft = PREDATOR_1_N;
  int *pc, *pr, c = 0, r = 0;
  static int predator_1_count;  /* number generated so far */
  static int pack_direction;    /* direction predator_1 will tend to move in*/
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */
  int num_of_pack;              /* position of pack in array of structures */
  int num_in_pack;              /* position of predator_1 in pack array */
  PREDATOR_1 *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    /* if this animal is the pack leader */
    if ((predator_1_count%PREDATOR_1_CLUSTER_SIZE) == 0) {

      /* if this instance is being generated at the begining (and so does
      not need to appear at the edge) .... */
      if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
        get_rnd_pos(pc, pr, nft);

      else      /* if instance is being generated later */
        get_rnd_side_pos(pc, pr, nft, 2);

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {      /* animal is not pack leader */

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
      tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > PREDATOR_1_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > PREDATOR_1_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

        /* if this instance is being generated at the begining (and so does
        not need to appear at the edge) .... */
        if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
          get_rnd_pos(pc, pr, nft);

        else      /* if instance is being generated later */
          get_rnd_side_pos(pc, pr, nft, 2);

        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    ptr = (PREDATOR_1 *) malloc(sizeof(PREDATOR_1));
    ptr->next_ptr = (PREDATOR_1 *) env_arr[*pc][*pr].p_arr[nft];
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

    /* generate values for the different fields */
    ptr->size = get_predator_1_size();
    ptr->damage = get_predator_1_damage(ptr->size);
    ptr->persistence = get_predator_1_persistence();
    ptr->time_chasing = get_predator_1_time_chasing();
    ptr->animal_spotted = get_predator_1_animal_spotted();
    ptr->chasing_animal = get_predator_1_chasing_animal();
    ptr->hungry = get_predator_1_hungry();

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    /* if this animal is the pack leader */
    if ((predator_1_count%PREDATOR_1_CLUSTER_SIZE) == 0) {

      num_of_pack = current_num_predator_1_packs;
      num_in_pack = 0;

      ptr->pack_leader = TRUE;
      ptr->pack_number = num_of_pack;

      predator_1_pack[num_of_pack].pack_leader_c = *pc;
      predator_1_pack[num_of_pack].pack_leader_r = *pr;
      predator_1_pack[num_of_pack].num_pack_in_env = 1;
      predator_1_pack[num_of_pack].pack_leader_in_env = TRUE;

      current_num_predator_1_packs++;

      pack_direction = (int) rnd(8.0);
    }

    else {      /* this instance is not the pack leader */
    
      num_of_pack = current_num_predator_1_packs - 1;
      num_in_pack = predator_1_pack[num_of_pack].num_pack_in_env;

      ptr->pack_leader = FALSE;
      ptr->pack_number = num_of_pack;

      predator_1_pack[num_of_pack].num_pack_in_env++;
    }

	ptr->north_prob = get_predator_1_north_prob(pack_direction);
	ptr->east_prob = get_predator_1_east_prob(pack_direction);
	ptr->south_prob = get_predator_1_south_prob(pack_direction);
	ptr->west_prob = get_predator_1_west_prob(pack_direction);

    ++predator_1_count;
  }
}


/* function to create an instance of predator_2 and return a pointer to it as a
result */
void get_predator_2s(number)
int number;
{

  int i, nft = PREDATOR_2_N;
  int *pc, *pr, c = 0, r = 0;
  int direction;                /* direction predator will tend to move in */
  PREDATOR_2 *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
      get_rnd_pos(pc, pr, nft);
    else
      get_rnd_side_pos(pc, pr, nft, 1);
      
    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    ptr = (PREDATOR_2 *) malloc(sizeof(PREDATOR_2));
    ptr->next_ptr = (PREDATOR_2 *) env_arr[*pc][*pr].p_arr[nft];
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

    /* calculate starting values for the different fields */
    ptr->damage = get_predator_2_damage();
    ptr->persistence = get_predator_2_persistence();
    ptr->time_chasing = get_predator_2_time_chasing();
    ptr->animal_spotted = get_predator_2_animal_spotted();
    ptr->chasing_animal = get_predator_2_chasing_animal();
    ptr->hungry = get_predator_2_hungry();

    direction = (int) rnd(8.0);        

	ptr->north_prob = get_predator_2_north_prob(direction);
	ptr->east_prob = get_predator_2_east_prob(direction);
	ptr->south_prob = get_predator_2_south_prob(direction);
	ptr->west_prob = get_predator_2_west_prob(direction);

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
  }
}


/* function to create an instance of prey and return a pointer to it as a
result */
void get_prey(number)
int number;
{

  int i, nft = PREY_N;
  int *pc, *pr, c = 0, r = 0;
  int direction;                /* direction prey will tend to move in */
  PREY *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    if ((daystep == 0) && (timestep == INIT_TIMESTEP_VALUE))
      get_rnd_pos(pc, pr, nft);
    else
      get_rnd_side_pos(pc, pr, nft, 1);
      
    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    ptr = (PREY *) malloc(sizeof(PREY));
    ptr->next_ptr = (PREY *) env_arr[*pc][*pr].p_arr[nft];
    env_arr[*pc][*pr].p_arr[nft] = (void *) ptr;

	ptr->value = get_prey_value();

    direction = (int) rnd(8.0);        

	ptr->north_prob = get_prey_north_prob(direction);
	ptr->east_prob = get_prey_east_prob(direction);
	ptr->south_prob = get_prey_south_prob(direction);
	ptr->west_prob = get_prey_west_prob(direction);

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
  }
}


/* function to create an instance of shade and return a pointer to it as a
result */
void get_shade(number)
int number;
{

  int i, nft = SHADE_N;
  static int shade_count;               /* used to keep instances in clumps
                                        when generated after start */
  int *pc, *pr, c = 0, r = 0;
  SHADE *ptr;
  static int cluster_c, cluster_r;      /* coords of centre of cluster */
  int num_attempts;                     /* number of attempts to get a random
                                        position within the cluster limits */

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

	/* have a probability of the shade occurring near water, else position
	it randomly anywhere */ 
	if (drand48() < SHADE_NEAR_WATER_PROB)
	  get_rnd_pos_near_water(pc, pr, nft, SHADE_TO_WATER_DIST);
	else
	  get_rnd_pos(pc, pr, nft);

    /* if this is the first instance of a cluster .... */
    if ((shade_count%SHADE_CLUSTER_SIZE) == 0) {

      /* set the cluster centre to these coordinates */
      cluster_c = *pc;
      cluster_r = *pr;
    }

    else {

      num_attempts = 0;

      *pc = -30;
      *pr = -30;

      /* keep getting random positions until inside cluster limits or until
         tried 2000 times with no success */
      while ((((abs(cluster_c-*pc)) > SHADE_CLUSTER_WIDTH) ||
        ((abs(cluster_r-*pr)) > SHADE_CLUSTER_WIDTH)) &&
        (num_attempts < 2000)) {

        get_rnd_pos(pc, pr, nft);
        num_attempts++;
      }
    }

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
      (void *) malloc(sizeof(SHADE));

    ptr = (SHADE *) env_arr[*pc][*pr].p_arr[nft];

    ptr->thickness = get_shade_thickness();

    /* increment the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    /* make relevant changes to the temperature, ability to escape
    detection, perception, and ability to escape in square */
    env_arr[*pc][*pr].temp_factor -= ptr->thickness;
    env_arr[*pc][*pr].perception_factor -= (0.5 * ptr->thickness);
    env_arr[*pc][*pr].escape_factor += (0.5 * ptr->thickness);

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
/*g*/
    ++shade_count;
  }
}


/* function to create an instance of water and return a pointer to it as a
result */
void get_water(number)
int number;
{

  int i, nft = WATER_N;
  int *pc, *pr, c = 0, r = 0;
  WATER *ptr;

  pc = &c; pr = &r;

  for (i = 0; i < number; ++i) {

    get_rnd_pos(pc, pr, nft);

    /* obtain an instance of the feature and 'attach' it to this area of the
    environment */
    env_arr[*pc][*pr].p_arr[nft] =
      (void *) malloc(sizeof(WATER));

    ptr = (WATER *) env_arr[*pc][*pr].p_arr[nft];

    /* give the water source an average size or capacity, as compared to
    other sources when rainfall, drinking, etc equal for each */
    ptr->average_size = get_water_average_size();

    /* the amount of water in this source is dependant on the amount of
    rainfall in the recent past, the temperature, and the average size of
    the source */
    ptr->value = get_water_value(ptr->average_size);

    /* give the water source a purity, or quality */
    if (drand48() < WATER_TOXICITY_PROB) {

      /* give the food source a toxicity */
      ptr->toxicity = get_water_toxicity();

      /* make the toxic entry in the ptr array not null so will be drawn */
      env_arr[*pc][*pr].p_arr[TOXIC_N] = (void *) NOT_NULL;

/*g*/      /* draw the toxic symbol onto the square */
/*g*/      add_to_square(TOXIC_N, *pc, *pr);
/*g*/
      /* give the toxic water source a time interval after which the
      ill-health will start to take effect */
	  ptr->toxicity_delay = get_water_toxicity_delay();
    }

    else
      ptr->toxicity = 0.0;

    /* value the 'number of features' counter for the area of the array */
    env_arr[*pc][*pr].physical_f_count++;

    /* add the structure to the feature list as well */
    f_list_add(nft, ((void *)ptr), pc, pr);

/*g*/    /* draw the image of the feature onto the environment pixrect */
/*g*/    add_to_square(nft, *pc, *pr);
  }
}


/* function to instantiate positions of environmental features randomly in
the environment so that no area gets too many features */
void get_rnd_pos(p_c, p_r, num_f_t)
int *p_c;
int *p_r;
int num_f_t;
{

  /* calculate a random position for the feature to be placed */
  *p_c = (int) rnd((double)ENV_ARR_COLS);
  *p_r = (int) rnd((double)ENV_ARR_ROWS);

  /* reposition the feature if this is a physical feature and there is
  already a physical feature there */
  while (PHYSICAL_FEATURE(num_f_t) &&
         (env_arr[*p_c][*p_r].physical_f_count > 0)) {

    /* calculate a random position for the feature to be placed */
    *p_c = (int) rnd((double)ENV_ARR_COLS);
    *p_r = (int) rnd((double)ENV_ARR_ROWS);
  }
}


/* function to instantiate positions of environmental features randomly in
the environment somewhere near to a water source */
void get_rnd_pos_near_water(p_c, p_r, num_f_t, distance)
int *p_c;
int *p_r;
int num_f_t;
int distance;
{

  int num_attempts = 0;

  /* calculate a random position for the feature to be placed */
  *p_c = (int) rnd((double)ENV_ARR_COLS);
  *p_r = (int) rnd((double)ENV_ARR_ROWS);

  /* reposition the feature if it is a physical one and there is already a
  physical feature in the square or if or if the position is not within the
  required distance of a water source */ 
  while ((num_attempts < 1000) &&
		 ((min_dist_to_water_source(*p_c, *p_r) > distance) ||
		  (PHYSICAL_FEATURE(num_f_t) &&
           (env_arr[*p_c][*p_r].physical_f_count > 0)))) {

    /* calculate a random position for the feature to be placed */
    *p_c = (int) rnd((double)ENV_ARR_COLS);
    *p_r = (int) rnd((double)ENV_ARR_ROWS);

    num_attempts++;
  }

  /* if failed to place near a water source then reposition the feature if
  this is a physical feature and there is already a physical feature there */
  while ((num_attempts > 999) &&
         (PHYSICAL_FEATURE(num_f_t) &&
          (env_arr[*p_c][*p_r].physical_f_count > 0))) {

    /* calculate a random position for the feature to be placed */
    *p_c = (int) rnd((double)ENV_ARR_COLS);
    *p_r = (int) rnd((double)ENV_ARR_ROWS);
  }
}


/* function to instantiate positions of environmental features randomly
around the edges of the environment */
void get_rnd_side_pos(p_c, p_r, num_f_t, prox)
register int *p_c;
register int *p_r;
register int num_f_t;
register int prox;            /* number of squares away from edge allowed */
{

  int num_attempts = 0;

  /* NOTE: prox should never be 0.  This won't be checked for though since
  too expensive (this function called very frequently) */

  /* calculate a random position for the feature to be placed */
  if (drand48() < 0.5) {
    *p_c = (int) rnd((double)ENV_ARR_COLS);
    *p_r = (ENV_ARR_ROWS - prox + ((int) rnd((double) (2.0*prox)))) %
      ENV_ARR_ROWS;
  }
  else {
    *p_c = (ENV_ARR_COLS - prox + ((int) rnd((double) (2.0*prox)))) %
      ENV_ARR_COLS;
    *p_r = (int) rnd((double)ENV_ARR_ROWS);
  }

  /* reposition the feature if it is a physiacl feature and there is already
  a physical feature there */
  while ((PHYSICAL_FEATURE(num_f_t) &&
          (env_arr[*p_c][*p_r].physical_f_count > 0)) &&
         (num_attempts < 1000)) {

    /* calculate a random position for the feature to be placed */
    if (drand48() < 0.5) {
      *p_c = (int) rnd((double)ENV_ARR_COLS);
      *p_r = (ENV_ARR_ROWS - prox + ((int) rnd((double) (2.0*prox)))) %
        ENV_ARR_ROWS;
    }
    else {
      *p_c = (ENV_ARR_COLS - prox + ((int) rnd((double) (2.0*prox)))) %
        ENV_ARR_COLS;
      *p_r = (int) rnd((double)ENV_ARR_ROWS);
    }

    num_attempts++;
  }

  /* if failed to place near the edge then reposition the feature if this is
  a physical feature and there is already a physical feature there */ 
  while ((num_attempts == 1000) &&
          PHYSICAL_FEATURE(num_f_t) &&
         (env_arr[*p_c][*p_r].physical_f_count > 0)) {

    /* calculate a random position for the feature to be placed */
    *p_c = (int) rnd((double)ENV_ARR_COLS);
    *p_r = (int) rnd((double)ENV_ARR_ROWS);
  }
}


/* function to return the minimum distance from the square whose coordinates
are given to any water source */
int min_dist_to_water_source(c, r)
int c;          /* square coordinates */
int r;
{

  int i;
  int min_dist_sqrd, this_dist_sqrd;

  /* set to arbitrary high value */
  min_dist_sqrd = 100000;

  /* for each instance of water */
  for (i = 0; i < f_list[WATER_N].count; ++i) {

    /* if distance squared < current minimum distance squared then set
    minimum to that */ 
    this_dist_sqrd =
        (f_list[WATER_N].column[i]-c) * (f_list[WATER_N].column[i]-c)
        + (f_list[WATER_N].row[i]-r) * (f_list[WATER_N].row[i]-r);

    if (this_dist_sqrd < min_dist_sqrd)
      min_dist_sqrd = this_dist_sqrd;
  }

  /* return integer of square root of minimum distance */
  return((int) sqrt((double) min_dist_sqrd));
}


/* function to initialise the value of the conditions attribute for a
cereal_food instance */
double get_cereal_food_conditions()
{

  return(rnd(0.9));
}


/* function to initialise the food-value attribute for a cereal_food
instance */
double get_cereal_food_value(cond)
double cond;		/* the suitability of the site for growth */
{

  double result;

  /* the food value is a measure of the amount of food to be obtained at the
  source at a particular time (should on average be less than fruit-type
  food).  It depends on the soil conditions and weather */
  if (env_dryness < OPT_DRYNESS)
    result = cond * env_dryness / ((double)OPT_DRYNESS);
  else
	result = cond * (1.0-env_dryness) / (1.0-((double)OPT_DRYNESS));

  return(result);

}


/* function to initialise the value of the toxicity attribute for a
cereal_food instance given that instance is definitely toxic */
double get_cereal_food_toxicity()
{

  return((rnd(0.15)));
}


/* function to initialise the value of the toxicity_delay attribute for a
cereal_food instance given that instance is definitely toxic */
int get_cereal_food_toxicity_delay()
{

  int result;

  if (drand48() < 0.5) 
    result = (int) rnd(((double) DAY_LENGTH/5));
  else if (drand48() < 0.9)
    result = (int) rnd(((double) DAY_LENGTH/3));
  else 
    result = (int) rnd(((double) DAY_LENGTH));

  return(result);
}


/* function to initialise the thickness of a cover instance */
double get_cover_thickness()
{

  return(drand48());
}


/* function to initialise the value of the conditions attribute for a
fruit_food instance */
double get_fruit_food_conditions()
{

  return((0.4 + rnd(0.6)));
}


/* function to initialise the cycle-length attribute for a fruit_food
instance */
int get_fruit_food_cycle_length()
{

  return(((int) (5.0 + rnd(6.0))));
}


/* function to initialise the value of the ripe-time attribute for a
fruit_food instance */
double get_fruit_food_ripe_time(c_l)
int c_l;		/* length of ripening-decaying cycle */
{

  return(((double) ((int) (((double)c_l) / (1.5+drand48())))));
}


/* function to initialise the cycle-state attribute for a fruit_food
instance */
int get_fruit_food_cycle_state(c_l)
int c_l;		/* length of ripening-decaying cycle */
{

  return(((int) rnd(((double)c_l))));
}


/* function to initialise the food-value attribute for a fruit_food instance*/
double get_fruit_food_value(c_s, r_t, cond)
int c_s;		/* position in cycle */
double r_t;		/* number of timesteps (stored as double) source is ripe */
double cond;		/* size/bushiness/healthiness of instance */
{

  double result;

  if (c_s > ((int)r_t))
    result = 0.0;
  else
	result = cond;

  return(result);
}


/* function to initialise the value of the toxicity attribute for a
fruit_food instance given that instance is definitely toxic */
double get_fruit_food_toxicity()
{

  return(rnd(0.40));
}


/* function to initialise the value of the toxicity_delay attribute for a
fruit_food instance given that instance is definitely toxic */
int get_fruit_food_toxicity_delay()
{

  int result;

  if (drand48() < 0.5) 
    result = (int) rnd(((double) DAY_LENGTH/5));
  else if (drand48() < 0.9)
    result = (int) rnd(((double) DAY_LENGTH/3));
  else 
    result = (int) rnd(((double) DAY_LENGTH));

  return(result);
}


/* function to initialise the probability of an irrelevant heading
northwards at each timestep */
double get_irrelevant_north_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.70);
    case (1): return(0.40);
    case (2): return(0.10);
    case (3): return(0.10);
    case (4): return(0.10);
    case (5): return(0.10);
    case (6): return(0.10);
    case (7): return(0.40);
  }
}


/* function to initialise the probability of an irrelevant heading
eastwards at each timestep */
double get_irrelevant_east_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.10);
    case (1): return(0.40);
    case (2): return(0.70);
    case (3): return(0.40);
    case (4): return(0.10);
    case (5): return(0.10);
    case (6): return(0.10);
    case (7): return(0.10);
  }
}


/* function to initialise the probability of an irrelevant heading
southwards at each timestep */
double get_irrelevant_south_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.10);
    case (1): return(0.10);
    case (2): return(0.10);
    case (3): return(0.40);
    case (4): return(0.70);
    case (5): return(0.40);
    case (6): return(0.10);
    case (7): return(0.10);
  }
}


/* function to initialise the probability of an irrelevant heading
westwards at each timestep */
double get_irrelevant_west_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.10);
    case (1): return(0.10);
    case (2): return(0.10);
    case (3): return(0.10);
    case (4): return(0.10);
    case (5): return(0.40);
    case (6): return(0.70);
    case (7): return(0.40);
  }
}


/* function to initialise the receptiveness of a mate */
int get_mate_receptive()
{

  return(((drand48() < 0.50) ? TRUE : FALSE));
}


/* function to initialise the "courted" attribute of a mate */
int get_mate_courted()
{

  return(FALSE);
}


/* function to initialise the probability of a mate heading northwards at
each timestep */
double get_mate_north_prob(direction)
int direction;		/* prevalent direction of travel of mate */
{

  switch (direction) {

    case (0): return(0.70);
    case (1): return(0.40);
    case (2): return(0.10);
    case (3): return(0.10);
    case (4): return(0.10);
    case (5): return(0.10);
    case (6): return(0.10);
    case (7): return(0.40);
  }
}


/* function to initialise the probability of a mate heading eastwards at
each timestep */
double get_mate_east_prob(direction)
int direction;		/* prevalent direction of travel of mate */
{

  switch (direction) {

    case (0): return(0.10);
    case (1): return(0.40);
    case (2): return(0.70);
    case (3): return(0.40);
    case (4): return(0.10);
    case (5): return(0.10);
    case (6): return(0.10);
    case (7): return(0.10);
  }
}


/* function to initialise the probability of a mate heading southwards at
each timestep */
double get_mate_south_prob(direction)
int direction;		/* prevalent direction of travel of mate */
{

  switch (direction) {

    case (0): return(0.10);
    case (1): return(0.10);
    case (2): return(0.10);
    case (3): return(0.40);
    case (4): return(0.70);
    case (5): return(0.40);
    case (6): return(0.10);
    case (7): return(0.10);
  }
}


/* function to initialise the probability of a mate heading westwards at
each timestep */
double get_mate_west_prob(direction)
int direction;		/* prevalent direction of travel of mate */
{

  switch (direction) {

    case (0): return(0.10);
    case (1): return(0.10);
    case (2): return(0.10);
    case (3): return(0.10);
    case (4): return(0.10);
    case (5): return(0.40);
    case (6): return(0.70);
    case (7): return(0.40);
  }
}


/* function to initialise the size attribute of a predator_1 */
double get_predator_1_size()
{

  return((0.3 + rnd(0.7)));
}


/* function to initialise the damage attribute of a predator_1 */
double get_predator_1_damage(size)
double size;		/* predator's size */
{

  double result;

  result = size * (0.7 + rnd(0.6));
  if (result >= 1.0)
    result = 0.9999;
  
  return(result);
}


/* function to initialise the persistence attribute of a predator_1 */
double get_predator_1_persistence()
{

  return(((double) ((int) (6.0 + rnd(8.0)))));
}


/* function to initialise the time chasing attribute of a predator_1 */
double get_predator_1_time_chasing()
{

  return(0.0);
}


/* function to initialise the animal spotted attribute of a predator_1 */
int get_predator_1_animal_spotted()
{

  return(FALSE);
}


/* function to initialise the "chasing animal" attribute of a predator_1 */
int get_predator_1_chasing_animal()
{

  return(FALSE);
}


/* function to initialise the `hungry' attribute of a predator_1 */
int get_predator_1_hungry()
{

  return(((drand48() < 0.9) ? TRUE : FALSE));
}


/* function to initialise the probability of the predator_1 heading
northwards at each timestep */
double get_predator_1_north_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.85);
    case (1): return(0.45);
    case (2): return(0.05);
    case (3): return(0.05);
    case (4): return(0.05);
    case (5): return(0.05);
    case (6): return(0.05);
    case (7): return(0.45);
  }
}


/* function to initialise the probability of the predator_1 heading
eastwards at each timestep */
double get_predator_1_east_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.05);
    case (1): return(0.45);
    case (2): return(0.85);
    case (3): return(0.45);
    case (4): return(0.05);
    case (5): return(0.05);
    case (6): return(0.05);
    case (7): return(0.05);
  }
}


/* function to initialise the probability of the predator_1 heading
southwards at each timestep */
double get_predator_1_south_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {

    case (0): return(0.05);
    case (1): return(0.05);
    case (2): return(0.05);
    case (3): return(0.45);
    case (4): return(0.85);
    case (5): return(0.45);
    case (6): return(0.05);
    case (7): return(0.05);
  }
}


/* function to initialise the probability of the predator_1 heading
westwards at each timestep */
double get_predator_1_west_prob(pack_direction)
int pack_direction;		/* prevalent direction of travel of pack */
{

  switch (pack_direction) {
    case (0): return(0.05);
    case (1): return(0.05);
    case (2): return(0.05);
    case (3): return(0.05);
    case (4): return(0.05);
    case (5): return(0.45);
    case (6): return(0.85);
    case (7): return(0.45);
  }
}


/* function to initialise the damage attribute of a predator_2 */
double get_predator_2_damage()
{

  return((0.3 + rnd(0.7)));
}


/* function to initialise the persistence attribute of a predator_2 */
double get_predator_2_persistence()
{

  return(((double) (int) (4.0 + rnd(5.0))));
}


/* function to initialise the time chasing attribute of a predator_2 */
double get_predator_2_time_chasing()
{

  return(0.0);
}


/* function to initialise the animal spotted attribute of a predator_2 */
int get_predator_2_animal_spotted()
{

  return(FALSE);
}


/* function to initialise the "chasing animal" attribute of a predator_2 */
int get_predator_2_chasing_animal()
{

  return(FALSE);
}


/* function to initialise the `hungry' attribute of a predator_2 */
int get_predator_2_hungry()
{

  return(((drand48() < 0.9) ? TRUE : FALSE));
}


/* function to initialise the probability of the predator_2 heading
northwards at each timestep */
double get_predator_2_north_prob(direction)
int direction;		/* prevalent direction of travel of predator_2 */
{

  switch (direction) {

    case (0): return(0.85);
    case (1): return(0.45);
    case (2): return(0.05);
    case (3): return(0.05);
    case (4): return(0.05);
    case (5): return(0.05);
    case (6): return(0.05);
    case (7): return(0.45);
  }
}


/* function to initialise the probability of the predator_2 heading
eastwards at each timestep */
double get_predator_2_east_prob(direction)
int direction;		/* prevalent direction of travel of predator_2 */
{

  switch (direction) {

    case (0): return(0.05);
    case (1): return(0.45);
    case (2): return(0.85);
    case (3): return(0.45);
    case (4): return(0.05);
    case (5): return(0.05);
    case (6): return(0.05);
    case (7): return(0.05);
  }
}


/* function to initialise the probability of the predator_2 heading
southwards at each timestep */
double get_predator_2_south_prob(direction)
int direction;		/* prevalent direction of travel of predator_2 */
{

  switch (direction) {

    case (0): return(0.05);
    case (1): return(0.05);
    case (2): return(0.05);
    case (3): return(0.45);
    case (4): return(0.85);
    case (5): return(0.45);
    case (6): return(0.05);
    case (7): return(0.05);
  }
}


/* function to initialise the probability of the predator_2 heading
westwards at each timestep */
double get_predator_2_west_prob(direction)
int direction;		/* prevalent direction of travel of predator_2 */
{

  switch (direction) {
    case (0): return(0.05);
    case (1): return(0.05);
    case (2): return(0.05);
    case (3): return(0.05);
    case (4): return(0.05);
    case (5): return(0.45);
    case (6): return(0.85);
    case (7): return(0.45);
  }
}


/* function to initialise the value attribute of a prey instance */
double get_prey_value()
{

  return((rnd(0.25)));
}


/* function to initialise the probability of the prey heading northwards at
each timestep */
double get_prey_north_prob(direction)
int direction;		/* prevalent direction of travel of prey */
{

  switch (direction) {

    case (0): return(0.40);
    case (1): return(0.30);
    case (2): return(0.20);
    case (3): return(0.20);
    case (4): return(0.20);
    case (5): return(0.20);
    case (6): return(0.20);
    case (7): return(0.30);
  }
}


/* function to initialise the probability of the prey heading eastwards at
each timestep */
double get_prey_east_prob(direction)
int direction;		/* prevalent direction of travel of prey */
{

  switch (direction) {

    case (0): return(0.20);
    case (1): return(0.30);
    case (2): return(0.40);
    case (3): return(0.30);
    case (4): return(0.20);
    case (5): return(0.20);
    case (6): return(0.20);
    case (7): return(0.20);
  }
}


/* function to initialise the probability of the prey heading southwards at
each timestep */
double get_prey_south_prob(direction)
int direction;		/* prevalent direction of travel of prey */
{

  switch (direction) {

    case (0): return(0.20);
    case (1): return(0.20);
    case (2): return(0.20);
    case (3): return(0.30);
    case (4): return(0.40);
    case (5): return(0.30);
    case (6): return(0.20);
    case (7): return(0.20);
  }
}


/* function to initialise the probability of the prey heading westwards at
each timestep */
double get_prey_west_prob(direction)
int direction;		/* prevalent direction of travel of prey */
{

  switch (direction) {
    case (0): return(0.20);
    case (1): return(0.20);
    case (2): return(0.20);
    case (3): return(0.20);
    case (4): return(0.20);
    case (5): return(0.30);
    case (6): return(0.40);
    case (7): return(0.30);
  }
}


/* function to initialise the thickness attribute of a shade instance */
double get_shade_thickness()
{

  return((0.2 + rnd(0.8)));
}


/* function to initialise the average size of the water source */
double get_water_average_size()
{

  return((0.4 + rnd(0.6)));
}


/* function to initialise the amount of water at the water source */
double get_water_value(av_size)
double av_size;			/* average size of water source */
{

  double result;

  result = 4.0 * av_size * (0.2 + 0.8 * (1.0 - env_dryness));
  if (result > 1.0)
	result = 0.999999;

  return(result);
}


/* function to initialise the value of the toxicity attribute for a
water instance given that instance is definitely toxic */
double get_water_toxicity()
{

  return(rnd(0.20));
}


/* function to initialise the value of the toxicity attribute for a
water instance given that instance is definitely toxic */
int get_water_toxicity_delay()
{

  int result;

  if (drand48() < 0.5) 
    result = (int) rnd(((double) DAY_LENGTH/5));
  else if (drand48() < 0.9)
    result = (int) rnd(((double) DAY_LENGTH/3));
  else 
    result = (int) rnd(((double) DAY_LENGTH));

  return(result);
}





