Games-AIBots
view release on metacpan or search on metacpan
lib/Games/AIBots.pm view on Meta::CPAN
|| /^(attempt)[\s\t]+(repair|destruct)$/
|| /^(beam)[\s\t]+(command|fuel|ammo)\s+(.+)$/
|| /^(toggle)[\s\t]+(shield|laymine|cloak)$/
) {
$bot->{'lastcmd'} = join(' ', ucfirst($1), substr($_, $-[2]));
&{"cmd_$1"}($bot, $2, $3, $4) or @{$bot->{'queue'}} = grep {$_ eq $bot->{'lastcmd'}} @{$bot->{'queue'}};;
bot_watch($bot) unless $Continue;;
}
elsif ($_) {
warn "Malformed command $_ from ".$bot->{'id'}.", state ".$bot->{'state'};
}
$bot->{'dead'} = 1 if $bot->{'life'} <= 0;
unless ($bot->{'dead'}) {
tick_cloak($bot);
obj_move(@{$old}{'x', 'y'}, @{$bot}{'x', 'y'}, bot_char($bot), "_bot$bot->{'id'}", 0, ($bot->{'id'} eq $Watch->{'id'}));
obj_move(@{$old}{'x', 'y'}, @{$bot}{'x', 'y'}, $bot->{'shield'} ? 'shield' : 'noshield', "_bots$bot->{'id'}", 1);
}
$Top->after($Tick_delay / (scalar @Bots), \&Games::AIBots::tick_bot) if $GUI and $Running;
}
sub tick_missile {
my $missile = shift;
return if $missile->{'dead'};
my $bot = $missile->{'bot'};
my ($dx, $dy) = delta($missile->{'h'}, 'front');
my $tag = "_missile$bot->{'id'}:$missile->{'id'}";
if (bot_at(@{$missile}{'x', 'y'}) and $missile->{'age'}
or obj_at($missile->{'x'} += $dx, $missile->{'y'} += $dy) ne '.'
or ++$missile->{'age'} >= $missile->{'range'})
{
detonate($bot, $missile->{'type'}, @{$missile}{'x', 'y'});
$missile->{'dead'}++;
$Canvas->delete($tag) if $GUI;
}
elsif ($missile->{'age'} > 1) {
obj_move($missile->{'x'} - $dx, $missile->{'y'} - $dy,
@{$missile}{'x', 'y'}, $missile->{'type'}.$missile->{'h'}, $tag, 1);
}
else {
obj_draw(@{$missile}{'x', 'y'}, $missile->{'type'}.$missile->{'h'}, $tag, 1);
}
}
sub tick_cloak {
my $bot = shift;
return unless $bot->{'cloak'};
if ($bot->{'fuel'} >= $Cloak_fuel and bot_pay($bot, ammo => $Cloak_ammo)) {
$bot->{'fuel'} -= $Cloak_fuel;
}
else {
$bot->{'cloak'} = 0;
}
}
sub tick_check {
my (%alive, $hasfuel, $missiles);
return if !$Running;
foreach my $bot (@Bots) {
$alive{$bot->{'team'} || bot_id($bot)}++ unless $bot->{'dead'};
$hasfuel++ unless $bot->{'dead'} or $bot->{'fuel'} <= 0;
foreach my $missile (@{$bot->{'missiles'}}) {
$missiles++ unless $missile->{'dead'};
}
}
if (!$missiles and (scalar keys(%alive) <= 1) or !$hasfuel) {
# Game Over
display('end');
my %TScore;
foreach my $bot (@Bots) {
$bot->{'score'} += 50 * $bot->{'life'};
$bot->{'score'} -= $bot->{'burn'};
$bot->{'score'} += 500 / $alive{$bot->{'team'} || bot_id($bot)}
unless $bot->{'dead'} or (scalar keys(%alive) > 1);
$TScore{$bot->{'team'} || bot_id($bot)} += $bot->{'score'} || 0;
$bot->{'lastcmd'} = '**End**';
}
my @BScore = sort {$b->{'score'} <=> $a->{'score'}} @Bots;
my @TScore = sort {$TScore{$b} <=> $TScore{$a}} keys(%TScore);
if ($GUI) {
$Btn_stop->configure(-state => 'disabled');
$Btn_play->configure(-image => 'play');
$_->configure(-state => 'normal', -background => '#a04444') foreach @Mnu_arg;
$Top->configure('-title' => "AI Bots v$Games::AIBots::VERSION [Winner:".bot_id($BScore[0])." | Team ".$TScore[0]."] (Tick: $Tick)");
$Watch->{'id'} = $BScore[0]->{'id'};
bot_watch($BScore[0]);
}
foreach my $bot (@BScore) {
$Watch->{'id'} = $bot->{'id'};
bot_watch($bot, 1);
print "\n" unless $Console and $^O ne 'MSWin32';
}
$Running = undef;
ding('game_over');
display('winner', bot_id($BScore[0]), $TScore[0]);
}
return $Running;
}
# ===========================================================================
# Bot Commands
# ===========================================================================
sub cmd_attempt {
my ($bot, $action) = @_;
if ($action eq 'repair') {
return if $bot->{'shield'} or $bot->{'life'} >= $Max_life;
if (!int(rand(10))) {
$bot->{'life'}++;
obj_flash('repair', @{$bot}{'x', 'y'});
}
elsif (!int(rand(20))) {
$bot->{'burn'}++;
obj_flash('explode', @{$bot}{'x', 'y'});
}
}
elsif ($action eq 'destruct') {
my $dmg = $bot->{'life'} * 100 / $Max_life;
@{$Weapon{'destructh'}}[$DmgS, $DmgN, $BurnS, $BurnN]
= ($dmg, $dmg, $dmg / 10, $dmg / 10);
@{$Weapon{'destructs'}}[$DmgS, $DmgN, $BurnS, $BurnN, $ScrS, $ScrN]
= ($dmg, $dmg, $dmg / 10, $dmg / 10, $dmg * 5, $dmg * 5);
detonate($bot, 'destruct', @{$bot}{'x', 'y'});
}
return 1;
}
( run in 2.771 seconds using v1.01-cache-2.11-cpan-99c4e6809bf )