diff --git a/perl/ttrts.pm b/perl/ttrts.pm new file mode 100644 index 0000000..7e9fdbf --- /dev/null +++ b/perl/ttrts.pm @@ -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; \ No newline at end of file diff --git a/randomPlayer.pl b/randomPlayer.pl new file mode 100755 index 0000000..14d6338 --- /dev/null +++ b/randomPlayer.pl @@ -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++; + +} \ No newline at end of file diff --git a/simplePlayer.pl b/simplePlayer.pl deleted file mode 100755 index 093fff9..0000000 --- a/simplePlayer.pl +++ /dev/null @@ -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++; - -} \ No newline at end of file