Add a Random player, simply does random commands on each turn
Remove simplePlayer in favor of new randomPlayer, which uses new ttrts.pm module
This commit is contained in:
parent
0d61b64517
commit
1af818a0b5
3 changed files with 283 additions and 131 deletions
179
perl/ttrts.pm
Normal file
179
perl/ttrts.pm
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#! /usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# Get information about a unit from it's descriptor
|
||||||
|
sub getUnit
|
||||||
|
{
|
||||||
|
return ($_[0] =~ /UNIT:(\d+) tm:(\d+) vs:([^ ]+) dr:([^ ]+) ps:\[(\d+),(\d+)\]/);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the units from a turn file
|
||||||
|
sub GetUnitsForTurn
|
||||||
|
{
|
||||||
|
my $turnFile = shift;
|
||||||
|
|
||||||
|
# Open the turn file
|
||||||
|
open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!";
|
||||||
|
|
||||||
|
# Skip the header information
|
||||||
|
my $headerLine = <$TURNHANDLE>;
|
||||||
|
my $sizeLine = <$TURNHANDLE>;
|
||||||
|
my $turnLine = <$TURNHANDLE>;
|
||||||
|
( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format";
|
||||||
|
|
||||||
|
my @units;
|
||||||
|
while( my $unitLine = <$TURNHANDLE> )
|
||||||
|
{
|
||||||
|
chomp $unitLine;
|
||||||
|
push(@units,$unitLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
close $TURNHANDLE;
|
||||||
|
|
||||||
|
return @units;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get information from the header for this turn
|
||||||
|
sub GetHeaderForTurn
|
||||||
|
{
|
||||||
|
my $turnFile = shift;
|
||||||
|
|
||||||
|
# Open the turn file
|
||||||
|
open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!";
|
||||||
|
|
||||||
|
# Pull in the header information
|
||||||
|
my $headerLine = <$TURNHANDLE>;
|
||||||
|
chomp $headerLine;
|
||||||
|
my $sizeLine = <$TURNHANDLE>;
|
||||||
|
chomp $sizeLine;
|
||||||
|
my $turnLine = <$TURNHANDLE>;
|
||||||
|
chomp $turnLine;
|
||||||
|
|
||||||
|
my ($gameName) = ( $headerLine =~ /===== ([^ ]+) =====/ );
|
||||||
|
my ($gameX,$gameY) = ( $sizeLine =~ /SIZE:\[(\d+),(\d+)\]/ );
|
||||||
|
|
||||||
|
( <$TURNHANDLE> =~ /~~~~/ ) or die "Gamestate file did not match expected format";
|
||||||
|
|
||||||
|
close $TURNHANDLE;
|
||||||
|
|
||||||
|
return ($gameName,$gameX,$gameY);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get units from a specific team
|
||||||
|
sub getUnitsOnTeam
|
||||||
|
{
|
||||||
|
my $theTeam = shift;
|
||||||
|
my @allUnits = @_;
|
||||||
|
my @myUnits;
|
||||||
|
|
||||||
|
for my $unit (@allUnits)
|
||||||
|
{
|
||||||
|
my ($unitTeam) = $unit =~ /tm:(\d+)/;
|
||||||
|
if ( $unitTeam == $theTeam )
|
||||||
|
{
|
||||||
|
push(@myUnits,$unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return @myUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub GetTurnFile
|
||||||
|
{
|
||||||
|
my $turn = shift;
|
||||||
|
my $turnFile = "Turn_TURN.txt";
|
||||||
|
$turnFile =~ s/TURN/$turn/;
|
||||||
|
return $turnFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub GetCommandFile
|
||||||
|
{
|
||||||
|
my $turn = shift;
|
||||||
|
my $team = shift;
|
||||||
|
my $cmdFileName = "Turn_TURN_Team_TEAM.txt";
|
||||||
|
$cmdFileName =~ s/TURN/$turn/;
|
||||||
|
$cmdFileName =~ s/TEAM/$team/;
|
||||||
|
return $cmdFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output the commands file
|
||||||
|
sub OutputCommandsFile
|
||||||
|
{
|
||||||
|
my $turn = shift;
|
||||||
|
my $team = shift;
|
||||||
|
my $commands = shift;
|
||||||
|
|
||||||
|
# Get output file
|
||||||
|
our $cmdFileName = GetCommandFile($turn,$team);
|
||||||
|
|
||||||
|
if (! -e $cmdFileName)
|
||||||
|
{
|
||||||
|
open(my $cmdFile, '>', $cmdFileName) or die "Couldn't open '$cmdFileName' $!";
|
||||||
|
print $cmdFile $commands;
|
||||||
|
close $cmdFile;
|
||||||
|
|
||||||
|
printf "Outputted $cmdFileName\n";
|
||||||
|
printf "$commands";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
open(my $cmdFile, '<', $cmdFileName) or die "Couldn't open '$cmdFileName' $!";
|
||||||
|
my $old_commands = do { <$cmdFile> };
|
||||||
|
|
||||||
|
printf "Replaying $cmdFileName\n";
|
||||||
|
printf "$old_commands";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print a game map
|
||||||
|
sub PrintGameMap
|
||||||
|
{
|
||||||
|
my $gameX = shift;
|
||||||
|
my $gameY = shift;
|
||||||
|
my @units = @_;
|
||||||
|
|
||||||
|
my @map;
|
||||||
|
|
||||||
|
# Fill with blanks
|
||||||
|
for my $x (0 .. $gameX-1)
|
||||||
|
{
|
||||||
|
for my $y (0 .. $gameY-1)
|
||||||
|
{
|
||||||
|
$map[$x][$y] = "-";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fill with units
|
||||||
|
for my $unit (@units)
|
||||||
|
{
|
||||||
|
my ($id,$tm,$vs,$dr,$psx,$psy) = getUnit($unit);
|
||||||
|
|
||||||
|
$tm += 31;
|
||||||
|
$vs = "\e[".$tm."m".$vs."\e[0m";
|
||||||
|
|
||||||
|
$map[$psx][$psy] = $vs;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print whole map bottom left is 0,0
|
||||||
|
for my $y ( reverse 0 .. $gameY-1 )
|
||||||
|
{
|
||||||
|
for my $x (0 .. $gameX-1)
|
||||||
|
{
|
||||||
|
printf($map[$x][$y]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for a file to exist
|
||||||
|
sub WaitForFile
|
||||||
|
{
|
||||||
|
my $file = $_[0];
|
||||||
|
while( ! -e $file )
|
||||||
|
{
|
||||||
|
select(undef, undef, undef, 0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
104
randomPlayer.pl
Executable file
104
randomPlayer.pl
Executable file
|
@ -0,0 +1,104 @@
|
||||||
|
#! /usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Term::ANSIColor;
|
||||||
|
|
||||||
|
# From http://perlmaven.com/how-to-create-a-perl-module-for-code-reuse
|
||||||
|
# expect ttrts perl module in a neighboring perl/ dir
|
||||||
|
use File::Basename qw(dirname);
|
||||||
|
use Cwd qw(abs_path);
|
||||||
|
use lib dirname(abs_path($0))."/perl";
|
||||||
|
|
||||||
|
# Use our ttrts perl library
|
||||||
|
use ttrts;
|
||||||
|
|
||||||
|
our $usage_text=<<TEXT;
|
||||||
|
NAME
|
||||||
|
randomPlayer.pl
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
randomPlayer.pl TEAM [OPTIONS]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
A very random perl AI for ttrts
|
||||||
|
|
||||||
|
TEXT
|
||||||
|
|
||||||
|
# Exit with usage if not given a number
|
||||||
|
scalar(@ARGV) or printf $usage_text and exit 1;
|
||||||
|
|
||||||
|
# Grab the team
|
||||||
|
our $team = $ARGV[0];
|
||||||
|
our $turn = 0;
|
||||||
|
|
||||||
|
our $gameName;
|
||||||
|
our $gameX;
|
||||||
|
our $gameY;
|
||||||
|
|
||||||
|
# If team is non-numeric
|
||||||
|
($team =~ m/\D+/) and printf $usage_text and exit 1;
|
||||||
|
|
||||||
|
# Give random orders to all units
|
||||||
|
sub OrderEverythingRandom
|
||||||
|
{
|
||||||
|
my @myUnits = @_;
|
||||||
|
|
||||||
|
my $commands = "";
|
||||||
|
my @selection = ("F","L","R","A");
|
||||||
|
|
||||||
|
foreach my $unit (@myUnits)
|
||||||
|
{
|
||||||
|
my ($unitID) = ($unit =~ /UNIT:(\d+)/);
|
||||||
|
$commands = $commands."ORDER:".$selection[rand(4)]." id:"."$unitID";
|
||||||
|
$commands = $commands."\n";
|
||||||
|
}
|
||||||
|
return $commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show launch params
|
||||||
|
printf("Launching with team %i\n",$team);
|
||||||
|
|
||||||
|
# Stay looping the AI
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
# Wait for turn file
|
||||||
|
our $turnFile = GetTurnFile($turn);
|
||||||
|
|
||||||
|
# Wait for the turn file
|
||||||
|
printf("Waiting for %s\n", $turnFile);
|
||||||
|
WaitForFile $turnFile;
|
||||||
|
|
||||||
|
# Read in the game state from turnFile
|
||||||
|
my @units = GetUnitsForTurn($turnFile);
|
||||||
|
my ($gameName,$gameX,$gameY) = GetHeaderForTurn($turnFile);
|
||||||
|
|
||||||
|
# Get units on my team
|
||||||
|
my @myUnits = getUnitsOnTeam($team,@units);
|
||||||
|
|
||||||
|
# Generate some commands
|
||||||
|
my $commands = OrderEverythingRandom(@myUnits);
|
||||||
|
|
||||||
|
# At this point, print the game map
|
||||||
|
PrintGameMap($gameX,$gameY,@units);
|
||||||
|
|
||||||
|
if( scalar(@units) == 0 )
|
||||||
|
{
|
||||||
|
printf "Game was a draw!\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
elsif( scalar(@myUnits) == scalar(@units) )
|
||||||
|
{
|
||||||
|
printf "Game over, you win!\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
elsif( scalar(@myUnits) == 0 )
|
||||||
|
{
|
||||||
|
printf "Game over, you lose!\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputCommandsFile $turn,$team,$commands;
|
||||||
|
|
||||||
|
$turn++;
|
||||||
|
|
||||||
|
}
|
131
simplePlayer.pl
131
simplePlayer.pl
|
@ -1,131 +0,0 @@
|
||||||
#! /usr/bin/perl
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
our $usage_text=<<TEXT;
|
|
||||||
NAME
|
|
||||||
simple_player.pl
|
|
||||||
|
|
||||||
USAGE
|
|
||||||
simple_player.pl TEAM [OPTIONS]
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
A very simple perl AI for ttrts
|
|
||||||
|
|
||||||
TEXT
|
|
||||||
|
|
||||||
# Exit with usage if not given a number
|
|
||||||
scalar(@ARGV) or printf $usage_text and exit 1;
|
|
||||||
|
|
||||||
# Grab the team
|
|
||||||
our $team = $ARGV[0];
|
|
||||||
our $turn = 0;
|
|
||||||
|
|
||||||
# If team is non-numeric
|
|
||||||
($team =~ m/\D+/) and printf $usage_text and exit 1;
|
|
||||||
|
|
||||||
# Wait for a file to exist
|
|
||||||
sub WaitForFile
|
|
||||||
{
|
|
||||||
my $file = $_[0];
|
|
||||||
printf("Waiting for %s\n", $file);
|
|
||||||
while( ! -e $file )
|
|
||||||
{
|
|
||||||
sleep 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the units from a turn file
|
|
||||||
sub GetUnitsForTurn
|
|
||||||
{
|
|
||||||
my $turnFile = $_[0];
|
|
||||||
|
|
||||||
# Open the turn file
|
|
||||||
open (my $TURNHANDLE, '<', $turnFile) or die "Could not open '$turnFile' $!";
|
|
||||||
|
|
||||||
# Pull in the header information
|
|
||||||
my $headerLine = <$TURNHANDLE>;
|
|
||||||
chomp $headerLine;
|
|
||||||
my $sizeLine = <$TURNHANDLE>;
|
|
||||||
chomp $sizeLine;
|
|
||||||
my $turnLine = <$TURNHANDLE>;
|
|
||||||
chomp $turnLine;
|
|
||||||
( <$TURNHANDLE> =~ m/~~~~/ ) or die "Gamestate file did not match expected format";
|
|
||||||
|
|
||||||
my @units;
|
|
||||||
while( my $unitLine = <$TURNHANDLE> )
|
|
||||||
{
|
|
||||||
chomp $unitLine;
|
|
||||||
push(@units,$unitLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
return @units;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Output the commands file
|
|
||||||
sub OutputCommandsFile
|
|
||||||
{
|
|
||||||
my $commands = $_[0];
|
|
||||||
|
|
||||||
# Get output file
|
|
||||||
our $orderFile = "Turn_TURN_Team_TEAM.txt";
|
|
||||||
$orderFile =~ s/TURN/$turn/;
|
|
||||||
$orderFile =~ s/TEAM/$team/;
|
|
||||||
|
|
||||||
system ("echo $commands > $orderFile");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sort units into teams
|
|
||||||
sub getUnitsOnTeam
|
|
||||||
{
|
|
||||||
my $theTeam = shift;
|
|
||||||
my @allUnits = @_;;
|
|
||||||
my @myUnits;
|
|
||||||
|
|
||||||
for my $unit (@allUnits)
|
|
||||||
{
|
|
||||||
my ($unitTeam) = $unit =~ /tm:(\d+)/;
|
|
||||||
if ( $unitTeam == $theTeam )
|
|
||||||
{
|
|
||||||
push(@myUnits,$unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return @myUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get commands for a turn
|
|
||||||
sub GetCommandsForTurn
|
|
||||||
{
|
|
||||||
my @units = @_;
|
|
||||||
my @myUnits = getUnitsOnTeam($team,@units);
|
|
||||||
|
|
||||||
# perform AI here
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show launch params
|
|
||||||
printf("Launching with team %i\n",$team);
|
|
||||||
|
|
||||||
# Stay looping the AI
|
|
||||||
while ( 1 )
|
|
||||||
{
|
|
||||||
# Wait for turn file
|
|
||||||
our $turnFile = "Turn_TURN.txt";
|
|
||||||
$turnFile =~ s/TURN/$turn/;
|
|
||||||
|
|
||||||
# Wait for the turn file
|
|
||||||
WaitForFile $turnFile;
|
|
||||||
|
|
||||||
# Read in the game state from turnFile
|
|
||||||
my @units = GetUnitsForTurn($turnFile);
|
|
||||||
|
|
||||||
# Generate some commands
|
|
||||||
my $commands = GetCommandsForTurn @units;
|
|
||||||
|
|
||||||
OutputCommandsFile $commands;
|
|
||||||
|
|
||||||
$turn++;
|
|
||||||
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue