view planner.pl @ 372:9f19fe8d189c

withdraw the ship 10 minutes first, we have only need 2 ships for blocking a town.
author "Rex Tsai <chihchun@kalug.linux.org.tw>"
date Tue, 14 Apr 2009 17:00:05 +0800
parents 95148fdc1021
children 0ec57ac68a4c
line wrap: on
line source

#!/usr/bin/perl
use Ikariam;
use Data::Dumper;
use Decision::ParseTree q{ParseTree};
use YAML qw/LoadFile Dump DumpFile/;
use Getopt::Std;
use POSIX qw(strftime);

Ikariam::Cities->has_a(island => 'Ikariam::Island');

my $army = {
    "Slinger" => 301,
    "Swordsman" => 302,
    "Phalanx" => 303,
    "Ram" => 307,
    "Archer" => 313,
    "Catapult" => 306,
    "Gunsman" => 304,
    "Mortar" => 305,
    "SteamGiant" => 308,
    "Gyrocopter" => 312,
    "Bombardier" => 309,
    "Doctor" => 311,
    "Cook" => 310,
};

my $fleet = {
    "CargoShip" => 201,
    "Ram-Ship" => 210,
    "BallistaShip" => 213,
    "Flamethrower" => 211,
    "CatapultShip" => 214,
    "MortarShip" => 215,
    "PaddleWheelRam" => 216,
    "DivingBoat" => 212,
};


sub calcTime {
    my ($gooff, $travelTime) = @_;
    return (sprintf("%s-%s", strftime("%H:%M", localtime(time+$gooff*60)), strftime("%H:%M", localtime(time+($gooff+$travelTime)*60))));
}

# return minutes.
sub travelTime {
    my ($x1, $y1, $x2, $y2, $speed) = @_;
    $speed = 60 unless(defined($speed));
    if($x1 == $x2 && $y1 == $y2) {
        return 600/$speed;
    } else {
        return int( (sqrt((abs($x1 - $x2) * abs($x1 - $x2)) + (abs($y1 - $y2) * abs($y1 - $y2)))) * (1200/$speed));
    }
}


package main;

if($#ARGV < 2) {
    die("Usage: %s -n 1 -a 1 -v 21 targetCity navyCity armyCity wingman1.. wingman2..\n");
}
getopts('wa:n:v:');
$opt_n = defined($opt_n) ? $opt_n : 1;
$opt_a = defined($opt_a) ? $opt_a : 1;
my $vanguard =  defined($opt_v) ? $opt_v : 21;

my $targetCityId = shift(@ARGV);
my $targetCity = Ikariam::Cities->retrieve($targetCityId);
my @cities;
# NAVY
foreach my $i (1..$opt_n) {
    my $navyCity = shift(@ARGV);
    my $city = LoadFile(sprintf("city-%s-dump.yaml", $navyCity));
    $city->{travelTime} = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 33);
    $city->{distance}   = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 33) + $vanguard;
    if($i == 1) {
        $city->{distance} += 8;
     } else {
        $city->{distance} += 5;
     }
    $city->{type} = "navy";
    $city->{queue} = "navy" . $i;
    push (@cities, $city);
}

# ARMY
foreach my $i (1..$opt_a) {
    my $armyCity = shift(@ARGV);
    my $city = LoadFile(sprintf("city-%s-dump.yaml", $armyCity));
    $city->{travelTime} = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 60);
    $city->{distance}   = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 60) + $vanguard;
    if($i == 1) {
        $city->{distance} += 5;
    } else {
        $city->{distance} += 1;
    }
    $city->{type} = "army";
    $city->{queue} = "army" . $i;
    push (@cities, $city);
}

# wingman, army
while(defined($cityId = shift(@ARGV))) {
    my $city = LoadFile(sprintf("city-%s-dump.yaml", $cityId));
    $city->{type} = "wingman";
    $city->{queue} = "wingman";
    $city->{travelTime} = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 60);
    $city->{distance} = travelTime($targetCity->island->x, $targetCity->island->y, $city->{island}->{x}, $city->{island}->{y}, 60);
    if(defined($opt_w)) {
            $city->{distance} -= ($i * 20 + 20);
    }
    push (@cities, $city);
}

# print the code.
print <<EOF;
#!/usr/bin/perl
use strict;
use Ikariam;
use Data::Dumper;
use POSIX qw(strftime);

sub calcTime {
    my (\$gooff, \$travelTime) = \@_;
    return (sprintf("%s-%s", strftime("%H:%M", localtime(time+\$gooff*60)), strftime("%H:%M", localtime(time+(\$gooff+\$travelTime)*60))));
}

package main;
my \$ikariam = new Ikariam(\$::server, \$::user, \$::pass);
EOF

printf ("# %s %s [%s:%s]\n", $targetCity->owner, $targetCity->cityname, $targetCity->island->x, $targetCity->island->y);
printf ("# http://%s/index.php?view=island&id=%d&selectCity=%d\n", $::server, $targetCity->island->id, $targetCity->id);
printf("#\n");
printf("my \$delay = 0; # minutes\n");

@cities = sort { $b->{distance} <=> $a->{distance}; } (@cities);
foreach my $i (0..$#cities) {
    printf('printf("%%s %s %s %s %sm\n", calcTime(%s - %s + $delay, %s));',
        $cities[$i]->{queue}, $cities[$i]->{name}, $cities[$i]->{id}, $cities[$i]->{travelTime},
        $cities[0]->{distance}, $cities[$i]->{distance}, $cities[$i]->{travelTime});
    printf(" # %s\n", calcTime($cities[0]->{distance} - $cities[$i]->{distance}, $cities[$i]->{travelTime}));
}
printf("printf('Press Enter to start...');\n");
printf("<STDIN>;\n");

foreach my $i (0..$#cities) {
    if($i ne 0) {
        # TODO, 計算港口速度
        # 減掉 cities[$i+1]->buliding->port 的速度
        printf("sleep(%d*60);\n",
                ($cities[$i-1]->{distance} - $cities[$i]->{distance}));
    }

    printf("\n# %s %s %dm\n", $cities[$i]->{name}, $cities[$i]->{queue}, $cities[$i]->{travelTime});
    printf("# ActionPoint %d/%d\n", $cities[$i]->{actionPoints}, $cities[$i]->{maxActionPoints});

    printf('$ikariam->login;' . "\n");
    if($cities[$i]->{type} eq "navy") {
        printf('$ikariam->changeCity(%d);' . "\n", $cities[$i]->{id});
        printf('$ikariam->blockadeCity(%d, {' . "\n", $targetCity->id);
        printf("\tblockadeDuration => 8*60*60," . "\n");
        while (my ($k, $v) = each(%{$cities[$i]->{fleet}})) {
            if($v > 0) {
                printf("\tcargo_fleet_%s => %s, # %s (%d)\n", $fleet->{$k}, 0, $k, $v);
            }
        }
        printf('});' . "\n", $cities[$i]->{id});
    } else {
        printf('$ikariam->changeCity(%d);' . "\n", $cities[$i]->{id});
        printf('$ikariam->plunderCity(%d, {' . "\n", $targetCity->id);
        while (my ($k, $v) = each(%{$cities[$i]->{army}})) {
            if($v > 0) {
                printf("\tcargo_army_%s => %s, # %s (%d)\n", $army->{$k}, $v, $k, $v);
            }
        }
        printf("\ttransporter   => 0, # transporter (%s)\n", $cities[$i]->{transporters}->{avail});
        printf('});' . "\n", $cities[$i]->{id});
    }
    printf('$ikariam->logout;' . "\n");
}