chiark / gitweb /
Merge branch 'stable-3.x'
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Wed, 9 Sep 2009 20:46:04 +0000 (21:46 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Wed, 9 Sep 2009 20:46:04 +0000 (21:46 +0100)
yarrg/Commods.pm
yarrg/TODO
yarrg/db-idempotent-populate
yarrg/ocean-topology-graph
yarrg/source-info.txt
yarrg/update-master-info
yarrg/web/routetrade

index 860510e33835e5e1e574ab429862f0563ecf7c2a..44cc74e8543b91b885ee76082cb3ea0042d5f3fd 100644 (file)
@@ -35,7 +35,8 @@ BEGIN {
     @ISA         = qw(Exporter);
     @EXPORT      = qw(&parse_info_clientside &fetch_with_rsync
                      &parse_info_serverside &parse_info_serverside_ocean
-                     %oceans %commods %clients %routes %route_mysteries
+                     %oceans %commods %clients
+                     %vessels %shotname2damage
                      &parse_pctb_commodmap %pctb_commodmap @pctb_commodmap
                      &get_our_version &check_tsv_line
                      &pipethrough_prep &pipethrough_run
@@ -52,8 +53,10 @@ our $masterinfoversion= 2; # version we understand
 
 our %oceans; # eg $oceans{'Midnight'}{'Ruby'}{'Eta Island'}= $sources;
 our %clients; # eg $clients{'ypp-sc-tools'}= [ qw(last-page) ];
-our %routes; # eg $routes{'Midnight'}{'Orca'}{'Tinga'}= $sources  NB abbrevs!
-our %route_mysteries; # eg $route_mysteries{'Midnight'}{'Norse'}= 3
+our %vessels; # eg $vessels{'War Brig'}{Shot}='medium'
+              #    $vessels{'War Brig'}{Volume}= 81000
+              #    $vessels{'War Brig'}{Mass}= 54000
+our %shotname2damage; # eg $shotname2damage{'medium'}= 3;
 # $sources = 's[l]b';
 #       's' = Special Circumstances; 'l' = local ; B = with Bleach
 
@@ -98,11 +101,24 @@ sub parse_info1 ($$) {
                    $oceans{$ocean}{$arch}{$_} .= $src;
                };
            });
-       } elsif (m/^routes (\w+)$/) {
-           my $ocean= $1;
+       } elsif (m/^vessels$/) {
+           @ctx= (sub {
+               return if m/^[-+|]+$/;
+               m/^ \| \s* ([A-Z][a-z\ ]+[a-z]) \s*
+                   \| \s* (small|medium|large) \s*
+                   \| \s* ([1-9][0-9,]+) \s*
+                   \| \s* ([1-9][0-9,]+) \s*
+                   \| $/x
+                   or die;
+               my $name= $1;
+               my $v= { Shot => $2, Volume => $3, Mass => $4 };
+               foreach my $vm (qw(Volume Mass)) { $v->{$vm} =~ s/,//g; }
+               $vessels{$name}= $v;
+           });
+       } elsif (m/^shot$/) {
            @ctx= (sub {
-               m/^(\S[^\t]*\S),\s*(\S[^\t]*\S),\s*([1-9][0-9]{0,2})$/ or die;
-               $routes{$ocean}{$1}{$2}= $3;
+               m/^ ([a-z]+) \s+ (\d+) $/x or die;
+               $shotname2damage{$1}= $2;
            });
        } elsif (m/^client (\S+.*\S)$/) {
            my $client= $1;
@@ -157,22 +173,6 @@ sub parse_info1 ($$) {
        }
     };
     foreach (@rawcm) { &$ca($_,$src); }
-
-    foreach my $on (keys %routes) {
-       my $routes= $routes{$on};
-       my $ocean= $oceans{$on};
-       die unless defined $ocean;
-       
-       my @allislands;
-       foreach my $an (sort keys %$ocean) {
-           my $arch= $ocean->{$an};
-           push @allislands, sort keys %$arch;
-       }
-       parse_info_maproutes($on, \@allislands, $routes);
-       foreach my $route (values %$routes) {
-           parse_info_maproutes($on, \@allislands, $route);
-       }
-    }
 }
 
 sub parse_info_clientside () {
@@ -204,21 +204,6 @@ sub fetch_with_rsync ($) {
     return $local;
 }
 
-sub parse_info_maproutes ($$$) {
-    my ($on, $allislands, $routemap) = @_;;
-    foreach my $k (sort keys %$routemap) {
-       my @ok= grep { index($_,$k) >= 0 } @$allislands;
-       die "ambiguous $k" if @ok>1;
-       if (!@ok) {
-           $route_mysteries{$on}{$k}++;
-           delete $routemap->{$k};
-       } elsif ($ok[0] ne $k) {
-           $routemap->{$ok[0]}= $routemap->{$k};
-           delete $routemap->{$k};
-       }
-    }
-}
-
 sub parse_info_serverside () {
     parse_info1('source-info.txt','s');
 }
index 6b227ebe739dae3f4283f233c218c5fbead918c6..c2bd4cb4e29451a7e288102f46a3d4ca425fb2f8 100644 (file)
@@ -34,8 +34,6 @@ WEBSITE
 
        initial/final stocks feature
 
-       max volume/mass
-
        max capital
 
        better documentation
index 143e2ef9d518e2e733d221365c372971b3ad29e0..1d106f2b4f9ef6924cebc6f19b0677ce8352d008 100755 (executable)
@@ -102,6 +102,13 @@ db_doall(<<END)
        dist            INTEGER                 NOT NULL,
        PRIMARY KEY (aiid, biid)
  );
+ CREATE TABLE IF NOT EXISTS vessels (
+       name            TEXT                    NOT NULL,
+       mass            INTEGER                 NOT NULL,
+       volume          INTEGER                 NOT NULL,
+       shot            INTEGER                 NOT NULL,
+       PRIMARY KEY (name)
+ );
 END
     ;
 
@@ -136,8 +143,20 @@ END
     $dbh->commit;
 }
 
-#---------- island list ----------
-#---------- routes ----------
-# now done by yppedia-chart-parser
-
-__DATA__
+#---------- vessel types ----------
+{
+    my $idempotent= $dbh->prepare(<<'END')
+ INSERT OR REPLACE INTO vessels (name, shot, mass, volume)
+                         VALUES (?,?,?,?)
+END
+    ;
+    foreach my $name (sort keys %vessels) {
+       my $v= $vessels{$name};
+       my $shotdamage= $shotname2damage{$v->{Shot}};
+       die "no shot damage for shot $v->{Shot} for vessel $name"
+           unless defined $shotdamage;
+       my @qa= ($name, $shotdamage, map { $v->{$_} } qw(Mass Volume));
+       $idempotent->execute(@qa);
+    }
+    $dbh->commit;
+}
index 55d15d97e8f5b20d530360c1fde16144cbea77f9..e609e35778188dc147390cd3a451dc315c95da62 100755 (executable)
@@ -20,7 +20,9 @@ $dbh->disconnect();
 #print Dumper($results);
 
 print "strict graph $ocean {\n";
-#print "    nodesep=10;\n";
+print "    splines=true;\n";
+print "    nslimit=10;\n";
+print "    mclimit=10;\n";
 
 foreach my $row (@$islands) {
     my ($id,$str) = @$row;
@@ -29,8 +31,8 @@ foreach my $row (@$islands) {
 }
 foreach my $row (@$routes) {
     my ($ia,$ib,$dist) = @$row;
-    print "    n$ia -- n$ib [ len=2, label=$dist ];\n";
-    #len=$dist, minlen=$dist, weight=".(1.0/$dist).", len=".($dist*0.25+1).",
+    print "    n$ia -- n$ib [ w=".(1.0/($dist*$dist)).", len=".(0.5*$dist+1).", label=$dist ];\n";
+    #len=$dist, minlen=$dist, ,
     #w=".(1.0/$dist).", 
 }
 
index b7d285b620601fbe29ce39fb5416287a3cb9cc4b..88b93113ff41ee5bc8b4c55c387733be0dd58e9b 100644 (file)
@@ -1,4 +1,36 @@
 
+vessels
+#|   Ship Name    |Gun Size|Volume | Mass  |
+ |Sloop           |small   |20,250 |13,500 |
+ |----------------+--------+-------+-------|
+ |Cutter          |small   |60,750 |40,500 |
+ |----------------+--------+-------+-------|
+ |Dhow            |medium  |20,250 |13,500 |
+ |----------------+--------+-------+-------|
+ |Longship        |small   |20,250 |13,500 |
+ |----------------+--------+-------+-------|
+ |Baghlah         |medium  |27,000 |18,000 |
+ |----------------+--------+-------+-------|
+ |Merchant brig   |medium  |135,000|90,000 |
+ |----------------+--------+-------+-------|
+ |War brig        |medium  |81,000 |54,000 |
+ |----------------+--------+-------+-------|
+ |Merchant galleon|large   |405,000|270,000|
+ |----------------+--------+-------+-------|
+ |Xebec           |medium  |182,250|121,500|
+ |----------------+--------+-------+-------|
+ |War frigate     |large   |324,000|216,000|
+ |----------------+--------+-------+-------|
+ |Grand frigate   |large   |810,000|540,000|
+# From http://yppedia.puzzlepirates.com/Ship; when updating,
+# delete unused columns and check heading is the same as above.
+# If fields reordered must change parser in Commods.pm.
+
+shot
+ small 2
+ medium        3
+ large 4
+
 commods
  kraken's blood                1kg
  %c dye                        1kg
index c0bbbffe1a303928159b120e66ebef046b55f8ef..e2b0973db453b093e9b6f261b60c5f2969701e8b 100755 (executable)
@@ -95,7 +95,7 @@ sub process_some_info ($$$) {
            next if $h =~ m/^nocommods/;
        }
        next if $sfn =~ m/source-info/ && $h =~ m/^ocean\b/;
-       next if $h =~ m/^client\b/;
+       next if $h =~ m/^client|^vessels|^shot\b/;
 
        print $df $_, "\n" or die $!;
     }
index 397e3854372787170afe7e1861de55150aa6495a..0da1fd80a81929454605e46df2064d56d26d3083 100644 (file)
@@ -264,6 +264,8 @@ foreach my $v (qw(MaxMass MaxVolume)) {
 
 <%perl>
 
+my @total_massvol;
+
 if (!@flows) {
        print 'No profitable trading opportunities were found.';
        return;
@@ -442,7 +444,7 @@ foreach my $ci (0..($#islandids-1)) {
        foreach my $mv (qw(mass volume)) {
                my $max_vn= "max_$mv";
                my $max= $mv eq 'mass' ? $max_mass : $max_volume;
-               next unless defined $max;
+               $max= 1e9 unless defined $max;
 #print " DEFINED MAX $mv $max ";
                $cplex .= "
    ". sprintf("%-10s","${mv}_$ci:")." ".
@@ -483,31 +485,54 @@ if ($qa->{'debug'}) {
        print "<pre>\n" if $qa->{'debug'};
        my $found_section= 0;
        my $glpsol_out= '';
+       my $continuation='';
        while (<$output>) {
                $glpsol_out.= $_;
                print encode_entities($_) if $qa->{'debug'};
-               if (m/^\s*No\.\s+Column name\s+(?:St\s+)?Activity\s/) {
-                       die if $found_section>0;
+               if (m/^\s*No\.\s+(Row|Column) name\s+(?:St\s+)?Activity\s/) {
+                       die "$_ $found_section ?" if $found_section>0;
                        $found_section= 1;
                        next;
                }
                next unless $found_section==1;
-               next if m/^[- ]+$/;
-               if (!/\S/) {
-                       $found_section= 2;
-                       next;
+               if (!length $continuation) {
+                       next if !$continuation &&  m/^[- ]+$/;
+                       if (!/\S/) {
+                               $found_section= 0;
+                               next;
+                       }
+                       if (m/^ \s* \d+ \s+ \w+ $/x) {
+                               $continuation= $&;
+                               next;
+                       }
+               }
+               $_= $continuation.$_;
+               $continuation= '';
+               my ($varname, $qty) = m/^
+                       \s* \d+ \s+
+                       (\w+) \s+ (?: [A-Z*]+ \s+ )?
+                       ([0-9.]+) \s
+                       /x or die "$_ ?";
+               if ($varname =~ m/^f(\d+)$/) {
+                       my ($ix) = $1;
+                       my $flow= $flows[$ix] or die;
+                       $flow->{OptQty}= $qty;
+                       $flow->{OptProfit}= $flow->{'unitprofit'} * $qty;
+                       $flow->{OptCapital}= $flow->{OptQty} *
+                               $flow->{'org_price'};
+               } elsif ($varname =~ m/^(mass|volume)_(\d+)$/) {
+                       my ($mv,$ix) = ($1,$2);
+                       $total_massvol[$ix]{$mv}= $qty;
                }
-               my ($ix, $qty) =
-                       m/^\s*\d+\s+f(\d+)\s+\S+\s+(\d+)\s/ or die "$_ ?";
-               my $flow= $flows[$ix] or die;
-               $flow->{OptQty}= $qty;
-               $flow->{OptProfit}= $flow->{'unitprofit'} * $qty;
-               $flow->{OptCapital}= $flow->{OptQty} * $flow->{'org_price'};
        }
        print "</pre>\n" if $qa->{'debug'};
        my $prerr= "\n=====\n$cplex\n=====\n$glpsol_out\n=====\n ";
        pipethrough_run_finish($output,$prerr);
-       die $prerr unless $found_section;
+       map { defined $_->{OptQty} or die "$prerr $_->{Ix}" } @flows;
+#      map { defined 
+#      die $prerr if grep { ! } @flows;
+#      map { die 
+#      die $prerr if map { 
 };
 
 $addcols->({ DoReverse => 1, Special => sub {
@@ -696,17 +721,40 @@ $addcols->({ Total => 0, DoReverse => 1 }, qw(
        }
      }
 
-     my $total;
+     my ($total, $total_to_show);
      my $dline= 0;
-     my $show_flows= sub {
-       my ($od,$arbitrage,$collectdeliver) = @_;
+     my $show_total= sub {
+       my ($totaldesc, $sign) = @_;
+       if (defined $total) {
+               die if defined $total_to_show;
+               $total_total += $sign * $total;
+               $total_to_show= [ $totaldesc, $total ];
+               $total= undef;
+       }
+       $dline= 0;
+     };
+     my $show_total_now= sub {
+       my ($xinfo) = @_;
+       return unless defined $total_to_show;
+       my ($totaldesc,$totalwas) = @$total_to_show;
 </%perl>
-%
+<tr>
+<td colspan=1>
+<td colspan=2><% $xinfo %>
+<td colspan=2 align=right><% $totaldesc %>
+<td align=right><% $totalwas |h %> total
+<%perl>
+       $total_to_show= undef;
+     };
+</%perl>
+%    my $show_flows= sub {
+%      my ($od,$arbitrage,$collectdeliver) = @_;
 %      my $todo= $flowlists{$od};
 %      return unless $todo;
 %      foreach my $tkey (sort keys %$todo) {
 %              my $t= $todo->{$tkey};
 %              next if $t->{"${od}Arbitrage"} != $arbitrage;
+%              $show_total_now->('');
 %              if (!$age_reported++) {
 %                      my $age= $now - $t->{Timestamp};
 %                      my $cellid= "da_${i}";
@@ -743,25 +791,29 @@ $addcols->({ Total => 0, DoReverse => 1 }, qw(
 %              $dline ^= 1;
 %      }
 %    };
-%    my $show_total= sub {
-%      my ($totaldesc, $sign)= @_;
-%      if (defined $total) {
-<tr>
-<td colspan=3>
-<td colspan=2 align=right><% $totaldesc %>
-<td align=right><% $total |h %> total
-%              $total_total += $sign * $total;
-%      }
-%      $total= undef;
-%      $dline= 0;
 <%perl>
-     };
 
      $show_flows->('dst',0,'Deliver'); $show_total->('Proceeds',1);
      $show_flows->('org',1,'Collect'); $show_total->('(Arbitrage) outlay',-1);
      $show_flows->('dst',1,'Deliver'); $show_total->('(Arbitrage) proceeds',1);
      $show_flows->('org',0,'Collect'); $show_total->('Outlay',-1);
-
+     my $totals= '';
+     if ($i < $#islandids) {
+       $totals .=      "In hold $total_massvol[$i]{mass} kg,".
+                       " $total_massvol[$i]{volume} l";
+       my $delim= '; spare ';
+       my $domv= sub {
+               my ($max, $got, $units) = @_;
+               return unless defined $max;
+               $totals .= $delim;
+               $totals .= sprintf "%g %s", ($max-$got), $units;
+               $delim= ', ';
+       };
+       $domv->($max_mass,   $total_massvol[$i]{mass},   'kg');
+       $domv->($max_volume, $total_massvol[$i]{volume}, 'l');
+       $totals .= ".\n";
+     }
+     $show_total_now->($totals);
 }
 </%perl>
 <tbody><tr>