#!/usr/bin/perl
# $File: //member/autrijus/AIBots/bin/aibots $ $Author: autrijus $
# $Revision: #1 $ $Change: 1 $ $DateTime: 2002/06/11 08:35:12 $
#
# Manual at the __END__ of script
#

use strict;
use Games::AIBots;
use Getopt::Std;

$::VERSION = $Games::AIBots::VERSION;

BEGIN {
    $|++;
    use vars qw/%opt/;
    getopts(':csmoru', \%opt);
    if (!$opt{'c'} and !$opt{'o'} and !$opt{'r'}) {eval q{
        use Tk;
        use Tk::Balloon;
        use Tk::DialogBox;
        use Tk::Optionmenu;
        use Tk::Photo;
        use Tk::Optionmenu;
        use Tk::Canvas;
        use Tk::Frame;
        use Tk::After;
    }}
    $opt{'c'}++ if $@;
}

unless ((!$opt{'r'} and !$opt{'o'}) xor !$opt{'s'}) {
    print "loading sound...\n";
    Games::AIBots::init_sound($opt{'m'});
}
if ($opt{'c'}) {
    Games::AIBots::init_console();
}
elsif (!$opt{'o'} and !$opt{'r'}) {
    print "loading image...\n";
    Games::AIBots::init_gui();
}

print "starting game...\n";
$Games::AIBots::Mask = exists $opt{u};
Games::AIBots::init_arg(@ARGV);
Games::AIBots::init_map();
Games::AIBots::do_loop($opt{'r'} * 100);

1;

__END__

=head1 NAME

aibots - An improved clone of A.I.Wars in Perl

=head1 SYNOPSIS

    % aibots [-r|o|c] [-s] [-m] <map> <bot1 bot2...>
    % aibots duel Samurai Thief Sofixti Lancer
    % aibots

=head1 DESCRIPTION

This is a clone of C<A.I. Wars> (L<http://www.tacticalneuronics.com/ai.htm>)
in pure perl, with C<Tk> and console interfaces.

Please consult the above URL for the general information about this
game.

=head1 OPTIONS

	-c: Console mode
	-s: Silent (Win32 only)
	-m: Music (Win32 only)
	-o: Messages only
	-r: Results only

=head1 ENVIRONMENT

=over

=item Path_AIBots

The Path to AIBots C<pics/>, C<wavs/>, C<bots/>, C<maps/> settings.
Defaults to the install path of C<Games/AIBots>.

=back

=head1 INTERFACE

=head2 The Setting Panel

=head3 Map Menu

The drop-down menu in the bottom-left corner lists all available 
maps. The ones in square brackets (eg. [Solania]) denotes a "level" 
with pre-defined bots.

Beginners are encouraged to start with the C<Open> or C<Arena> map.

=head3 Change Background

Press this key to cycle through all available backgrounds. This has 
no effects on the actual game.

=head3 Participating Bots

The nine menus in the bottom lets you pick bots to duel with each 
other. Click on an empty menu to select; select the empty entry to 
delete a bot.

=head3 Watch

You could press the watch botton next to each bots, to have its 
statistics listed on the upper-left corner.

=head3 About

Displays author and version info.

=head2 The Control Panel

=head3 Play / Pause

After the maps and bots are selected, the Play button will be 
enabled. Press it to start the duel. All bots act upon their programs 
without human intervension.

You could press the Pause button anytime during the game; press again 
to resume.

=head3 Stop

A game usually ends when there's only one remaining team left on the 
field. Before the game ends normally, you could press the Stop button 
to end a long endgame prematurely.

=head3 Speed

Toggles beterrn slow, medium and fast. You could slow down the game 
during close encounters, and fast-forwards boring intervals.

=head3 Sound 

If the Win32::Sound module is installed, AIBots could play sounds upon each event.

=head2 The Title Panel

=head3 Watch and Status

When the game is playing, the black button in the upper-left corner 
will display the Bot currently under Watch. Press that button to 
toggle the target.

The bot being watched will be surrounded by the C<[ ]> symbol, and 
has its statistics listed on the upper panel, like this at the 
beginning of a game:

    [Mage-2] Score: 0 Ammo: 30 Life: 10 Fuel: 2499 [Turn Right]

These columns denote the bot's type (Mage), number (2), current score 
(0), ammo left (30), life points, (10), fuel (2499), and the action 
of this turn (Turn Right).

Also, the window title will display (Tick: 1), means this is the 
first step into the game.

=head1 SCORING AND RULES

=head2 Basic Concepts

In AIBots, players compete with each other not by reflexes, but 
ability to program 'Bots'.

Score accumulated with each bots determines a game's outcome. The 
primary mean to gain score is to deal damage to other team's Bots. 
Additionally, the last Bot standing will receive a 500 point bonus.

To inflict damage, Bots need weapons. All weapons except for Energy 
Zaps consume ammo points. The Life points represents the maximal 
damage a bot can take before dying. When a Bot's killed, it's turned 
into a Flag.

Turning, Moving and Launching projectile weapons consume fuel points. 
When a Bot runs out of fuel, it could not perform any of above 
actions anymore. The rate of fuel burning increases propotionally 
with damage received.

Life points and Ammo will not regenerate, but are replenished on 
Flag, Vault, and Strategy Points.

Each Tick, all Bots executes one Action Command and any number of 
other commands in turn.

=head2 Board Elements

=head3 bot [^>v<]

The heading of each Bot determines the direction of weapon, move 
forward and move backward commands.

Bots do not stack. An attempt to move onto another bot results in a 
Bump.

=head3 spawn [1..9@]

Bots appear at random Spawn tiles when the game begin.

Entry Points in digits are for the bot with the identical number.

After the game begins, spawn tiles are treated as empty tiles.

=head3 wall [#]

Walls cannot be passed or destroyed.

=head3 fence [+]

Fences cannot be passed, but could be destroyed with any weapon.

=head3 flag [P]

If a damaged Bot moves on a Flag tile, it regains all Life points and 
increases 30 Ammo and 350 Fuel.

If the Bot is undamaged, Flag deals 5 damage to it.

=head3 mine [O]

A Bot moves into a Mine tile suffers 5 damage to its Life points and 
Fuel burn rates. If the mine was layed by an enemy, the enemy 
receives 400 points of Score.

=head3 vault [A]

Vault contains 20 points of Ammo.

Any weapons inflicted on the Vault tile will cause an explosion, 
which deals 3 damage to all adjacent Bots' Life and Fuel burning 
rates.

Vaults next to each other will explode simultaneously.

=head3 snode [*]

Bots staying on the Strategy Node tile will receive 1 points of Fuel 
every 5 turns, 1 point of Ammo every 10 turns, and heals 1 point of 
Life every 15 turns.

=head2 Weapons

=head3 laser

Laser is the most basic weapon. It consumes 1 point of Ammo, and 
attacks to five tiles forward. Laser beam will stop after hitting the 
first object.

When hit, Bots with Shield Off state will receive (6 - distance) 
points of damage. Shielded bots receives (3 - distance) points of 
damage in the first two tiles only.

Burn rate damage caused by Laser equals to its Life point damage.

=head3 bazooka

Bazookas consume 10 Ammo and 300 Fuel points each. They fly with the 
speed of 1 tile per Tick, and explode upon impact.

Upon explosion, a Bazooka deals 7 (shield off) / 4 (shield on) damage 
to adjacent Bots.

Direct hit to a Bot causes 9 / 6 points of damage, depends on its 
shield state.

Burn rate damage caused by Bazookas equals to its Life point damage.

=head3 grenade

Grenades consume 5 Ammo and 200 Fuel points each. They fly with the 
speed of 1 tile per Tick, and explode upon impact.

Upon explosion, a Grenade deals 5 (shield off) / 2 (shield on) damage 
to adjacent Bots.

Direct hit to a Bot causes 7 / 4 points of damage, depends on its 
shield state.

Burn rate damage caused by Grenades is 12 / 9 upon direct impact, 4 / 
1 collateral.

=head3 energy

Energy Zap consume 1 point of Life, and deals 2 points of Life and 
Burn rate damage to all adjacent Bots.

Energy Zap is the only weapon capable of destroying Flag and Mines.

=head3 destruct

Self-destruct deals the same amont of damage as remaining life points 
to all adjacent Bots, both to Life and Burn rate points.

A self-destructed Bot will not turn into a Flag.

=head2 On/Off Toggles

=head3 shield

Shields could be Enabled or Disabled at any given time.

Bots receives less damage when shielded, but cannot fire any weapon 
except for Enegy Zaps and Self-Destruct.

=head3 laymine

When Enabled, a Bot will leave a Landmine in the original tile every 
time it moves, which consumes 5 Ammo points.

=head3 cloak

Bots with Cloak enabled will not be seen by other Bots via 
C<$enemy_[x/y/h]> and C<$friend[x/y/h]> variables.

A Bot lose 10 Fuel and 2 Ammo points each turn when cloaked.

=head2 Scoring

=head3 Damage

    Bazooka	Impact: Unshieled +500, Shielded +300.          
    		Collateral: Unshielded +400, Shielded +200.

    Grenade	Impact: Unshieled +500, Shielded +300.           
    		Collateral: Unshielded +200, Shielded +100.

    Laser	Actual damage * 20

    Destruct	Actual damage * 50

    Energy Zap	+100

    Vault	+200

    Mine	+400

=head3 Bonus

+50 for every Life points left, or -50 for every points below 0.

-1 for every point of Burn rate causes by damage.

The last Team surviving receives +500 points.

 
=head1 PROGRAMMING YOUR BOT

=head2 Variables

=head3 Metadata

$name, $author

$team

$pic

=head3 Current Status

$shield, $laymine, $cloak

$bumped, $found

$score, $burn

=head3 Resources Left

$fuel, $max_fuel

$ammo, $max_ammo

$life, $max_life

=head3 Coordinates and Heading

$x, $y, $h

$enemy_x, $enemy_y, $enemy_h

$friend_x, $friend _y, $friend_h

$snode_x, $snode_y

=head3 Internal Variables

$id, $botcount

$lastcmd

$state, $line

=head2 Actions

=head3 Scanning

scan front, scan left, scan right;

scan perimeter;

scan cross, scan corner;

scan longrange;

scan position [1..9];

scan relative [1..9];

scan gps $x, $y;
Moving

move forward, move backward;

turn left, turn right;

=head3 Attack

fire energy;

fire laser;

fire bazooka;

fire grenade, fire grenade $d;

=head3 Enable and Disable

enable/disable shield;

enable/disable laymine;

enable/disable cloak;

=head3 Miscellanous

attempt repair;

attempt destruct;

beam fuel/ammo/command;

=head2 Exported Functions

=head3 Detection

&nearst(friend|enemy)

&inperim(friend|enemy)

&headto(friend|enemy)

=head3 Checking Return Values

&found($obj1|$obj2|...)

&bumped($obj1|$obj2|...)

=head3 Current Status

&damaged()

&ready($weapon)

&onnode()

=head3 Miscellanous

&turnto(2|4|6|8)

&distance($x, $y)

&toggle()

=head2 Flow Control

=head3 Conditionals

if ($condition) {...}

unless($condition) {...}

elsif ($condition) {...}

else {...}

... if/unless ($condition)

=head3 Subroutines

LABEL: {...}

redo;

goto LABEL;

call LABEL;

return;

=head1 CUSTOMIZING

=head2 The maps/ Directory

=head3 Metadata

    =background		Background image

    =bot[1..9]		Default Bots

    =sound		Opening Sound

    =snode x, y		Strategy Node location

=head1 AUTHORS

Autrijus Tang E<lt>autrijus@autrijus.org>

=head1 COPYRIGHT

Copyright 2001 by Autrijus Tang E<lt>autrijus@autrijus.org>.

This program is free software; you can redistribute it and/or 
modify it under the same terms as Perl itself.

See L<http://www.perl.com/perl/misc/Artistic.html>

=cut
