#!/usr/bin/perl use LWP::Simple; use HTML::Tree; my $save_dir = "save"; my $bench_dir = "bench"; my $score_db = "score_db"; printf("Opening save directory: $save_dir\n"); opendir(DIR, $save_dir); @BENCH = grep { !(/^\./) && -f "$save_dir/$_" } readdir(DIR); close DIR; $bench = @BENCH; printf("Got %d entries from $save_dir\n", $bench); my $hill_url = 'http://sal.math.ualberta.ca/hill.php?key=nano'; my $mypid = 45; my $hill_card = get_score_card($hill_url); my @HC = split(/\n/, $hill_card); #find warriors we need scorecards for foreach $hc (@HC){ my ($rank, $win, $loss, $tie, $wid, $name, $pid, $author, $pt, $pg, $age) = split(/\t/, $hc); if($pid == $mypid && !($wid eq "")){ $name =~ s/-nano-eve78//; $name =~ s/-eve78//; foreach $W (@BENCH){ if($W eq $name){ print "Found match for warrior on score card $name\n"; $match = 1; push(@WARRIORS, $W); $SCURL{$W} = "http://sal.math.ualberta.ca/warrior.php?key=nano&id=$wid"; } } if($match != 1){ print("Couldn't find a match for $name in $save_dir"); next; } } } if(@WARRIORS > 0){ #process the score cards for warriors we found foreach $W (@WARRIORS){ printf("Score card for $scurl\n"); $scards{$W} = get_score_card($SCURL{$W}); } foreach $W (@WARRIORS){ print "Processing $W\n"; parse_scorecard($scards{$W}, \@HILL, \%HTAKEN, \%HGIVEN); $HILL_TAKEN{$W} = \%HTAKEN; $HILL_GIVEN{$W} = \%HGIVEN; } foreach $W (@WARRIORS){ print "Benchmarking $W\n"; bench_warrior($W, \@BENCH, \%BTAKEN, \%BGIVEN); $BENCH_TAKEN{$W} = \%BTAKEN; $BENCH_GIVEN{$W} = \%BGIVEN; } %seen = (); @HILL = grep { ! $seen{$_} ++ } @HILL; %seen = (); @WARRIORS = grep { ! $seen{$_} ++ } @WARRIORS; foreach $H (@HILL){ printf("Processing hill warrior $H\n"); $low = 999.9; #impossibly high low to start $low_w = ""; foreach $B (@BENCH){ $total = 0; foreach $W (@WARRIORS){ $a = abs($HILL_TAKEN{$W}{$H} - $BENCH_TAKEN{$W}{$B}); $b = abs($HILL_GIVEN{$W}{$H} - $BENCH_GIVEN{$W}{$B}); $total = $total + ($a * $a) + ($b * $b); #print "$H -> $B -> $W ### $HILL_TAKEN{$W}{$H} - $BENCH_TAKEN{$W}{$B} + $HILL_GIVEN{$W}{$H} - $BENCH_GIVEN{$W}{$B} ERROR: $total \n"; } $total = sqrt($total); if($total < $low){ $low = $total; $low_w = $B; } } printf("Selected %s with error %3.2f to emulate %s\n", $low_w, $low, $H); foreach $W (@WARRIORS){ printf("%10s -> %10s\t\tTaken: %3.1f\tGiven: %3.1f\n", $W, $H, $HILL_TAKEN{$W}{$H}, $HILL_GIVEN{$W}{$H}); printf("%10s -> %10s\t\tTaken: %3.1f\tGiven: %3.1f\n", $W, $H, $BENCH_TAKEN{$W}{$low_w}, $BENCH_GIVEN{$W}{$low_w}); } system("cp $save_dir/$low_w $bench_dir"); } } else { # we had nothing on the hill, might as well make a random benchmark system("./mkrandbench.pl"); } sub parse_scorecard{ my ($score_card, $WARRIORS, $PTAKEN, $PGIVEN) = @_; @C = split(/\n/, $score_card); foreach $c (@C){ chomp $c; my ($rank, $win, $loss, $tie, $wid, $name, $pid, $author, $pt, $pg, $age) = split(/\t/, $c); $name = trim($name); $name =~ s/://; $pt = trim($pt); $pg = trim($pg); printf("%s:%s:%s:%s:%3.2f:%3.2f\n", $wid, $name, $pid, $author, $pt, $pg); push(@$WARRIORS, $wid); $$WNAMES{$wid} = $name; $$PTAKEN{$wid} = $pt; $$PGIVEN{$wid} = $pg; } close C; } sub get_score_card { my $url = shift; my $skipped_header = 0; my $raw_score_card = get($url) || print "Failed to retrieve $url!\n"; $raw_score_card =~ s/ //g; my $root = HTML::TreeBuilder->new; $root->parse($raw_score_card); $root->eof(); # debugging $root->dump; my $score_card; foreach $table ($root->find_by_tag_name( 'table' )){ foreach $tr ($table->find_by_tag_name( 'tr' )){ if($tr->as_text() =~ /%L/){ $skipped_header = 1; next; } if($skipped_header != 1){ next; } foreach $td ($tr->find_by_tag_name( 'td' )){ $tab_text = $td->as_HTML(); if($tab_text =~ /href/){ #this is a player or warrior name link if($tab_text =~ /player=/){ $tab_text =~ /player=([0-9]+)/; $id = $1; } else { $tab_text =~ /id=([0-9]+)&/; $id = $1; } $name = $td->as_text(); $tab_text = "$id\t$name"; } else { $tab_text = $td->as_text(); } $score_card = "$score_card$tab_text\t"; } $score_card = "$score_card\n"; } last; } return $score_card; } #Trim leading and trailing whitespace, from orielly. sub trim { my $out = shift; $out =~ s/^\s+//; $out =~ s/\s+$//; return $out; } sub check_cache($name, $bench){ my ($name, $bench) = @_; open(FH,"$score_db/$name/$bench") || return "None"; while(){ chomp; ($taken, $given) = split(/:/); } close(FH); return [$taken, $given]; } sub write_cache($name, $bench, $taken, $given){ my ($name, $bench, $taken, $given) = @_; opendir(FH, "$score_db/$name") || mkdir "$score_db/$name"; close(FH); open(FH,">$score_db/$name/$bench"); print FH "$taken:$given\n"; close(FH); } sub bench_warrior( $name, \@BENCH, \%PTAKEN, \%PGIVEN){ my ($name, $BENCH, $PTAKEN, $PGIVEN) = @_; for(my $j = 0; $j < @$BENCH; $j++){ my $first = 0; my $cache = &check_cache($name, $BENCH[$j]); if($cache eq "None"){ $cache = &check_cache($BENCH[$j], $name); if(!($cache eq "None")){ ($bwin, $owin) = @{$cache}; $cache = [$owin, $bwin]; } } if($cache eq "None"){ open(PMARS,"./pmars -s 80 -c 800 -p 80 -d 5 -l 5 -P -b -k $save_dir/$name $save_dir/$$BENCH[$j]|"); while () { #Get scores chomp; my($Wins, $Ties) = split; if($first == 0){ $owin = $Wins; $otie = $Ties; $owin = ($owin * 3) + $otie; $first++; } else { $bwin = $Wins; $btie = $Ties; $bwin = ($bwin * 3) + $btie; last; } } &write_cache($name, $BENCH[$j], $owin, $bwin); } else { ($owin, $bwin) = @{$cache}; } $$PTAKEN{$$BENCH[$j]} = (($bwin) * 300) / 426; $$PGIVEN{$$BENCH[$j]} = (($owin) * 300) / 426; #print "$$BENCH[$j] $$PTAKEN{$$BENCH[$j]} $$PGIVEN{$$BENCH[$j]}\n"; close(PMARS); } }