mirror of
https://github.com/brmlab/brmlife.git
synced 2025-08-02 09:53:38 +02:00
Add example Perl client
This commit is contained in:
parent
a8f029c81a
commit
346b1f05a7
1 changed files with 154 additions and 0 deletions
154
client/example.pl
Executable file
154
client/example.pl
Executable file
|
@ -0,0 +1,154 @@
|
|||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Example brmlife client.
|
||||
# Partially based on the btraptor.
|
||||
#
|
||||
# To run e.g. 15 instances of this client, run this command inside screen:
|
||||
#
|
||||
# for i in `seq 1 15`; do screen ./example.pl; done
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Switch;
|
||||
use IO::Socket;
|
||||
|
||||
$/ = "\r\n";
|
||||
|
||||
sub tick($) {
|
||||
my ($socket) = @_;
|
||||
|
||||
# read message from socket and parse it
|
||||
my $line = '';
|
||||
my %state = ();
|
||||
print "\n";
|
||||
while ( chomp($line = <$socket>) ) {
|
||||
print "# $line\n";
|
||||
last if $line eq '';
|
||||
if ($line eq 'DEAD') {
|
||||
print "[ii] im dead\n";
|
||||
exit(-2);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($line eq 'BUMP') {
|
||||
print "[ii] bump\n";
|
||||
next;
|
||||
}
|
||||
|
||||
$line =~ m/^([^ ]+) (.*)$/;
|
||||
my ($type, $value) = ($1, $2);
|
||||
|
||||
if ($type eq 'energy') {
|
||||
if ($value =~ /\D/) {
|
||||
print "[ee] type energy wrong value\n";
|
||||
print $value . "\n";
|
||||
exit(-1);
|
||||
}
|
||||
$state{energy} = $value;
|
||||
|
||||
} elsif ($type eq 'visual') {
|
||||
if ($value !~ /^([^ ][^ ] )+([^ ][^ ])$/) {
|
||||
print "[ee] type visual wrong value\n";
|
||||
print $value . "\n";
|
||||
exit(-1);
|
||||
}
|
||||
$state{visual} = [ split(" ", $value) ];
|
||||
}
|
||||
}
|
||||
|
||||
%state;
|
||||
}
|
||||
|
||||
sub take_action($%) {
|
||||
my ($socket, %state) = @_;
|
||||
|
||||
# Relative x,y coordinates for each movement/attack direction.
|
||||
my @dirs = ([0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1]);
|
||||
|
||||
# Move/attack desires for each direction.
|
||||
my @move = ((0, 0, 0), (0, 0, 0), (0, 0, 0));
|
||||
my @attack = ((0, 0, 0), (0, 0, 0), (0, 0, 0));
|
||||
|
||||
# dirindex($x) returns @move, $attack index for given @dirs item.
|
||||
sub dirindex { my ($dir) = @_; $dir->[0]+1 + 3*($dir->[1]+1) }
|
||||
|
||||
# Relative x,y coordinates for each visual input, in order.
|
||||
my @vdirs = (
|
||||
@dirs,
|
||||
[0, -2], [1, -2], [2, -2], [2, -1], [2, 0], [2, 1], [2, 2], [1, 2], [0, 2], [-1, 2], [-2, 2], [-2, 1], [-2, 0], [-2, -1], [-2, -2], [-1, -2],
|
||||
);
|
||||
|
||||
# Default direction in case of nothing interesting in the vicinity.
|
||||
my $max = $dirs[1];
|
||||
|
||||
for my $i (0..$#{$state{visual}}) {
|
||||
my ($type, $agent) = split(//, $state{visual}->[$i]);
|
||||
my $dir = $vdirs[$i];
|
||||
|
||||
if (abs($dir->[0]) > 1 or abs($dir->[1]) > 1) {
|
||||
# We do not support processing visual information
|
||||
# for inputs two tiles away.
|
||||
next;
|
||||
}
|
||||
|
||||
if ($agent eq 'x') {
|
||||
# Herp
|
||||
$move[dirindex($dir)] += 2;
|
||||
}
|
||||
|
||||
if ($agent eq 'a') {
|
||||
# Corpse
|
||||
$move[dirindex($dir)] += 4;
|
||||
}
|
||||
|
||||
if ($agent eq 'A') {
|
||||
# Agent
|
||||
$move[dirindex($dir)] += 7;
|
||||
$attack[dirindex($dir)] += 1;
|
||||
}
|
||||
|
||||
if ($move[dirindex($dir)] > $move[dirindex($max)] or
|
||||
($move[dirindex($dir)] == $move[dirindex($max)]) and (int rand(2))) {
|
||||
$max = $dir;
|
||||
}
|
||||
}
|
||||
|
||||
if ($attack[dirindex($max)]) {
|
||||
print $socket "attack_dir $max->[0] $max->[1]\r\n";
|
||||
} else {
|
||||
print $socket "move_dir $max->[0] $max->[1]\r\n";
|
||||
}
|
||||
print $socket "\r\n";
|
||||
}
|
||||
|
||||
|
||||
# connect
|
||||
my ($remote_host, $remote_port, $socket);
|
||||
$remote_host = "localhost";
|
||||
$remote_port = 27753;
|
||||
|
||||
$socket = IO::Socket::INET->new(
|
||||
PeerAddr => $remote_host,
|
||||
PeerPort => $remote_port,
|
||||
Proto => "tcp",
|
||||
Type => SOCK_STREAM
|
||||
) or die "Couldn't connect to $remote_host:$remote_port : $@\n";
|
||||
print "[ii] connected\r\n";
|
||||
|
||||
# negotiate attributs
|
||||
print $socket "move 1.0\r\n";
|
||||
print $socket "attack 1.0\r\n";
|
||||
print $socket "defense 1.0\r\n";
|
||||
print $socket "\r\n";
|
||||
print "[ii] agent created\r\n";
|
||||
|
||||
my %state = ();
|
||||
while (%state = tick($socket)) {
|
||||
print $state{energy} . "\n";
|
||||
print "[", join('], [', @{$state{visual}}), "]\n";
|
||||
|
||||
take_action($socket, %state);
|
||||
}
|
||||
|
||||
shutdown($socket, 2);
|
Loading…
Add table
Add a link
Reference in a new issue