#!/usr/bin/perl
#
####################
# VacuumAgents.pl
#
# agent functions and performace measures 
# to be run in the GridWorld.pm environment.
#
# Jim Mahoney, Feb 3 2003
#####################################
use strict;
use warnings;

# --- agents and performance methods ----

# Input:  reference ($result->{key}=value) of results of actions.
# Output: numeric score for that result.
sub performanceMeasure {
  my ($result) = @_;
  return 100 if $result->{suck};
  return -1  if $result->{move};
  return 0;
}

# Input:  reference ($percepts->{key}=value) hash of perceptions.
# Output: action taken (string)
sub randomAgent {
  # my ($percepts) = @_;
  return (qw( forward forward forward 
	      turnRight turnLeft suck suck))[ int(rand(7)) ];
}

# Input:  reference ($percepts->{key}=value) hash of perceptions.
# Output: action taken (string)
sub reflexAgent {
  my ($percept) = @_;
  return 'suck'					if $percept->{dirt};
  return (qw(turnLeft turnRight))[int(rand(2))] if $percept->{bump};
  return (qw( forward forward forward 
	      turnRight turnLeft ))[ int(rand(5)) ];
}

# --- main ---------------------------------

# Create a new world for the agent to run on.
use GridWorld;
my $grid = new GridWorld( stuff		=> 'dirt',
			  randomFill	=> 0.7,
			  timeSteps	=> 40,
			  xSize		=> 8,
			  ySize		=> 8,
			);	
# Copy it to re-use later.
my $grid2 = $grid->clone();

# Let the random agent play in it.
print "--- Running the random agent -- \n";
my $score = $grid->runVacuumAgent( agent	 => \&randomAgent , 
				   performance  => \&performanceMeasure ,
				  );
print "Score = '$score'\n";
print "--- Finished random agent -- \n";

# Now run the reflex agent.
print "\n";
print "--- Running the reflex agent -- \n";
$score = $grid2->runVacuumAgent( agent	 => \&reflexAgent , 
				performance  => \&performanceMeasure ,
			      );
print "Score = '$score'\n";
print "--- Finished reflex agent -- \n";

# --- find averages of many runs; do less printing ---

my $total1 = 0;
my $total2 = 0;
print "\n == 20 runs == \n\n";
for (1..20){
  $grid = new GridWorld( stuff		=> 'dirt',
			 randomFill	=> 0.7,
			 timeSteps	=> 40,
			 xSize		=> 8,
			 ySize		=> 8,
		       );	
  #Copy it.
  $grid2 = $grid->clone();

  my $score2 = $grid2->runVacuumAgent( agent=>\&reflexAgent, verbose=>'no' );
  my $score1 = $grid->runVacuumAgent( agent=>\&randomAgent, verbose=>'no' );

  $total1 += $score1;
  $total2 += $score2;

  print "random gives $score1; reflex gives $score2 .\n";
}

print "\n";
print "Average random agent score was " . $total1/20 ."\n";
print "Average reflex agent score was " . $total2/20 ."\n";
print "\n";
print "\n";

