

/*----------------------------------------------------------------------------
|                                                                             |
| PROGRAM TO TEST DIFFERENT BEHAVIOURAL STRATEGIES IN A SIMULATED ENVIRONMENT |
|                                                                             |
|                                                               Toby Tyrrell. |
|                                                   Version 3.1.2 : 26-07-90. |
 ----------------------------------------------------------------------------*/

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

extern WORK_STRUCT work_packet;  /* already a global, just let me see! JB*/
FILE *regression_f;              /* info about the environment... */

/* the function behave sets up a random animal environment, and then places
the animal inside it and monitors its performance until it dies.  It then
returns the value of the animal's genetic fitness (the measure of how well
the animal performed) */
double behave(argc, argv)
int argc;
char *argv[];
{

  tob_f = fopenwithcheck("causes_of_death", "a");

  /* save info about this environment for regression  JB */
  regression_f = fopenwithcheck("env_data", "a");
  fprintf (regression_f, "# %d  wt %d  ", work_packet.indvdl_number,
	   work_packet.slave_type);

/*g*/
/*g*/  process_command_line_args(argc, argv);
/*g*/
/*g*/  read_in_images();
/*g*/
/*g*/  set_up_graphics();

  set_up_env();

  set_up_animal();
/*g*/
/*g*//*  set_up_scroll();
/*g*/
  set_up_strategy();

  /* keep running program until animal dead */
  while (animal_alive == TRUE) {

	/* calculate what the animal perceives of the environment */
	animal_perception();

	/* update the animal's navigational memory */
	update_animal_map();

	/* let the animal decide what its next action will be */
	strategy_choice();

/*g*/  update_strategy_display();
/*g*/
/*g*/      /* slow down the program if chosen on panel */
/*g*/	  usleep(delay);
/*g*/
/*g*/  	  /* bring all the displays up to date */
/*g*/      notify_dispatch();
/*g*/
/*g*/      while ((paused == TRUE) && (step == FALSE))
/*g*/        notify_dispatch();
/*g*/      step = FALSE;
/*g*/
	/* make any changes to the environment as a result of the animal's
	actions (e.g. eating food) */
	animal_change_to_env();

    /* update the environment by one timestep */
    update_1_env();

	/* make any changes to the animal as a result of changes in the
	environment (e.g. predator's moving) */
	env_change_to_animal();

	if ((timestep%10) == 0)
	  update_10_env();

	if (timestep == DAY_LENGTH) {
	  update_day_env();
	  printf("day number %d\n", daystep);
	  fflush(stdout);
	}
/*g*/
/*g*/	  if ((timestep%250) == 0)
/*g*/		draw_map();
/*g*/
/*g*/	  /* if animal has just died */
/*g*/	  if (animal_alive == FALSE) {
/*g*/		
/*g*/		/* show analysis of its life and how it died */ 
/*g*/		show_analysis();
/*g*/
/*g*/		paused = TRUE;
/*g*/		while (paused)
/*g*/		  notify_dispatch();
/*g*/
/*g*/			/* destroy all windows and start again */
/*g*/			destroy(env_frame);
/*g*/			destroy(weather_frame);
/*g*/			destroy(key_frame);
/*g*/			destroy(analysis_frame);
/*g*/			destroy(perception_frame);
/*g*/			destroy(animal_frame);
/*g*/			destroy(map_frame);
/*g*/			destroy(nav_frame);
/*g*/			destroy(long_profile_frame);
/*g*/           paused = FALSE;
/*g*/           step = FALSE;
/*g*/           delay = 0;
/*g*/           current_num_irrelevant_packs = 0;
/*g*/           current_num_predator_1_packs = 0;
/*g*/	  }
  }

  free_memory();

  lifespan = ((double) daystep) +
			 (((double) timestep) / ((double) DAY_LENGTH)) -
			 (((double) INIT_TIMESTEP_VALUE) / ((double) DAY_LENGTH));

  fclose(tob_f);

  /* the last of the enviroment data... */
  fprintf (regression_f, "ls %lf  gf %d\n", lifespan, genetic_fitness);
  fclose (regression_f);

  return(((double) genetic_fitness));
}


/*g*//* Function to read the command line arguments and then use them to set the
/*g*//*size of the window if they are within specified limits */
/*g*/void process_command_line_args(argc, argv)
/*g*/int argc;
/*g*/char *argv[];
/*g*/{
/*g*/
/*g*/  int max_width = SCREEN_WIDTH - 10;    /* taking account of space for */
/*g*/  int max_height = SCREEN_HEIGHT - 23;  /* margins and frame title     */
/*g*/
/*g*/  /* if the size of the picture of the environment is smaller than the
/*g*//*  screen then limit the size of the window to that of the environment */
/*g*/  if ((ENV_ARR_COLS*SQUARE_SIZE+1) < max_width)
/*g*/    max_width = (ENV_ARR_COLS*SQUARE_SIZE+1);
/*g*/  if ((ENV_ARR_ROWS*SQUARE_SIZE+1) < max_height)
/*g*/    max_height = (ENV_ARR_ROWS*SQUARE_SIZE) + 1 + PANEL_HEIGHT + 13;
/*g*/
/*g*/  win_width = 776;
/*g*/  win_height = 776;
/*g*/
/*g*/  if (win_width < MIN_WIN_WIDTH) {
/*g*/    printf("\nwindow width must be > %d.\n", MIN_WIN_WIDTH);
/*g*/    exit(0);
/*g*/  }
/*g*/  if (win_width > max_width) {
/*g*/    printf("\nwindow width must be < %d.\n", max_width);
/*g*/    exit(0);
/*g*/  }
/*g*/  if (win_height < (MIN_WIN_HEIGHT+PANEL_HEIGHT+13)) {
/*g*/    printf("\nwindow height must be > %d.\n",(MIN_WIN_HEIGHT+PANEL_HEIGHT+13));
/*g*/    exit(0);
/*g*/  }
/*g*/  if (win_height > max_height) {
/*g*/    printf("\nwindow height must be < %d.\n", max_height);
/*g*/    exit(0);
/*g*/  }
/*g*/}
/*g*/
/*g*/
/*g*//* function to read in raster images from files into pixrects */
/*g*/void read_in_images()
/*g*/{
/*g*/
/*g*/  FILE *f;
/*g*/  char image_file_name[30];
/*g*/
/*g*/  sprintf(image_file_name, "icons/cereal_food");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[CEREAL_FOOD_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/cover");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[COVER_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/dangerous_place");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[DANGEROUS_PLACE_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/den");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[DEN_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/fruit_food");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[FRUIT_FOOD_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/irrelevant");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[IRRELEVANT_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/landmark");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[LANDMARK_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/mate");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[MATE_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/predator_1");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[PREDATOR_1_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/predator_2");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[PREDATOR_2_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/prey");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[PREY_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/shade");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[SHADE_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/water");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[WATER_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/toxic");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[TOXIC_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  /* image of animal */
/*g*/  sprintf(image_file_name, "icons/animal");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  feature_pr[ANIMAL_N] = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  /* weather images */
/*g*/  sprintf(image_file_name, "icons/rain");    
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  rain_pr = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/cloud");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  cloud_pr = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/
/*g*/  sprintf(image_file_name, "icons/ssun");
/*g*/  f = fopenwithcheck(image_file_name, "r");
/*g*/  ssun_pr = pr_load(f, null_cmap);
/*g*/  fclose(f);
/*g*/}
/*g*/
/*g*/
/*g*//* this functions initialises the frame, canvas, pixwin, colourmap, etc for
/*g*//*the program */
/*g*/void set_up_graphics()
/*g*/{
/*g*/
/*g*/  /* initialise the fonts */
/*g*/  set_up_fonts();
/*g*/
/*g*/  /* set up the foreground and background colours */
/*g*/  bg_clr_ptr = &bg_clr;
/*g*/  fg_clr_ptr = &fg_clr;
/*g*/  bg_clr_ptr->red = ((u_char) 255);
/*g*/  bg_clr_ptr->blue = ((u_char) 255);
/*g*/  bg_clr_ptr->green = ((u_char) 255);
/*g*/  fg_clr_ptr->red = ((u_char) 0);
/*g*/  fg_clr_ptr->blue = ((u_char) 0);
/*g*/  fg_clr_ptr->green = ((u_char) 0);
/*g*/
/*g*/  /* create frame to cover most of screen */
/*g*/  env_frame = window_create(NULL, FRAME,
/*g*/    WIN_SHOW, TRUE,
/*g*/    FRAME_BACKGROUND_COLOR, bg_clr_ptr,
/*g*/    FRAME_FOREGROUND_COLOR, fg_clr_ptr,
/*g*/    FRAME_LABEL, "Simulated Environment",
/*g*/    WIN_WIDTH, (win_width+10),
/*g*/    WIN_HEIGHT, (win_height+PANEL_HEIGHT+31),
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 0,
/*g*/    0);
/*g*/
/*g*/  /* create 'control' panel */
/*g*/  env_panel = window_create(env_frame, PANEL,
/*g*/    WIN_SHOW, TRUE,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 3,
/*g*/    WIN_WIDTH, win_width,
/*g*/    WIN_HEIGHT, PANEL_HEIGHT,
/*g*/    0);
/*g*/
/*g*/  /* create 'control' panel */
/*g*/  env_panel = window_create(env_frame, PANEL,
/*g*/    WIN_SHOW, TRUE,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 3,
/*g*/    WIN_WIDTH, win_width,
/*g*/    WIN_HEIGHT, PANEL_HEIGHT,
/*g*/    0);
/*g*/
/*g*/  /* contents of panel */
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(0),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Internal on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(18),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Weather on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(34),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Key on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(0),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Prcptn on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(18),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Nvgtn on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(34),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Map on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_MESSAGE,
/*g*/    PANEL_ITEM_X, ATTR_COL(0),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(2),
/*g*/    PANEL_LABEL_FONT, serif_r_12,
/*g*/    PANEL_LABEL_STRING, "Profiles on/off",
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(48),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Quit   ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, quit_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(48),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Pause  ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, pause_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(48),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(2),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Restart", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, restart_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(60),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Faster", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, faster_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(60),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Slower", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, slower_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(60),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(2),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, "Step", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, step_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(15),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, animal_change_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(31),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, weather_change_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(44),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(0),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, key_change_proc,
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(15),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, perception_change_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(31),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, nav_change_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(44),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(1),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, map_change_proc,    
/*g*/    0);
/*g*/
/*g*/  (void) panel_create_item(env_panel, PANEL_BUTTON,
/*g*/    PANEL_ITEM_X, ATTR_COL(15),
/*g*/    PANEL_ITEM_Y, ATTR_ROW(2),
/*g*/    PANEL_LABEL_IMAGE,
/*g*/      panel_button_image(env_panel, " ", 0, serif_r_12),
/*g*/    PANEL_NOTIFY_PROC, profile_change_proc,    
/*g*/    0);
/*g*/
/*g*/  sprintf(text, "day:  %d", daystep);
/*g*/  day_message = panel_create_item(env_panel, PANEL_MESSAGE, 
/*g*/    PANEL_ITEM_X, ATTR_COL(70),
/*g*/    PANEL_ITEM_Y, ATTR_COL(0),
/*g*/    PANEL_LABEL_STRING, text,
/*g*/    0);
/*g*/
/*g*/  sprintf(text, "time: %d", timestep);
/*g*/  time_message = panel_create_item(env_panel, PANEL_MESSAGE, 
/*g*/    PANEL_ITEM_X, ATTR_COL(70),
/*g*/    PANEL_ITEM_Y, ATTR_COL(1),
/*g*/    PANEL_LABEL_STRING, text,
/*g*/    0);
/*g*/
/*g*/  /* panel message to show whether it is day or night */
/*g*/  sprintf(text, "night");
/*g*/  daynight_message = panel_create_item(env_panel, PANEL_MESSAGE, 
/*g*/    PANEL_ITEM_X, ATTR_COL(70),
/*g*/    PANEL_ITEM_Y, ATTR_COL(2),
/*g*/    PANEL_LABEL_STRING, text,
/*g*/    0);
/*g*/
/*g*/  /* panel message to show what the animal is doing */
/*g*/  sprintf(text, "sleeping");
/*g*/  action_message = panel_create_item(env_panel, PANEL_MESSAGE, 
/*g*/    PANEL_ITEM_X, ATTR_COL(80),
/*g*/    PANEL_ITEM_Y, ATTR_COL(0),
/*g*/    PANEL_LABEL_STRING, text,
/*g*/    0);
/*g*/
/*g*/  /* create canvas */
/*g*/  env_canvas = window_create(env_frame, CANVAS,
/*g*/    WIN_SHOW, TRUE,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, (PANEL_HEIGHT + 8),
/*g*/	CANVAS_AUTO_SHRINK, FALSE,
/*g*/	CANVAS_AUTO_EXPAND, FALSE,
/*g*/    CANVAS_RETAINED, TRUE,
/*g*/    CANVAS_WIDTH, win_width,
/*g*/    CANVAS_HEIGHT, win_height,
/*g*/    WIN_WIDTH, win_width,
/*g*/    WIN_HEIGHT, win_height,
/*g*/    0);
/*g*/
/*g*/  /* create pixwin for program */
/*g*/  env_pw = canvas_pixwin(env_canvas);
/*g*/
/*g*/  /* initialise the colourmap */
/*g*/  set_colourmap();
/*g*/
/*g*/  /* set up the required rasterops */
/*g*/  set_ops();
/*g*/
/*g*/  /* create an icon */
/*g*/  make_icon();
/*g*/
/*g*/  /* attach colourmap to pixwin */
/*g*/  pw_setcmsname(env_pw, "notimportant");
/*g*/  pw_putcolormap(env_pw, 0, CMAP_SIZE, red, green, blue);
/*g*/}
/*g*/
/*g*/
/*g*//* function to set the colourmap for the graphics */
/*g*/void set_colourmap()
/*g*/{
/*g*/
/*g*/  int i;
/*g*/
/*g*/  /* set the colourmap */
/*g*/  for (i = 0; i < CMAP_SIZE; ++i)
/*g*/    red[i] = green[i] = blue[i] = 250;
/*g*/  red[0] = green[0] = blue[0] = 0;
/*g*/
/*g*/  red[CEREAL_FOOD_N*5+1]   = (250 / 10) * 6;      		 /* cereal food */
/*g*/  green[CEREAL_FOOD_N*5+1] = (250 / 10) * 6;
/*g*/  blue[CEREAL_FOOD_N*5+1]  = 0;
/*g*/
/*g*/  red[CEREAL_FOOD_N*5+2]   = (250 / 10) * 7;      		 /* cereal food */
/*g*/  green[CEREAL_FOOD_N*5+2] = (250 / 10) * 7;
/*g*/  blue[CEREAL_FOOD_N*5+2]  = 0;
/*g*/
/*g*/  red[CEREAL_FOOD_N*5+3]   = (250 / 10) * 8;      		 /* cereal food */
/*g*/  green[CEREAL_FOOD_N*5+3] = (250 / 10) * 8;
/*g*/  blue[CEREAL_FOOD_N*5+3]  = 0;
/*g*/
/*g*/  red[CEREAL_FOOD_N*5+4]   = (250 / 10) * 9;      		 /* cereal food */
/*g*/  green[CEREAL_FOOD_N*5+4] = (250 / 10) * 9;
/*g*/  blue[CEREAL_FOOD_N*5+4]  = 0;
/*g*/
/*g*/  red[CEREAL_FOOD_N*5+5]   = (250 / 10) * 10;      		 /* cereal food */
/*g*/  green[CEREAL_FOOD_N*5+5] = (250 / 10) * 10;
/*g*/  blue[CEREAL_FOOD_N*5+5]  = 0;
/*g*/
/*g*/  red[COVER_N*5+1]   = (150 / 10) * 6; 		 /* cover */
/*g*/  green[COVER_N*5+1] = (230 / 10) * 6;
/*g*/  blue[COVER_N*5+1]  = (80 / 10) * 6;
/*g*/
/*g*/  red[COVER_N*5+2]   = (150 / 10) * 7; 		 /* cover */
/*g*/  green[COVER_N*5+2] = (230 / 10) * 7;
/*g*/  blue[COVER_N*5+2]  = (80 / 10) * 7;
/*g*/
/*g*/  red[COVER_N*5+3]   = (150 / 10) * 8; 		 /* cover */
/*g*/  green[COVER_N*5+3] = (230 / 10) * 8;
/*g*/  blue[COVER_N*5+3]  = (80 / 10) * 8;
/*g*/
/*g*/  red[COVER_N*5+4]   = (150 / 10) * 9; 		 /* cover */
/*g*/  green[COVER_N*5+4] = (230 / 10) * 9;
/*g*/  blue[COVER_N*5+4]  = (80 / 10) * 9;
/*g*/
/*g*/  red[COVER_N*5+5]   = (150 / 10) * 10; 		 /* cover */
/*g*/  green[COVER_N*5+5] = (230 / 10) * 10;
/*g*/  blue[COVER_N*5+5]  = (80 / 10) * 10;
/*g*/
/*g*/  red[DANGEROUS_PLACE_N*5+5]   = 170;  	        /* dangerous place */
/*g*/  green[DANGEROUS_PLACE_N*5+5] = 170;	
/*g*/  blue[DANGEROUS_PLACE_N*5+5]  = 170;
/*g*/
/*g*/  red[DEN_N*5+5]   = 150;  	       		        /* den */
/*g*/  green[DEN_N*5+5] = 130;	
/*g*/  blue[DEN_N*5+5]  = 110;
/*g*/
/*g*/  red[FRUIT_FOOD_N*5+1]   = (230 / 10) * 6;		/* fruit food */
/*g*/  green[FRUIT_FOOD_N*5+1] = (60 / 10) * 6;
/*g*/  blue[FRUIT_FOOD_N*5+1]  = (70 / 10) * 6;
/*g*/
/*g*/  red[FRUIT_FOOD_N*5+2]   = (230 / 10) * 7;		/* fruit food */
/*g*/  green[FRUIT_FOOD_N*5+2] = (60 / 10) * 7;
/*g*/  blue[FRUIT_FOOD_N*5+2]  = (70 / 10) * 7;
/*g*/
/*g*/  red[FRUIT_FOOD_N*5+3]   = (230 / 10) * 8;		/* fruit food */
/*g*/  green[FRUIT_FOOD_N*5+3] = (60 / 10) * 8;
/*g*/  blue[FRUIT_FOOD_N*5+3]  = (70 / 10) * 8;
/*g*/
/*g*/  red[FRUIT_FOOD_N*5+4]   = (230 / 10) * 9;		/* fruit food */
/*g*/  green[FRUIT_FOOD_N*5+4] = (60 / 10) * 9;
/*g*/  blue[FRUIT_FOOD_N*5+4]  = (70 / 10) * 9;
/*g*/
/*g*/  red[FRUIT_FOOD_N*5+5]   = (230 / 10) * 10;		/* fruit food */
/*g*/  green[FRUIT_FOOD_N*5+5] = (60 / 10) * 10;
/*g*/  blue[FRUIT_FOOD_N*5+5]  = (70 / 10) * 10;
/*g*/
/*g*/  red[IRRELEVANT_N*5+5]   = 200;  	   		 /* irrelevant */
/*g*/  green[IRRELEVANT_N*5+5] = 170;	
/*g*/  blue[IRRELEVANT_N*5+5]  = 170;
/*g*/
/*g*/  red[LANDMARK_N*5+5]   = 180;  	   		 /* landmark */
/*g*/  green[LANDMARK_N*5+5] = 180;	
/*g*/  blue[LANDMARK_N*5+5]  = 180;
/*g*/
/*g*/  red[MATE_N*5+5]   = 210;   	       		 /* mate */
/*g*/  green[MATE_N*5+5] = 180; 	
/*g*/  blue[MATE_N*5+5]  = 80;
/*g*/
/*g*/  red[PREDATOR_1_N*5+5]   = 200;       		 /* predator 1 */
/*g*/  green[PREDATOR_1_N*5+5] = 170;	
/*g*/  blue[PREDATOR_1_N*5+5]  = 100;
/*g*/
/*g*/  red[PREDATOR_2_N*5+5]   = 170;      		 /* predator 2 */
/*g*/  green[PREDATOR_2_N*5+5] = 170;	
/*g*/  blue[PREDATOR_2_N*5+5]  = 170;
/*g*/
/*g*/  red[PREY_N*5+5]   = 160;  	       		 /* prey */
/*g*/  green[PREY_N*5+5] = 140;	
/*g*/  blue[PREY_N*5+5]  = 120;
/*g*/
/*g*/  red[SHADE_N*5+1]   = (200 / 8) * 4; 		 /* shade */
/*g*/  green[SHADE_N*5+1] = (200 / 8) * 4;
/*g*/  blue[SHADE_N*5+1]  = 0;
/*g*/
/*g*/  red[SHADE_N*5+2]   = (200 / 8) * 5; 		 /* shade */
/*g*/  green[SHADE_N*5+2] = (200 / 8) * 5;
/*g*/  blue[SHADE_N*5+2]  = 0;
/*g*/
/*g*/  red[SHADE_N*5+3]   = (200 / 8) * 6; 		 /* shade */
/*g*/  green[SHADE_N*5+3] = (200 / 8) * 6;
/*g*/  blue[SHADE_N*5+3]  = 0;
/*g*/
/*g*/  red[SHADE_N*5+4]   = (200 / 8) * 7; 		 /* shade */
/*g*/  green[SHADE_N*5+4] = (200 / 8) * 7;
/*g*/  blue[SHADE_N*5+4]  = 0;
/*g*/
/*g*/  red[SHADE_N*5+5]   = (200 / 8) * 8; 		 /* shade */
/*g*/  green[SHADE_N*5+5] = (200 / 8) * 8;
/*g*/  blue[SHADE_N*5+5]  = 0;
/*g*/
/*g*/  red[WATER_N*5+1]   = (90 / 10) * 6; 		 /* water */
/*g*/  green[WATER_N*5+1] = (90 / 10) * 6;
/*g*/  blue[WATER_N*5+1]  = (230 / 10) * 6;
/*g*/
/*g*/  red[WATER_N*5+2]   = (90 / 10) * 7; 		 /* water */
/*g*/  green[WATER_N*5+2] = (90 / 10) * 7;
/*g*/  blue[WATER_N*5+2]  = (230 / 10) * 7;
/*g*/
/*g*/  red[WATER_N*5+3]   = (90 / 10) * 8; 		 /* water */
/*g*/  green[WATER_N*5+3] = (90 / 10) * 8;
/*g*/  blue[WATER_N*5+3]  = (230 / 10) * 8;
/*g*/
/*g*/  red[WATER_N*5+4]   = (90 / 10) * 9; 		 /* water */
/*g*/  green[WATER_N*5+4] = (90 / 10) * 9;
/*g*/  blue[WATER_N*5+4]  = (230 / 10) * 9;
/*g*/
/*g*/  red[WATER_N*5+5]   = (90 / 10) * 10; 		 /* water */
/*g*/  green[WATER_N*5+5] = (90 / 10) * 10;
/*g*/  blue[WATER_N*5+5]  = (230 / 10) * 10;
/*g*/
/*g*/  red[TOXIC_N*5+5]   = 130;					 /* toxic */
/*g*/  green[TOXIC_N*5+5] = 130;
/*g*/  blue[TOXIC_N*5+5]  = 130;
/*g*/
/*g*/  red[ANIMAL_N*5+1]   = (210 / 7) * 3; 		 /* animal
/*g*/  green[ANIMAL_N*5+1] = (180 / 7) * 3;
/*g*/  blue[ANIMAL_N*5+1]  = (80 / 7) * 3;
/*g*/
/*g*/  red[ANIMAL_N*5+2]   = (210 / 7) * 4; 		 /* animal */
/*g*/  green[ANIMAL_N*5+2] = (180 / 7) * 4;
/*g*/  blue[ANIMAL_N*5+2]  = (80 / 7) * 4;
/*g*/
/*g*/  red[ANIMAL_N*5+3]   = (210 / 7) * 5; 		 /* animal */
/*g*/  green[ANIMAL_N*5+3] = (180 / 7) * 5;
/*g*/  blue[ANIMAL_N*5+3]  = (80 / 7) * 5;
/*g*/
/*g*/  red[ANIMAL_N*5+4]   = (210 / 7) * 6; 		 /* animal */
/*g*/  green[ANIMAL_N*5+4] = (180 / 7) * 6;
/*g*/  blue[ANIMAL_N*5+4]  = (80 / 7) * 6;
/*g*/
/*g*/  red[ANIMAL_N*5+5]   = (210 / 7) * 7; 		 /* animal */
/*g*/  green[ANIMAL_N*5+5] = (180 / 7) * 7;
/*g*/  blue[ANIMAL_N*5+5]  = (80 / 7) * 7;
/*g*/
/*g*/  red[96]   = 0;                   /* grey used for perception display */
/*g*/  green[96] = 0;
/*g*/  blue[96]  = 0;
/*g*/
/*g*/  red[97]   = 40;                   /* grey used for perception display */
/*g*/  green[97] = 40;
/*g*/  blue[97]  = 40;
/*g*/
/*g*/  red[98]   = 80;                   /* grey used for perception display */
/*g*/  green[98] = 80;
/*g*/  blue[98]  = 80;
/*g*/
/*g*/  red[99]   = 120;                   /* grey used for perception display */
/*g*/  green[99] = 120;
/*g*/  blue[99]  = 120;
/*g*/
/*g*/  red[100]   = 160;                   /* grey used for perception display */
/*g*/  green[100] = 160;
/*g*/  blue[100]  = 160;
/*g*/
/*g*/  red[(CMAP_SIZE-1)] = green[(CMAP_SIZE-1)] = blue[(CMAP_SIZE-1)] = 250;
/*g*/}
/*g*/
/*g*/
/*g*//* function to set up the different rasterops required for the program */
/*g*/void set_ops()
/*g*/{
/*g*/
/*g*/  int i;
/*g*/
/*g*/  for (i = 0; i < CMAP_SIZE; ++i)
/*g*/    op[i] = ((PIX_SRC|PIX_COLOR(i)) | PIX_DST);
/*g*/}
/*g*/
/*g*/
/*g*//* function to set up the fonts to be used by the program */
/*g*/void set_up_fonts()
/*g*/{
/*g*/
/*g*/  /* define the fonts used in the program */
/*g*/  serif_r_12 = pf_open("/usr/lib/fonts/fixedwidthfonts/serif.r.12");
/*g*/  serif_r_14 = pf_open("/usr/lib/fonts/fixedwidthfonts/serif.r.14");
/*g*/}
/*g*/
/*g*/
/* function to initialise the environment by deciding where the different
features are */
void set_up_env()
{

  int i, j, k, jbscratch;

  animal_alive = TRUE;

  /* initialise time variables */
  daystep = 0;
  timestep = INIT_TIMESTEP_VALUE;
  part_of_day = NIGHT;

  /* initialise structures for each area of the array */
  for (i = 0; i < ENV_ARR_COLS; ++i)
    for (j = 0; j < ENV_ARR_ROWS; ++j) {

	  /* no features in squares yet */
      env_arr[i][j].physical_f_count = 0;

	  /* set all pointers to null */
      for (k = 0; k < NUM_FEATURE_TYPES; ++k)
        env_arr[i][j].p_arr[k] = (void *) NULL;

      env_arr[i][j].temp_factor = 1.0;
      env_arr[i][j].perception_factor = 1.0;
      env_arr[i][j].escape_factor = 0.0;
    }

  current_num_irrelevant_packs = 0;
  current_num_predator_1_packs = 0;

  /* initialise structures (lists of instances) for different feature types */
  init_feature_lists();

  /* initialise the state of weather */
  init_weather();

  /* initialise the state of rainfall */
  init_rainfall();

  /* initialise the state of temperature */
  init_temp();

  /* initialise the value of the environment dryness */
  init_dryness();

/*g*//* create a display to show the state of the weather in the simulated
/*g*//*  environment */ 
/*g*/  set_up_weather_display();
/*g*/
/*g*/  /* create a display to show a key on */
/*g*/  set_up_key_display();
/*g*/
/*g*/  /* create a display for what the animal can perceive in the environment */
/*g*/  set_up_animal_display();
/*g*/
/*g*/  /* create a display to give an analysis of the life (and death!) of the
/*g*//*  animal once it has died */
/*g*/  set_up_analysis_display();
/*g*/
/*g*/  set_up_perc_display();
/*g*/
/*g*/  turn_on(env_frame);

	/* put a certain number of water features in the environment (NOTE: water 
	instances have to be generated first to allow other features to be
	positioned around them) */

        jbscratch = INIT_NUM_WATER;
	get_water(jbscratch);
	fprintf (regression_f, "w %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of cereal_food features in the environment */
        jbscratch = INIT_NUM_CEREAL_FOOD;
	get_cereal_food(jbscratch);
	fprintf (regression_f, "cf %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of dangerous place features in the environment */
        jbscratch = INIT_NUM_COVER;
	get_cover(jbscratch);
	fprintf (regression_f, "cv %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of dangerous_place features in the environment */
	get_dangerous_places(INIT_NUM_DANGEROUS_PLACE);
/*g*/	notify_dispatch();

	/* put a certain number of den features in the environment */
	get_dens(INIT_NUM_DEN);
/*g*/	notify_dispatch();

	/* put a certain number of fruit_food features in the environment */
        jbscratch = INIT_NUM_FRUIT_FOOD;
	get_fruit_food(jbscratch);
	fprintf (regression_f, "ff %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of irrelevant features in the environment */
	get_irrelevants(INIT_NUM_IRRELEVANT);
/*g*/	notify_dispatch();

	/* put a certain number of landmark features in the environment */
	get_landmarks(INIT_NUM_LANDMARK);
/*g*/	notify_dispatch();

	/* put a certain number of mate features in the environment */
        jbscratch = INIT_NUM_MATE;
	get_mates(jbscratch);
	fprintf (regression_f, "m %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of predator_1 features in the environment */
	get_predator_1s(INIT_NUM_PREDATOR_1);
/*g*/	notify_dispatch();

	/* put a certain number of predator_2 features in the environment */
	get_predator_2s(INIT_NUM_PREDATOR_2);
/*g*/	notify_dispatch();

	/* put a certain number of prey features in the environment */
        jbscratch = INIT_NUM_PREY;
	get_prey(jbscratch);
	fprintf (regression_f, "p %d  ", jbscratch);
/*g*/	notify_dispatch();

	/* put a certain number of shade features in the environment */
	get_shade(INIT_NUM_SHADE);
/*g*/	notify_dispatch();

  set_up_navigation();
}

/*g*/
/*g*//* function to read in the icon image and attach it to the frame for the
/*g*//*program */
/*g*/void make_icon()
/*g*/{
/*g*/
/*g*/  env_icon = icon_create(ICON_IMAGE, &icon_pixrect, 0);
/*g*/  window_set(env_frame, FRAME_ICON, env_icon, 0);
/*g*/}
/*g*/
/*g*/
/*g*//* function to initialise a display showing a key for the environment */
/*g*/void set_up_key_display()
/*g*/{
/*g*/
/*g*/  int i;
/*g*/
/*g*/  key_frame = window_create(NULL, FRAME,
/*g*/    WIN_SHOW, FALSE,
/*g*/    FRAME_LABEL, "Key to Feature Types",
/*g*/    WIN_WIDTH, 350,
/*g*/    WIN_HEIGHT, 510,
/*g*/    WIN_X, 50,
/*g*/    WIN_Y, 50,
/*g*/    0);
/*g*/
/*g*/  /* create canvas */
/*g*/  key_canvas = window_create(key_frame, CANVAS,
/*g*/    WIN_SHOW, TRUE,
/*g*/    CANVAS_AUTO_EXPAND, TRUE,
/*g*/    CANVAS_AUTO_SHRINK, TRUE,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 0,
/*g*/    WIN_WIDTH, 350,
/*g*/    WIN_HEIGHT, 510,
/*g*/    0);
/*g*/
/*g*/  /* create pixwin for key display */
/*g*/  key_pw = canvas_pixwin(key_canvas);
/*g*/
/*g*/  window_fit(key_frame);
/*g*/
/*g*/  /* attach colourmap to pixwin */
/*g*/  pw_setcmsname(key_pw, "notimportant");
/*g*/  pw_putcolormap(key_pw, 0, CMAP_SIZE, red, green, blue);
/*g*/
/*g*/  /* draw in images of features */
/*g*/  for (i = 0; i < (NUM_FEATURE_TYPES-1); ++i)
/*g*/
/*g*/    pw_rop(key_pw, 1, (i*SQUARE_SIZE + 26), SQUARE_SIZE, SQUARE_SIZE,
/*g*/		   ((PIX_SRC|PIX_COLOR(5*(i+1))) | PIX_DST), feature_pr[i], 0, 0); 
/*g*/
/*g*/  /* add the explanatory comments */
/*g*/  pw_text(key_pw, 1, 15, (PIX_SRC|PIX_COLOR(30)), serif_r_12,
/*g*/    " Lighter shades imply greater value to the animal ");
/*g*/
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(CEREAL_FOOD_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - cereal type food"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(COVER_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - cover"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(DANGEROUS_PLACE_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - dangerous place");   
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(DEN_N+1)+10),
/*g*/    	  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - den");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(FRUIT_FOOD_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - fruit type food"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(IRRELEVANT_N+1)+10),
/*g*/	      (PIX_SRC|PIX_COLOR(30)),
/*g*/		  serif_r_12, " - irrelevant animal (just needs avoiding)");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(LANDMARK_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - landmark"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(MATE_N+1)+10), 
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - mate");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(PREDATOR_1_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - predator (type 1)"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(PREDATOR_2_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - predator (type 2)"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(PREY_N+1)+10), 
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - prey");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(SHADE_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - shade");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(WATER_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12, " - water source");
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(TOXIC_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)), serif_r_12,
/*g*/		  " - toxic food or water source"); 
/*g*/  pw_text(key_pw, (SQUARE_SIZE+10), (SQUARE_SIZE*(ANIMAL_N+1)+10),
/*g*/		  (PIX_SRC|PIX_COLOR(30)),
/*g*/		  serif_r_12, " - animal whose behaviour is being modelled");
/*g*/}
/*g*/
/*g*/
/*g*//* function to initialise a display showing an analysis of the animal's
/*g*//*life (and death!).  This will be displayed once the animal dies */
/*g*/void set_up_analysis_display()
/*g*/{
/*g*/
/*g*/  int i;
/*g*/
/*g*/  analysis_frame = window_create(NULL, FRAME,
/*g*/    WIN_SHOW, FALSE,
/*g*/    FRAME_LABEL, "Analysis",
/*g*/    WIN_WIDTH, 650,
/*g*/    WIN_HEIGHT, 400,
/*g*/    WIN_X, 400,
/*g*/    WIN_Y, 400,
/*g*/    0);
/*g*/
/*g*/  analysis_panel = window_create(analysis_frame, PANEL,
/*g*/    WIN_SHOW, TRUE,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 3,
/*g*/    WIN_WIDTH, 650,
/*g*/    WIN_HEIGHT, 27,
/*g*/    0);
/*g*/
/*g*/  panel_create_item(analysis_panel, PANEL_BUTTON, 
/*g*/	PANEL_LABEL_IMAGE, 
/*g*/	panel_button_image(analysis_panel, " Run Program Again ", 0, serif_r_12),
/*g*/	PANEL_NOTIFY_PROC, rerun_proc,
/*g*/  0);
/*g*/
/*g*/  panel_create_item(analysis_panel, PANEL_BUTTON, 
/*g*/	PANEL_LABEL_IMAGE, 
/*g*/	panel_button_image(analysis_panel, " Quit Program ", 0, serif_r_12),
/*g*/	PANEL_NOTIFY_PROC, quit_proc,
/*g*/  0);
/*g*/
/*g*/  analysis_text_win = window_create(analysis_frame, TEXTSW,
/*g*/	TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,		/* stops veto when
/*g*//*												destroying textsw window */
/*g*/    WIN_SHOW, TRUE,
/*g*/    WIN_FONT, serif_r_12,
/*g*/    WIN_X, 0,
/*g*/    WIN_Y, 35,
/*g*/    WIN_WIDTH, 650,
/*g*/    WIN_HEIGHT, 365,
/*g*/  0);
/*g*/
/*g*/  /* open a file to which will be written all the info. concerning what
/*g*//*  injuries the animal incurs etc., which can then be dumped to the textsw
/*g*//*  when the animal dies */
/*g*/  analysis_info_f = fopen("analysis", "w");
/*g*/
/*g*/  /* write some preliminary blurb to that file */
/*g*/  fprintf(analysis_info_f,
/*g*/	"The animal's health can vary between 0.0 (death) and 1.0 (max)\n\n");
/*g*/}
/*g*/
/*g*/
/*g*//* function to display key */
/*g*/void key_change_proc()
/*g*/{
/*g*/
/*g*/  if (window_get(key_frame, WIN_SHOW) == FALSE)
/*g*/	turn_on(key_frame);
/*g*/  else
/*g*/	turn_off(key_frame);
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to slow down the speed at which the environment runs */
/*g*/void slower_proc()
/*g*/{
/*g*/
/*g*/  /* increase the delay introduced in each timestep */
/*g*/  if (delay < 10000)
/*g*/	delay = 10000;
/*g*/  else
/*g*/    delay *= 3;
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to increase the speed at which the environment runs */
/*g*/void faster_proc()
/*g*/{
/*g*/
/*g*/  /* reduce if possible the delay introduced in each timestep */
/*g*/  if (delay < 100)
/*g*/	delay = 100;
/*g*/  else
/*g*/    delay /= 3;
/*g*/}
/*g*/

void update_1_env()
{

	update_1_cereal_food();
	update_1_cover();
	update_1_fruit_food();
	update_1_shade();
	update_1_water();
	update_1_irrelevant();
	update_1_mate();
	update_1_predator_1();
	update_1_predator_2();
	update_1_prey();

  update_1_time_variables();
}


void update_10_env()
{

  /* update various weather-related variables */
  update_weather();
  update_rainfall();
  update_temp();
/*g*/  update_weather_display();

  update_10_water();
/*g*/
/*g*/  /* change the appearances of those features which have shades of colour and
/*g*//*  might have been affected by a change in weather or amount of grazing, etc.*/
/*g*/  update_graded_features();
}


void update_day_env()
{

  /* update weather variables */
  update_day_rainfall();
  update_day_temp();
  update_day_dryness();

  /* update environmental features */
  update_day_cereal_food();
  update_day_fruit_food();
  update_day_water();
  
  daystep++;
  timestep = 0;
/*g*/
/*g*/  sprintf(text, "time: %d", timestep);
/*g*/  panel_set(time_message, PANEL_LABEL_STRING, text, 0);
/*g*/  sprintf(text, "day:  %d", daystep);
/*g*/  panel_set(day_message, PANEL_LABEL_STRING, text, 0);
}


/*g*//* function to print the contents of the analysis file into the textsw and
/*g*//*then to display the textsw */
/*g*/void show_analysis()
/*g*/{
/*g*/
/*g*/  /* write details about animal's life to analysis file */
/*g*/  fprintf(analysis_info_f,
/*g*/	"\n\n Length of animal's life was %.3f (max. = %.3f)\n\n",
/*g*/	(((double)daystep) + (((double)timestep)/((double)DAY_LENGTH))),
/*g*/	MAX_ANIMAL_LIFESPAN);
/*g*/  fprintf(analysis_info_f," Genetic fitness = number of matings =");
/*g*/  fprintf(analysis_info_f, " success measure = %d\n", genetic_fitness);
/*g*/  fclose(analysis_info_f);
/*g*/
/*g*/  /* copy contents of file into textsw */
/*g*/  window_set(analysis_text_win, TEXTSW_INSERT_FROM_FILE, "analysis", 0);
/*g*/
/*g*/  /* turn on the textsw */
/*g*/  turn_on(analysis_frame);
/*g*/  turn_on(analysis_text_win);
/*g*/
/*g*/  notify_dispatch();
/*g*/}
/*g*/

/* function to initialise the different 'lists' that denote where instances
of different feature types are located in the environment */
void init_feature_lists()
{

  int i, j;

  for (i = 0; i < NUM_FEATURE_TYPES; ++i) {
    f_list[i].count = 0;

	for (j = 0; j < MAX_NUM_ANY_FEATURE_TYPE; j++) {
	  f_list[i].f_ptr[j] = ((void *) NULL);
	  f_list[i].row[j] = -100;
	  f_list[i].column[j] = -100;
	}
  }
}


/* function to add an instance of a feature to one of the lists that denote
where instances of different feature types are located in the environment */
void f_list_add(nft, ptr, pc, pr)
int nft;                /* the number of the feature type */
void *ptr;              /* a pointer to the feature */
int *pc;           		/* its position in the env_array */
int *pr;
{

  register int count = f_list[nft].count;

  /* add the pointer and coordinates to the end of the list */
  f_list[nft].f_ptr[count]  = ptr;
  f_list[nft].column[count] = *pc;;
  f_list[nft].row[count]    = *pr;

  /* increment the list counter */
  f_list[nft].count++;
}


/* function to remove an instance of a feature from a list that denotes where
instances of different feature types are located in the environment */ 
void f_list_remove(nft, index)
int nft;                /* the number of the feature type */
int index;              /* position in list of this instance */
{

  register int count = f_list[nft].count;

  /* copy the pointer and coordinates from the end of the list to this
  position (thereby deleting this item) */
  f_list[nft].f_ptr[index]  = f_list[nft].f_ptr[count-1];
  f_list[nft].column[index] = f_list[nft].column[count-1];
  f_list[nft].row[index]    = f_list[nft].row[count-1];

  /* decrement list count (so that item just copied only occurs once in list)*/
  f_list[nft].count--;
}

/*g*/
/*g*//* procedure to quit from the program */
/*g*/void quit_proc()
/*g*/{
/*g*/
/*g*/  exit(0);
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to cause the program to be run again */
/*g*/void rerun_proc()
/*g*/{
/*g*/
/*g*/  /* stay paused until user asks for this option */
/*g*/  paused = FALSE;
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to pause the program */
/*g*/void pause_proc()
/*g*/{
/*g*/
/*g*/  paused = TRUE;
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to restart the program after it has been paused */
/*g*/void restart_proc()
/*g*/{
/*g*/
/*g*/  paused = FALSE;
/*g*/}
/*g*/
/*g*/
/*g*//* procedure to make the program step (go forward one timestep) */
/*g*/void step_proc()
/*g*/{
/*g*/  
/*g*/  step = TRUE;
/*g*/}
/*g*/
/*g*/
/*g*//* a function to add the picture of a feature to a square of the array
/*g*//*using the list of pointers for that square */
/*g*/void add_to_square(nft, c, r)
/*g*/int nft;        /* the number of the feature type */
/*g*/int c;
/*g*/int r;          /* coordinates of square */
/*g*/{
/*g*/
/*g*/  register int colour;	/* entry in colourmap to be used */
/*g*/  register void *ptr;
/*g*/
/*g*/  ptr = env_arr[c][r].p_arr[nft];
/*g*/
/*g*/  switch(nft) {
/*g*/   	case(CEREAL_FOOD_N): colour = nft*5 + 1 +
/*g*/		                   ((int) (((CEREAL_FOOD *) ptr)->value * 5.0));
/*g*/	  break;
/*g*/	case(COVER_N): colour = nft*5 + 1 +
/*g*/                     ((int) (((COVER *) ptr)->thickness * 5.0));
/*g*/	  break;
/*g*/	case(FRUIT_FOOD_N): colour = nft*5 + 1 +
/*g*/		                  ((int) (((FRUIT_FOOD *) ptr)->value * 4.99999));
/*g*/	  break;
/*g*/    case(PREDATOR_1_N): colour = (PREDATOR_1_N+1)*5;
/*g*/      break;
/*g*/    case(PREDATOR_2_N): colour = (PREDATOR_2_N+1)*5;
/*g*/      break;
/*g*/	case(SHADE_N): colour = nft*5 + 1 +
/*g*/                     ((int) (((SHADE *) ptr)->thickness * 5.0));
/*g*/	  break;
/*g*/	case(WATER_N): colour = nft*5 + 1 +
/*g*/                     ((int) (((WATER *) ptr)->value * 5.0));
/*g*/	  break;
/*g*/	case(TOXIC_N): colour = (nft+1)*5;
/*g*/	  break;
/*g*/	default: colour = (5 * (nft+1));
/*g*/  }
/*g*/
/*g*/  /* draw the image of this feature over whatever's there */
/*g*/  pw_stencil(env_pw, (c*SQUARE_SIZE+1), (r*SQUARE_SIZE+1),
/*g*/	SQUARE_SIZE, SQUARE_SIZE, (PIX_SRC|PIX_COLOR(colour)),
/*g*/	feature_pr[nft], 0, 0, NULL, 0, 0); 
/*g*/}
/*g*/
/*g*/
/*g*//* a function to redraw a square of the array using the list of pointers for
/*g*//*that square */
/*g*/void redraw_square(c, r)
/*g*/int c;
/*g*/int r;          /* coordinates of square */
/*g*/{
/*g*/
/*g*/  register int i;
/*g*/  register int colour;	/* entry in colourmap to be used */
/*g*/  register void *ptr;
/*g*/
/*g*/  /* first of all clear the square */
/*g*/  pw_rop(env_pw, (c*SQUARE_SIZE+1), (r*SQUARE_SIZE+1), SQUARE_SIZE,
/*g*/	SQUARE_SIZE, PIX_CLR, NULL, 0, 0);  
/*g*/
/*g*/  for (i = 0; i < NUM_FEATURE_TYPES; i++) {
/*g*/
/*g*/    /* if there is an instance of this feature type in the square .... */
/*g*/    if ((ptr = env_arr[c][r].p_arr[i]) != ((void *) NULL)) {
/*g*/
/*g*/      switch(i) {
/*g*/   	    case(CEREAL_FOOD_N): colour = CEREAL_FOOD_N*5 + 1 +
/*g*/		                   ((int) (((CEREAL_FOOD *) ptr)->value * 5.0));
/*g*/		   break;
/*g*/	    case(COVER_N): colour = COVER_N*5 + 1 +
/*g*/                     ((int) (((COVER *) ptr)->thickness * 5.0));
/*g*/		   break;
/*g*/	    case(FRUIT_FOOD_N): colour = FRUIT_FOOD_N*5 + 1 +
/*g*/		                  ((int) (((FRUIT_FOOD *) ptr)->value * 4.99999));
/*g*/		   break;
/*g*/	    case(PREDATOR_1_N): colour = (PREDATOR_1_N+1)*5;
/*g*/		   break;
/*g*/	    case(PREDATOR_2_N): colour = (PREDATOR_2_N+1)*5;
/*g*/		   break;
/*g*/	    case(SHADE_N): colour = SHADE_N*5 + 1 +
/*g*/                     ((int) (((SHADE *) ptr)->thickness * 5.0));
/*g*/		   break;
/*g*/	    case(WATER_N): colour = WATER_N*5 + 1 +
/*g*/                     ((int) (((WATER *) ptr)->value * 5.0));
/*g*/		   break;
/*g*/		case(TOXIC_N): colour = (TOXIC_N+1)*5;
/*g*/		  break;
/*g*/	    default: colour = (5 * (i+1));
/*g*/      }
/*g*/
/*g*/      /* draw the image of this feature over whatever's there */
/*g*/      pw_stencil(env_pw, (c*SQUARE_SIZE+1),	(r*SQUARE_SIZE+1),
/*g*/		SQUARE_SIZE, SQUARE_SIZE, (PIX_SRC|PIX_COLOR(colour)),
/*g*/		feature_pr[i], 0, 0, NULL, 0, 0);  
/*g*/    }
/*g*/  }
/*g*/}
/*g*/
/*g*/
/*g*//* a function to redraw a square of the array using the list of pointers for
/*g*//*that square.  Same as "redraw_square" except that it doesn't clear the
/*g*//*square first */
/*g*/void redraw_square_without_clearing(c, r)
/*g*/int c;
/*g*/int r;          /* coordinates of square */
/*g*/{
/*g*/
/*g*/  register int i;
/*g*/  register int colour;	/* entry in colourmap to be used */
/*g*/  register void *ptr;
/*g*/
/*g*/  for (i = 0; i < NUM_FEATURE_TYPES; i++)
/*g*/    /* if there is an instance of this feature type in the square .... */
/*g*/    if ((ptr = env_arr[c][r].p_arr[i]) != ((void *) NULL)) {
/*g*/
/*g*/      switch(i) {
/*g*/   	    case(CEREAL_FOOD_N): colour = CEREAL_FOOD_N*5 + 1 +
/*g*/		                   ((int) (((CEREAL_FOOD *) ptr)->value * 5.0));
/*g*/		  break;
/*g*/	    case(COVER_N): colour = COVER_N*5 + 1 +
/*g*/                     ((int) (((COVER *) ptr)->thickness * 5.0));
/*g*/		  break;
/*g*/	    case(FRUIT_FOOD_N): colour = FRUIT_FOOD_N*5 + 1 +
/*g*/		                  ((int) (((FRUIT_FOOD *) ptr)->value * 4.99999));
/*g*/		  break;
/*g*/	    case(PREDATOR_1_N): colour = (PREDATOR_1_N+1)*5;
/*g*/		  break;
/*g*/	    case(PREDATOR_2_N): colour = (PREDATOR_2_N+1)*5;
/*g*/		  break;
/*g*/	    case(SHADE_N): colour = SHADE_N*5 + 1 +
/*g*/                     ((int) (((SHADE *) ptr)->thickness * 5.0));
/*g*/		  break;
/*g*/	    case(WATER_N): colour = WATER_N*5 + 1 +
/*g*/                     ((int) (((WATER *) ptr)->value * 5.0));
/*g*/		  break;
/*g*/		case(TOXIC_N): colour = (TOXIC_N+1)*5;
/*g*/		  break;
/*g*/	    default: colour = (5 * (i+1));
/*g*/      }
/*g*/
/*g*/      /* draw the image of this feature over whatever's there */
/*g*/      pw_stencil(env_pw, (c*SQUARE_SIZE+1),	(r*SQUARE_SIZE+1),
/*g*/		SQUARE_SIZE, SQUARE_SIZE, (PIX_SRC|PIX_COLOR(colour)),
/*g*/		feature_pr[i], 0, 0, NULL, 0, 0);  
/*g*/    }
/*g*/}
/*g*/

/* function to update the values of time variables at each timestep */
void update_1_time_variables()
{

  int day_division;

  /* increment the value of timestep and change displayed value on screen */
  ++timestep;
/*g*/  sprintf(text, "time: %d", timestep);
/*g*/  panel_set(time_message, PANEL_LABEL_STRING, text, 0);

  /* decide from timestep what 'part' of the day it is */

  /* divide day up into twelfths */
  day_division = (int) (((double) timestep) / ((double) DAY_LENGTH) * 12.0);

  switch(day_division) {

    case(0): part_of_day = NIGHT;
             sprintf(text, "night");
		     break;
    case(1): part_of_day = NIGHT;
             sprintf(text, "night");
		     break;
    case(2): part_of_day = SUNRISE;
             sprintf(text, "sunrise");
		     break;
	case(3): part_of_day = MORNING;
             sprintf(text, "morning");
		     break;
    case(4): part_of_day = MORNING;
             sprintf(text, "morning");
		     break;
    case(5): part_of_day = MIDDAY;
             sprintf(text, "midday");
		     break;
    case(6): part_of_day = MIDDAY;
             sprintf(text, "midday");
		     break;
    case(7): part_of_day = AFTERNOON;
             sprintf(text, "afternoon");
		     break;
    case(8): part_of_day = AFTERNOON;
             sprintf(text, "afternoon");
		     break;
    case(9): part_of_day = SUNSET;
             sprintf(text, "sunset");
		     break;
    case(10): part_of_day = NIGHT;
              sprintf(text, "night");
		      break;
    case(11): part_of_day = NIGHT;
              sprintf(text, "night");
		      break;
  }

/*g*/  /* change message on screen */
/*g*/  panel_set(daynight_message, PANEL_LABEL_STRING, text, 0);
}


void free_memory()
{

  int i, j, k;

  /* free all items pointed to from env_arr */
  for (i = 0; i < ENV_ARR_COLS; ++i)
    for (j = 0; j < ENV_ARR_ROWS; ++j)
      for (k = 0; k < NUM_FEATURE_TYPES; ++k)
		if ((env_arr[i][j].p_arr[k] != ((void *) NULL)) &&
			(env_arr[i][j].p_arr[k] != ((void *) NOT_NULL)))
		  free(env_arr[i][j].p_arr[k]);

  free_animal_memory();
}

