;
s/\\\s*\n//; # remove \ and newline
}
if ($state == 1)
{
#
# This is the initial state
# Globals are set here at the top of the file
#
# we also check for scorecard entry here,
# but only after we have read all globals.
#
if (/^PAGE/ && $vars{Submit} eq "Scorecard")
{
if ($mpscoring)
{&scorecard($firstboard,$lastboard);}
else
{&imp_scorecard($firstboard,$lastboard);}
exit(0);
}
elsif (/^PAGE/ && $vars{Submit} eq "Hand Records")
{
&handrecords;
exit(0);
}
elsif (/^PAGE\s*$page/)
{ $state = 2; }
elsif (/^PAGE/)
{$state = 12;}
elsif (/^DATE/)
{
s/^DATE\s*//;
s/\s*$//;
$date = $_;
}
elsif (/^NAME/)
{
s/^NAME\s*//;
s/\s*$//;
$myname = $_;
}
elsif (/^HOMEPAGE/)
{
s/^HOMEPAGE\s*//;
s/\s*$//;
$homepage = $_;
}
elsif (/^EMAIL/)
{
s/^EMAIL\s*//;
s/\s*$//;
$email = $_;
}
elsif (/^BOARDS/)
{
s/^BOARDS\s*//;
s/\s*$//;
if (/\s+/)
{
# two arguments
split;
$firstboard = $_[0];
$lastboard = $_[1];
}
else
{
# one argument
$firstboard = 1;
$lastboard = $_[0];
}
}
# in state 1 (preamble) the BOARD command saves
# a board. In state 2, it retrieves it. Hand
# records will use them, too.
elsif (/^BOARD/)
{
$state = 11;
s/^BOARD\s*//; s/\s*$//;
$board = $_; # remember board number/title
$savedboards{$board} = "";
$handtokens = 0;
}
elsif (/^PERL/)
{
$state = 6;
$perlcode = "";
}
elsif (/^IMPPAIRS/)
{
$mpscoring = 0;
$imppairs = 1;
}
elsif (/^IMP/)
{
$mpscoring = 0;
$imppairs = 0;
}
elsif (/^DEBUG/)
{
$state = 9;
}
elsif (/^DEFINE/)
{
# this sets up a simple macro...no arguments yet
chop;
s/^DEFINE\s*//; s/\s*$//;
($name,$replacement) = &split_args($_);
$macros{$name} = $replacement;
}
elsif (/^OPPONENTS/)
{
chop;
s/^OPPONENTS\s*//; s/\s*$//;
@opp = &split_args($_);
}
elsif (/^TOP/)
{
chop;
s/^TOP\s*//; s/\s*$//;
$top = $_;
if ($top <= 0) {$top = 12;}
}
elsif (/^BODY/)
{
chop;
s/^BODY\s*//; s/\s*$//;
$body = $_;
}
elsif (/^LAYOUT/)
{
chop;
s/^LAYOUT\s*//; s/\s*$//;
$layout = $_;
}
elsif (/^RESULTS/)
{
s/^RESULTS\s*//; s/\s*$//;
$resultstring = $_;
$state = 13;
}
elsif (/^VP20/)
{
s/^VP20\s*//; s/\s*$//;
$vp20 = $_; # number of boards in match
}
elsif (/^CARRYOVER/)
{
s/^CARRYOVER\s*//; s/\s*$//;
$carryover = $_;
}
elsif (/^LEADER/)
{
chop;
s/\\ /SPACEXXX/g;
split;
for ($i=0;$i<@_;$i++) {$_[$i] =~ s/SPACEXXX/ /g;}
# looks like LEADER 1 Begley 112.4
$opponent{$_[1]} = $_[2];
$teamscore{$_[1]} = $_[3];
}
else
{ next; }
}
# State 2
elsif ($state == 2)
{
# PAGE directive
if (/^PAGE/)
{
&print_page;
&done;
}
# TITLE directive
elsif (/^TITLE(\*?)/)
{
$star = $1;
$title = $_;
$title =~ s/TITLE\*?\s*//;
$title =~ s/\s*$//;
if (!$star) { $text .= "$title
\n"; }
}
# HANDRECORDS directive
elsif (/^HANDRECORDS/)
{
$handrecords = 1;
}
# TEXTVERSION directive
elsif (/^TEXTVERSION/)
{
$textbutton = 1;
}
# NEXT directive
elsif (/^NEXT(\*?)/)
{
$star = $1;
s/\*//;
# check for optional argument
if (/^NEXT\{(.*)\}/)
{
$nextstring = $1;
s/NEXT\{.*\}\s*(.*)\s*/$1/;
}
else
{ s/NEXT\s*(.*)\s*/$1/; }
if ($star)
{ $text .= &end_of_hand_no_sb($_); }
else
{ $text .= &end_of_hand($_); }
}
# SCORE directive
elsif (/^SCORE/)
{
# score looks like
# SCORE board contract declarer result score matchpoints/IMPs
chop;
($junk,$board,$contract,$declarer,$result,$score,$matchpoints) =
&split_args($_);
# if user-results exist, IMP against them.
if ($useresults)
{
$tempresult = $results[$board-$firstboard];
$matchpoints = &imps($score,$tempresult);
}
# print/save results
$text .= "CARD($contract) $result $score\n";
$scores .= "$board:$contract.$declarer.$score.$matchpoints;";
}
# CHOICE directive
elsif (/^CHOICE/)
{
chop;
# check for optional argument
if (/^CHOICE\{(.*)\}/)
{
$choicestring = $1;
s/CHOICE\{.*\}\s*(.*)\s*$/$1/;
}
else
{s/^CHOICE\s*//; s/\s*$//;}
@args = &split_args($_);
$text .= &html_radio(@args);
}
# CASE directive
elsif (/^CASE/)
{
# is the answer right?
s/CASE\s*//;
s/\s*$//;
if ($_ ne $answer)
{
$state = 4;
}
}
# ENDCASE directive
elsif (/^ENDCASE/)
{
# not a problem
}
# HAND directive
elsif (/^HAND/ && !/^HAND\(/) # HAND( is BML, not movie directive
{
# check for optional arguments
if (/^HAND\*/)
{$fullhand = 1;} else {$fullhand = 0;}
if (/^HAND\*?{(.*)}/)
{
$arglist = $1;
$arglist =~ tr/a-z/A-Z/;
@whichhands = split(/[\s,]+/,$arglist);
}
else
{ @whichhands = ("N","W","E","S"); }
$hand = "";
$handtokens = 0;
$state = 3;
}
# BIDDING/BID4 directive
elsif ((/^BIDDING/ || /^BID4/) && !/BIDDING\(/ && !/BID4\(/ )
{
$state = 7;
$bidding = "";
}
# BID2 directive
elsif (/^BID2/)
{
$state = 8;
$bidding = "";
}
# PERL directive
elsif (/^PERL/)
{
$state = 5;
$perlcode = "";
}
# ENDPERL directive
elsif (/^ENDPERL/)
{
# do nothing
}
# SAVE directive
elsif (/^SAVE/)
{
chop;
s/^SAVE\s*//;
s/\s*$//;
$scores .= "$_;";
}
# USE directive
elsif (/^USE/)
{
# nab string
chop;
s/^USE\s*//;
s/\s*$//;
# check it?
if ($scores =~ /$_/)
# it gets used up (all copies)
{$scores =~ s/$_;//g;}
else
{$state = 10;}
}
# ENDUSE directive
elsif (/^ENDUSE/)
{
# do nothing
}
# ELSE directive
elsif (/^ELSE/)
{
$state = 10;
}
# BOARD directive
elsif (/^BOARD/)
{
chop;
# is variant?
if (/^BOARD\*/)
{$variant = 1; s/\*//;}
else
{$variant = 0;}
# save optional args
if (/^BOARD{/)
{
$arglist = $_;
$arglist =~ s/.*{(.*)}.*/$1/;
$arglist =~ tr/a-z/A-Z/;
s/{.*}//;
}
else
{$arglist = "N,W,E,S";}
@arglist = split(/,/,$arglist);
# find hand title
s/^BOARD\s*//; s/\s*$//;
# $savedboards{$_} is sixteen tokens.
# build HAND macro
@_ = split(/\s+/,$savedboards{$_});
$h[0] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[1] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[2] = "VHAND($_[5],$_[7],$_[9],$_[11])";
$h[3] = "VHAND($_[12],$_[13],$_[14],$_[15])";
if (!$variant)
{
$text .= "HAND(";
if ($arglist =~ /N/)
{$text .= $h[0].",\n";}
else
{$text .= ",";}
if ($arglist =~ /W/)
{$text .= $h[1].",\n";}
else
{$text .= ",";}
if ($arglist =~ /E/)
{$text .= $h[2].",\n";}
else
{$text .= ",";}
if ($arglist =~ /S/)
{$text .= $h[3].")\n";}
else
{$text .= ")\n";}
}
else
{
$text .= "HAND(";
# argument 0-3
if ($arglist[0])
{ $text .= $h[$location{$arglist[0]}]; }
$text .= ",";
if ($arglist[1])
{ $text .= $h[$location{$arglist[1]}]; }
$text .= ",";
if ($arglist[2])
{ $text .= $h[$location{$arglist[2]}]; }
$text .= ",";
if ($arglist[3])
{ $text .= $h[$location{$arglist[3]}]; }
$text .= ")\n";
}
}
# MAP directive
elsif (/^MAP/)
{
# syntax: MAP image page tag x y x y tag x y x y ...
chop;
s/^MAP\s*//; s/\s*$//;
@args = &split_args($_);
$text .= &html_imagemap(@args);
}
# LEADERBOARD
elsif (/^LEADERBOARD/)
{
$text .= &printleaders;
}
# comments
elsif (/^#/)
{
# do nothing
}
else
{
# substitutions:
# (1) blank line --->
if (/^\s*$/)
{
$text .= "
\n";
}
else
{
$text .= $_;
}
}
}
# accepting hand
elsif ($state == 3)
{
# other directives are errors
if (/^PAGE/ ||
/^CASE/ ||
/^ENDCASE/ ||
/^SCORE/ ||
/^TITLE/ ||
/^PERL/ ||
/^ENDPERL/ ||
/^NEXT/ ||
/^CHOICE/ ||
/^BOARDS/ ||
/^NAME/ ||
/^DATE/ ||
/^EMAIL/ ||
/^HAND/ ||
/^HOMEPAGE/) {&error("Incomplete HAND\n");}
# we shall read a total of 16 tokens
chop;
s/^\s*//;
s/\s*$//;
$hand .= $_." ";
split;
$handtokens += @_;
if ($fullhand)
{$ntokens = 16;}
else
{$ntokens = 4 * @whichhands;}
if ($handtokens >= $ntokens)
{
split(/\s+/,$hand);
# if one hand, it's simple
# if two hands, then the suits are all
# in sequence for a hand unless the
# two hands are E/W, then they are interleaved
# if three hands, E/W are interleaved if both there
# if four hands, E/W always interleaved
# I don't see an intelligent way to compress
# this code, so it's getting cased out.
$h[0] = ""; $h[1] = ""; $h[2] = ""; $h[3] = "";
if ($fullhand) # HAND* directive
{
$_ = join("",@whichhands);
if (/N/) {$h[0] = "VHAND($_[0],$_[1],$_[2],$_[3])";}
if (/W/) {$h[1] = "VHAND($_[4],$_[6],$_[8],$_[10])";}
if (/E/) {$h[2] = "VHAND($_[5],$_[7],$_[9],$_[11])";}
if (/S/) {$h[3] = "VHAND($_[12],$_[13],$_[14],$_[15])";}
}
elsif (@whichhands == 4)
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[$location{$whichhands[1]}] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[$location{$whichhands[2]}] = "VHAND($_[5],$_[7],$_[9],$_[11])";
$h[$location{$whichhands[3]}] = "VHAND($_[12],$_[13],$_[14],$_[15])";
}
elsif (@whichhands == 3)
{
$_ = join("",@whichhands);
if (/N/ && /S/) # only one E/W, so no interleaving
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[$location{$whichhands[1]}] = "VHAND($_[4],$_[5],$_[6],$_[7])";
$h[$location{$whichhands[2]}] = "VHAND($_[8],$_[9],$_[10],$_[11])";
}
else
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[$location{$whichhands[1]}] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[$location{$whichhands[2]}] = "VHAND($_[5],$_[7],$_[9],$_[11])";
}
}
elsif (@whichhands == 2)
{
$_ = join("",@whichhands);
if (/E/ && /W/) # only E/W, so interleave
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[2],$_[4],$_[6])";
$h[$location{$whichhands[1]}] = "VHAND($_[1],$_[3],$_[5],$_[7])";
}
else
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[$location{$whichhands[1]}] = "VHAND($_[4],$_[5],$_[6],$_[7])";
}
}
elsif (@whichhands == 1)
{
$h[$location{$whichhands[0]}] = "VHAND($_[0],$_[1],$_[2],$_[3])";
}
# use BML macro
$text .= "HAND(".$h[0].",\n".$h[1].",\n".$h[2].",\n".$h[3].")\n";
$state = 2;
}
}
# rejecting bad case
elsif ($state == 4)
{
if (/^PAGE/)
{
&print_page;
&done;
}
elsif (/^CASE/)
{
# is the answer right?
s/CASE\s*//;
s/\s*$//;
if ($_ eq $answer)
{
$state = 2;
}
}
elsif (/^ENDCASE/)
{
$state = 2;
}
else
{
# ignore input
}
}
# accepting perl code
elsif ($state == 5)
{
if (/^ENDPERL/)
{
if (!$secure) {eval $perlcode;}
$state = 2;
}
else
{
$perlcode .= $_;
}
}
# accepting perl code
elsif ($state == 6)
{
if (/^ENDPERL/)
{
if (!$secure) {eval $perlcode;}
$state = 1;
}
else
{
$perlcode .= $_;
}
}
# accepting 4-player bidding
elsif ($state == 7)
{
# end on new directive
$skip = 0;
for ($i=0;$i<@directives;$i++)
{
if (/^$directives[$i]/)
{
@_ = &split_args($bidding);
$text .= "BID4(".join(",",@_).")\n";
$state = 2;
$skip = 1;
}
}
if ($skip) {redo;}
chop; s/^\s*//; s/\s*$//;
if (/^\s*$/) {next;}
$bidding .= $_." ";
# end is 3 consecutive passes or All Pass
$done = 0;
if (/All\s*Pass/i || /END/)
{ $done = 1; $bidding =~ s/END//; }
elsif (/Pass/i)
{
$_ = $bidding; split;
$passes = 0;
$nobid = 1;
for ($i=0;$i<@_;$i++)
{
# ignore first pass unless bid has occurred
if ($_[$i] =~ /[1234567]/) {$nobid = 0;}
if ($_[$i] =~ /Pass/i)
{$passes++;} else {$passes = 0;}
if ((!$nobid && $passes >= 3) || ($passes >= 4))
{$done = 1; last;}
}
}
if ($done)
{
@_ = &split_args($bidding);
$text .= "BID4(".join(",",@_).")\n";
$state = 2;
}
}
# accepting 2-player bidding
elsif ($state == 8)
{
# end on new directive
$skip = 0;
for ($i=0;$i<@directives;$i++)
{
if (/^$directives[$i]/)
{
@_ = &split_args($bidding);
$text .= "BID4(".join(",",@_).")\n";
$state = 2;
$skip = 1;
}
}
if ($skip) {redo;}
chop; s/^\s*//; s/\s*$//;
if (/^\s*$/) {next;}
$bidding .= $_." ";
if (/END/ || $bidding =~ /[1234567].*Pass/i)
{
$bidding =~ s/END//;
@_ = &split_args($bidding);
$text .= "BIDDING(".join(",",@_).")\n";
$state = 2;
}
}
# Syntax check state
elsif ($state == 9)
{
# mixed/lower case directive?
for ($i=0;$i<@directives;$i++)
{
if (/^$directives[$i]/i && !/^$directives[$i]/)
{
$text .= "Possible mixed/lower case directive:
\n";
$text .= " Line $.:
\n";
$text .= " $_
";
}
}
}
# ELSE blocks
elsif ($state == 10)
{
# exit
if (/^ENDUSE/ || /^ELSE/)
{
$state = 2;
}
}
# reading boards in during preamble
elsif ($state == 11)
{
# end on new directive
$skip = 0;
for ($i=0;$i<@directives;$i++)
{
if (/^$directives[$i]/)
{
$state = 1;
$skip = 1;
}
}
if ($skip) {redo;}
chop; s/^\s*//; s/\s*$//;
split;
$handtokens += @_;
$_ = join(" ",@_);
$savedboards{$board} .= $_." ";
if ($handtokens >= 16)
{ $state = 1; }
}
# reading in results
elsif ($state == 13)
{
#end on new directive
$skip = 0;
for ($i=0;$i<@directives;$i++)
{
if (/^$directives[$i]/)
{
$state = 1;
$skip = 1;
}
}
if (/^\s*$/) {$state = 1; $skip = 1};
if ($skip)
{
# convert into assoc. array.
$resultstring =~ s/^\s*//;
@results = split(/\s+/,$resultstring);
$useresults = 1;
# reprocess directive
redo;
}
else
{
chop;
$resultstring .= " ".$_;
}
}
# ignoring wrong pages
elsif ($state == 12)
{
if (/^PAGE\s*$page/)
{ $state = 2; }
}
} # end while <>
# On end of file:
if ($state == 9)
{
if ($htmldebug)
{
&print_page;
&done;
}
else
{
$text =~ s/\
$//g;
print $text;
}
}
elsif ($state == 1)
{
# didn't find the page
&html_header("Error");
print "
Error
\n";
print "Could not find page $page.\n";
&html_trailer;
&done;
}
else
{
&print_page;
&done;
}
sub print_page
{
if ($title) { &html_header($title); }
else { &html_header($page); }
&bridge_trans($text);
print $text;
&html_trailer;
}
# header
sub html_header
{
print "Content-type: text/html\n\n";
print "\n";
print "\n";
print "$_[0]\n";
print "\n";
print "\n";
print "$layout\n";
}
# trailer
sub html_trailer
{
print "
\n";
print "\n";
print "© $myname,\n";
print "$email,\n";
print "$date\n";
print "\n";
print "\n";
print "\n";
}
# redirection
sub html_redirect
{
print "Location: $_[0]\n\n";
}
# This sets up the go to scorecard boxes
sub end_of_hand
{
$script = $ENV{SCRIPT_NAME};
$xxx .= "\n";
$xxx;
}
# radio boxes
# input 1: hand number (hidden var)
# input 2-3: name of and tag for first (checked) box
# input 4-6: name of and tag for 2nd box, ...
# it'll also assign $scores to the Scores hidden variable
sub html_radio
{
@args = @_;
$script = $ENV{SCRIPT_NAME};
$xxx .= "\n";
$xxx; # return massive string
}
# This generates an image map call and stuffs all useful data into the URL
sub html_imagemap
{
@args = @_;
$file = $ENV{'SCRIPT_NAME'};
$args[1] =~ tr/ /+/;
if (@args > 3)
{
$xxx = "
\n";
$xxx .= "\n";
$xxx;
}
else
{
$xxx = "\n";
$xxx .= "
\n";
$xxx;
}
}
# This prints a scorecard
sub scorecard
{
local($first,$last);
# save arguments
$first = $_[0];
$last = $_[1];
# errors
if ($first > $last) {$first = 1; $last = 26;}
# header
&html_header("Private Score");
# handle scores
$_ = $scores;
s/Appeal;//g; # don't worry about appeals
@s = split(/;/,$_);
for ($i=0;$i<@s;$i++)
{
$_ = $s[$i];
($h,$r) = /(.*):(.*)/;
$scores[$h] = $r;
}
# build next box
$page = $vars{"Page"};
$temp = "Private Score
\n";
$script = $ENV{SCRIPT_NAME};
$temp .= "\n";
# table header line
if (@opp)
{
if (!$textonly)
{
$temp .= "\n";
$temp .= "Hand | Opp | Contract | \n";
$temp .= "Declarer | Score | MPs |
\n";
}
else
{
$temp .= "\n";
$temp .= " Hand Opp Contract Decl. Score MPs\n";
}
}
else
{
if (!$textonly)
{
$temp .= "Hand | Contract | \n";
$temp .= "Declarer | Score | MPs |
\n";
}
else
{
$temp .= "\n";
$temp .= " Hand Contract Decl. Score MPs\n";
}
}
# Each board
$nhands = 0;
$totalmp = 0;
for ($i=$first;$i<=$last;$i++)
{
$op = $i-$first;
# no score on the board
if ($scores[$i] eq "")
{
if ($textonly)
{ $temp .= sprintf(" %s\n",$i); }
else
{
$temp .= " $i | | | ";
$temp .= " | | |
\n";
}
}
# board with score
else
{
$_ = $scores[$i];
($c,$d,$r,$mp) = split(/\./);
if ($textonly)
{
if (@opp)
{ $temp .= sprintf(" %3s %3s %-6s %2s %6s %5s\n",$i,$opp[$op],$c,$d,$r,$mp); }
else
{ $temp .= sprintf(" %3s %-6s %2s %6s %5s\n",$i,$c,$d,$r,$mp); }
}
else
{
if (@opp)
{
$temp .= " $i | ";
$temp .= "$opp[$op] | CARD($c) | ";
$temp .= "$d | $r | $mp |
\n";
}
else
{
$temp .= " $i | CARD($c) | ";
$temp .= "$d | $r | $mp |
\n";
}
}
$nhands++;
if ($mp =~ /\+/) {$mp =~ s/\+//; $mp += .5;}
$totalmp += $mp;
}
} # end each board loop
# end of hand record
if (!$textonly)
{
$temp .= "
\n";
&bridge_trans($temp);
}
else
{$temp .= "\n";}
print $temp;
# summary
if ($nhands > 0)
{
$game = $totalmp / $nhands / $top * 100;
if ($nhands == 1) {$junk = "board";} else {$junk = "boards";}
printf "After %d %s, you have a %.1f%% game.\n",$nhands,$junk,$game;
if ($carryover)
{printf "
With carryover, you have %g matchpoints.\n",$totalmp+$carryover;}
}
# end of page
&html_trailer;
}
# This prints an IMP scorecard
sub imp_scorecard
{
local($first,$last);
# save arguments
$first = $_[0];
$last = $_[1];
# errors
if ($first > $last) {$first = 1; $last = 26;}
# header
&html_header("Private Score");
# handle scores
$_ = $scores;
s/Appeal;//g; # don't worry about appeals
split(/;/,$_);
for ($i=0;$i<@_;$i++)
{
$_ = $_[$i];
($h,$r) = /(.*):(.*)/;
$scores[$h] = $r;
}
# next button
$page = $vars{"Page"};
$temp = "Private Score
\n";
$script = $ENV{SCRIPT_NAME};
$temp .= "\n";
# for each hand
$nhands = 0;
$totalmp = 0;
$plusimp = 0;
$minusimp = 0;
$vps = 0;
for ($i=$first;$i<=$last;$i++)
{
# start new match
if ((!$vp20 && $i == $first) || ($vp20 && (($i-$first) % $vp20) == 0))
{
# header
if ($textonly)
{
$temp .= "\n";
$temp .= " Hand Contract Decl. Score +IMPs -IMPs\n";
}
else
{
$temp .= "
\n";
$temp .= "Hand | Contract | Declarer | ";
$temp .= "Score | IMPs |
\n";
}
}
# if no score, print an empty line
if ($scores[$i] eq "")
{
if ($textonly)
{ $temp .= sprintf(" %s\n",$i); }
else
{
$temp .= " $i | | ";
$temp .= " | | | |
\n";
}
}
# otherwise, print a line with the score on it
else
{
$_ = $scores[$i];
($c,$d,$r,$mp) = split(/\./);
if ($textonly)
{
if ($mp < 0)
{
$temp .= sprintf(" %3s %-6s %2s %6s %4s\n",$i,$c,$d,$r,-$mp);
}
else
{
$temp .= sprintf(" %3s %-6s %2s %6s %4s\n",$i,$c,$d,$r,$mp);
}
}
else
{
if ($mp < 0)
{
$mp = -$mp;
$temp .= " $i | ";
$temp .= "CARD($c) | $d | ";
$temp .= "$r | | $mp |
\n";
$mp = -$mp;
}
else
{
$temp .= " $i | ";
$temp .= "CARD($c) | $d | ";
$temp .= "$r | $mp | |
\n";
}
}
# compute total score
$nhands++;
$totalmp += $mp;
if ($mp > 0) {$plusimp += $mp;} else {$minusimp -= $mp;}
}
# is this the end of a match?
if ((!$vp20 && $i == $last) || (($vp20 && (($i - $first) % $vp20) == $vp20-1) && $nhands > 0))
{
# add trailer
if ($textonly)
{
$temp .= sprintf("Total: %4s %4s\n",$plusimp,$minusimp);
$temp .= "\n";
}
else
{
$temp .= "Total: | | ";
$temp .= " | | $plusimp | ";
$temp .= "$minusimp |
\n";
$temp .= "
\n";
&bridge_trans($temp);
}
print $temp;
$temp = "";
if (!$vp20 && $nhands > 0)
{
$zzz = $totalmp;
if ($nhands == 1) {$junk = "board";} else {$junk = "boards";}
$junk2 = "ahead";
if ($totalmp == 1 || $totalmp == -1) {$junk3 = "";} else {$junk3 = "s";}
if ($totalmp == 0)
{printf "After %d %s, you are exactly tied.\n",$nhands,$junk;}
else
{
if ($totalmp < 0) {$totalmp = -$totalmp; $junk2 = "behind";}
printf "After %d %s, you are %d IMP%s %s.\n",$nhands,$junk,$totalmp,$junk3,$junk2;
}
}
# add VP computation
if ($vp20)
{
print "You get ",&vp20($totalmp)," victory points in this match.\n";
$vps += &vp20($totalmp);
$totalmp = 0;
$plusimp = 0;
$minusimp = 0;
$nhands = 0;
}
}
}
if ($vp20)
{
print "You have $vps victory points so far.\n";
if ($carryover)
{printf "
With carryover, you have %g VPs.\n",$vps+$carryover;}
}
&html_trailer;
}
# This produces a hand records page
sub handrecords
{
&html_header("Hand Records");
$page = $vars{"Page"};
$text = <<"END";
Hand Records
If you go to a board via the links on this
page, you might not be able to get back
here easily, so I suggest that you place a bookmark
here for easy reference.
'."\n";
# insert the hands
for ($i=$firstboard; $i<=$lastboard; $i += 2)
{
$iplusone = $i + 1;
if ($iplusone > $lastboard)
{
$text .= "
\n";
$text .= "Board $i:
\n";
@_ = split(/\s+/,$savedboards{$i});
$h[0] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[1] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[2] = "VHAND($_[5],$_[7],$_[9],$_[11])";
$h[3] = "VHAND($_[12],$_[13],$_[14],$_[15])";
$text .= "HAND($h[0],\n$h[1],\n$h[2],\n$h[3])\n";
}
else
{
$text .= "TWOHANDS(Board $i:, Board $iplusone:,\n";
@_ = split(/\s+/,$savedboards{$i});
$h[0] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[1] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[2] = "VHAND($_[5],$_[7],$_[9],$_[11])";
$h[3] = "VHAND($_[12],$_[13],$_[14],$_[15])";
$text .= "$h[0],\n$h[1],\n$h[2],\n$h[3],\n\n";
@_ = split(/\s+/,$savedboards{$iplusone});
$h[0] = "VHAND($_[0],$_[1],$_[2],$_[3])";
$h[1] = "VHAND($_[4],$_[6],$_[8],$_[10])";
$h[2] = "VHAND($_[5],$_[7],$_[9],$_[11])";
$h[3] = "VHAND($_[12],$_[13],$_[14],$_[15])";
$text .= "$h[0],\n$h[1],\n$h[2],\n$h[3])\n\n";
}
}
# add the links
# find filename
$file = $ENV{'SCRIPT_NAME'};
if ($textonly)
{
for ($i=$firstboard;$i<=$lastboard;$i++)
{
$text =~ s|(Board $i):|$1:|;
}
}
else
{
for ($i=$firstboard;$i<=$lastboard;$i++)
{
$text =~ s|(Board $i):|$1:|;
}
}
&bridge_trans($text);
print $text;
&html_trailer;
}
# Bridge formatting stuff
# hide_parens converts \( and \) into QUOTED_PAREN and QUOTED_THESIS
sub hide_parens
{
$_[0] =~ s/\\\(/__QUOTED_PAREN__/g;
$_[0] =~ s/\\\)/__QUOTED_THESIS__/g;
}
# replace_parens reverses above and removes escapes
sub replace_parens
{
$_[0] =~ s/__QUOTED_PAREN__/(/g;
$_[0] =~ s/__QUOTED_THESIS__/)/g;
}
# this takes a string and does replacement
sub bridge_trans
{
&hide_parens($_[0]);
# user-defined macros
foreach $key (keys %macros)
{
$_[0] =~ s/($key)\(([^\)]*)\)/¯o_sub($macros{$key},$2)/ge;
$_[0] =~ s/$key/$macros{$key}/g;
}
$_[0] =~ s/SUIT\(([^)]*)\)/&suit($1)/ge;
$_[0] =~ s/CARD\(([^)]*)\)/&card($1)/ge;
$_[0] =~ s/FOOTNOTE\(([^)]*)\)/&footnote($1)/ge;
$_[0] =~ s/HHAND\(([^)]*)\)/&hhand($1)/ge;
$_[0] =~ s/BIDDING\(([^)]*)\)/&bidding($1)/ge;
$_[0] =~ s/BID4\(([^)]*)\)/&bid4($1)/ge;
$_[0] =~ s/VHAND\(([^)]*)\)/&vhand($1)/ge;
$_[0] =~ s/HAND\(([^)]*)\)/&hand($1)/ge;
$_[0] =~ s/TWOHANDS\(([^)]*)\)/&twohands($1)/ge;
$_[0] =~ s/PANELIST\(([^)]*)\)/&panelist($1)/ge;
$_[0] =~ s/\\'/'/g;
&replace_parens($_[0]);
}
# this replaces 1H, 2S, CA, etc. with appropriate stuff
sub card
{
$_ = $_[0];
if ($textonly) {return $_;}
if (/Dbl/ || /Double/)
{
''.$_.'';
}
elsif (/^S/)
{
s/^.//;
'
'.$_.'';
}
elsif (/^H/)
{
s/^.//;
'
'.$_.'';
}
elsif (/^D/)
{
s/^.//;
'
'.$_.'';
}
elsif (/^C/)
{
s/^.//;
'
'.$_.'';
}
elsif (/S$/)
{
s/.$//;
''.$_.'
';
}
elsif (/H$/)
{
s/.$//;
''.$_.'
';
}
elsif (/D$/)
{
s/.$//;
''.$_.'
';
}
elsif (/C$/)
{
s/.$//;
''.$_.'
';
}
elsif (/Sx$/ || /SX$/)
{
s/..$//;
''.$_.'
x';
}
elsif (/Hx$/ || /HX$/)
{
s/..$//;
''.$_.'
x';
}
elsif (/Dx$/ || /DX$/)
{
s/..$//;
''.$_.'
x';
}
elsif (/Cx$/ || /CX$/)
{
s/..$//;
''.$_.'
x';
}
elsif (/Sxx$/ || /SXX$/)
{
s/...$//;
''.$_.'
xx';
}
elsif (/Hxx$/ || /HXX$/)
{
s/...$//;
''.$_.'
xx';
}
elsif (/Dxx$/ || /DXX$/)
{
s/...$//;
''.$_.'
xx';
}
elsif (/Cxx$/ || /CXX$/)
{
s/...$//;
''.$_.'
xx';
}
elsif (/^[1234567][Ss]/)
{
s/(.)./$1
/;
''.$_.'';
}
elsif (/^[1234567][Hh]/)
{
s/(.)./$1
/;
''.$_.'';
}
elsif (/^[1234567][Dd]/)
{
s/(.)./$1
/;
''.$_.'';
}
elsif (/^[1234567][Cc]/)
{
s/(.)./$1
/;
''.$_.'';
}
else
{
''.$_.'';
}
}
# hhand draws a horizontal hand
# it takes four arguments: spades, hearts, diamonds, clubs
sub hhand
{
@args = split(/,/,$_[0]);
if ($textonly)
{
return ' '.
"$args[0] $args[1] $args[2] $args[3]".
'';
}
'
'.$args[0].
'
'.$args[1].
'
'.$args[2].
'
'.$args[3].'';
}
# vhand draws a vertical hand
# it takes four arguments: spades, hearts, diamonds, clubs
sub vhand
{
@args = split(/,/,$_[0]);
if ($textonly)
{
return "$args[0]
$args[1]
$args[2]
$args[3]";
}
'
'.$args[0].'
'.
'
'.$args[1].'
'.
'
'.$args[2].'
'.
'
'.$args[3];
}
# hand draws a full hand diagram
# it takes four arguments, North, West, East, South
sub hand
{
local(@north,@south,@east,@west,$argument);
$argument = $_[0];
$argument =~ s/\n//g;
@args = split(/,/,$argument);
if ($textonly)
{
@north = split(/\
/,$args[0]);
@west = split(/\
/,$args[1]);
@east = split(/\
/,$args[2]);
@south = split(/\
/,$args[3]);
if (@north) {$north = "North";} else {$north = "";};
if (@west ) {$west = "West ";} else {$west = " ";};
if (@east ) {$east = "East ";} else {$east = "";};
if (@south) {$south = "South";} else {$south = "";};
$temp = "\n";
$temp .= " $north\n";
$temp .= " $north[0]\n";
$temp .= " $north[1]\n";
$temp .= " $north[2]\n";
$temp .= " $north[3]\n";
$temp .= "$west $east\n";
$temp .= sprintf("%-14s %-14s\n",$west[0],$east[0]);
$temp .= sprintf("%-14s %-14s\n",$west[1],$east[1]);
$temp .= sprintf("%-14s %-14s\n",$west[2],$east[2]);
$temp .= sprintf("%-14s %-14s\n",$west[3],$east[3]);
$temp .= " $south\n";
$temp .= " $south[0]\n";
$temp .= " $south[1]\n";
$temp .= " $south[2]\n";
$temp .= " $south[3]\n";
$temp .= "
\n";
$temp;
}
else
{
"\n".
" | ".$args[0]." | |
\n".
"".$args[1]." |  | ".$args[2]." |
\n".
" | ".$args[3]." | |
\n".
"
\n";
}
}
# twohands draws two full hand diagrams, horizontally on the page
# it takes 10 arguments: words, words, hand, hand
sub twohands
{
local(@north,@south,@east,@west,$argument);
$argument = $_[0];
$argument =~ s/\n//g;
@args = split(/,/,$argument);
if ($textonly)
{
@north1 = split(/\
/,$args[2]);
@west1 = split(/\
/,$args[3]);
@east1 = split(/\
/,$args[4]);
@south1 = split(/\
/,$args[5]);
@north2 = split(/\
/,$args[6]);
@west2 = split(/\
/,$args[7]);
@east2 = split(/\
/,$args[8]);
@south2 = split(/\
/,$args[9]);
$north = "North";
$west = "West ";
$east = "East ";
$south = "South";
$temp = "
\n";
$temp .= "\n";
$temp .= sprintf("%-25s |",$args[0]);
$temp .= sprintf("%-25s \n",$args[1]);
$temp .= " $north | $north\n";
$temp .= sprintf(" %-14s |",$north1[0]);
$temp .= sprintf(" %-14s \n",$north2[0]);
$temp .= sprintf(" %-14s |",$north1[1]);
$temp .= sprintf(" %-14s \n",$north2[1]);
$temp .= sprintf(" %-14s |",$north1[2]);
$temp .= sprintf(" %-14s \n",$north2[2]);
$temp .= sprintf(" %-14s |",$north1[3]);
$temp .= sprintf(" %-14s \n",$north2[3]);
$temp .= "$west $east | ";
$temp .= "$west $east\n";
$temp .= sprintf("%-14s %-14s | ",$west1[0],$east1[0]);
$temp .= sprintf("%-14s %-14s \n" ,$west2[0],$east2[0]);
$temp .= sprintf("%-14s %-14s | ",$west1[1],$east1[1]);
$temp .= sprintf("%-14s %-14s \n" ,$west2[1],$east2[1]);
$temp .= sprintf("%-14s %-14s | ",$west1[2],$east1[2]);
$temp .= sprintf("%-14s %-14s \n" ,$west2[2],$east2[2]);
$temp .= sprintf("%-14s %-14s | ",$west1[3],$east1[3]);
$temp .= sprintf("%-14s %-14s \n" ,$west2[3],$east2[3]);
$temp .= " $south | $south\n";
$temp .= sprintf(" %-14s |",$south1[0]);
$temp .= sprintf(" %-14s \n",$south2[0]);
$temp .= sprintf(" %-14s |",$south1[1]);
$temp .= sprintf(" %-14s \n",$south2[1]);
$temp .= sprintf(" %-14s |",$south1[2]);
$temp .= sprintf(" %-14s \n",$south2[2]);
$temp .= sprintf(" %-14s |",$south1[3]);
$temp .= sprintf(" %-14s \n",$south2[3]);
$temp .= "
\n";
$temp;
}
else
{
"\n".
"
| | \n".
"
|
\n".
"$args[0] | | $args[1] |
\n".
" | ".$args[2]." | | \n".
" | \n".
" | ".$args[6]." | |
\n".
"".$args[3]." |  | ".$args[4]." | \n".
" | \n".
" ".$args[7]." |  | ".$args[8]." |
\n".
" | ".$args[5]." | | \n".
" | \n".
" | ".$args[9]." | |
\n".
"
\n";
}
}
# Two player bidding
sub bidding
{
@args = split(/,/,$_[0]);
if ($textonly)
{
$output = "\n";
$max = $#args+1;
for ($i = 0; $i <$max;$i+= 2)
{
$output .= sprintf("%-8s %-8s\n",$args[$i],$args[$i+1]);
}
$output .= "
\n";
$output;
}
else
{
$output = "\n";
# first two args are players
$output .= '';
$output .= $args[0];
$output .= ' | ';
$output .= $args[1];
$output .= " |
\n";
# remaining args are bids
$max = $#args+1;
for ($i=2;$i<$max;$i+=2)
{
$output .= ''.&card($args[$i]).
' | '.&card($args[$i+1])." |
\n";
}
$output .= "
\n";
$output;
}
}
# four player bidding
sub bid4
{
local($td1,$td2,$td3);
@args = split(/,/,$_[0]);
if ($textonly)
{
$output = "\n";
$max = $#args+3;
for ($i=0;$i<$max;$i+=4)
{
$output .= sprintf("%-8s %-8s %-8s %-8s\n",$args[$i],$args[$i+1],$args[$i+2],$args[$i+3]);
}
$output .= "
\n";
$output;
}
else
{
$output = "\n";
# first four args are players
$output .= '';
$output .= $args[0];
$output .= ' | ';
$output .= $args[1];
$output .= ' | ';
$output .= $args[2];
$output .= ' | ';
$output .= $args[3];
$output .= " |
\n";
$td1 = "td";
$td2 = "td";
$td3 = "td";
# remaining args are bids
$max = $#args+3;
for ($i=4;$i<$max;$i+=4)
{
# handle "All pass" well.
if ($args[$i ] =~ /All\s*Pass/i) {$td1 = "td colspan = 4";}
if ($args[$i+1] =~ /All\s*Pass/i) {$td2 = "td colspan = 3";}
if ($args[$i+2] =~ /All\s*Pass/i) {$td3 = "td colspan = 2";}
$output .= "<$td1>". &card($args[$i]).
"<$td2>".&card($args[$i+1]).
"<$td3>".&card($args[$i+2]).
"".&card($args[$i+3]).
" |
\n";
}
$output .= "
\n";
$output;
}
}
# suit draws a two-player suit combination
sub suit
{
@args = split(/,/,$_[0]);
if ($textonly)
{
$output = "\n";
$output .= "Dummy\n";
$output .= "$args[0]\n";
$output .= "\n";
$output .= "Declarer\n";
$output .= "$args[1]\n";
$output .= "
\n";
$output;
}
else
{
"\n".
"Dummy |
\n".
"CARD(".$args[0].") |
\n".
" |
\n".
"Declarer |
\n".
"CARD(".$args[1].") |
\n".
"
\n";
}
}
# Footnote draws superscripts
sub footnote
{
if ($textonly)
{
# kludge, but works
"__QUOTED_PAREN__$_[0]__QUOTED_THESIS__ ";
}
else
{
"".$_[0]."";
}
}
# Panelist is strange
sub panelist
{
$_[0] =~ tr/a-z/A-Z/; # upcase
$init = $_[0];
$rest = $_[0];
$init =~ s/(.).*/$1/;
$rest =~ s/.//;
"".$init."".$rest."\n";
}
# split arguments
# Remove quotes, but keep spaces in quotes
sub split_args
{
# this works by changing quotes in strings to __SP__
# then changing them back after the split.
local(@args,$string,$qlevel);
# are we in a string?
$qlevel = 0; # 0 = no
# by character
@args = split(//,$_[0]);
for ($i=0;$i<@args;$i++) # for each character
{
if ($args[$i] eq '"')
{ $qlevel = !$qlevel; }
elsif ($args[$i] eq ' ')
{ if ($qlevel) {$args[$i] = "__SP__" ;} }
}
# stick it all back together
$string = join("",@args);
# remove quotes
$string =~ s/"//g;
# split on white space
@args = split(/\s+/,$string);
for ($i=0;$i<@args;$i++)
{ $args[$i] =~ s/__SP__/ /g; }
@args;
}
# clean up
sub done
{
close(MOVIEFILE);
exit(0);
}
# errors
sub error
{
&html_header("Error");
print "Sorry, an unrecoverable error occurred:\n";
print $_[0];
&html_trailer;
exit(0);
}
# reasonably pretty date for last creation time.
# This might be different from system to system.
sub lmdate
{
$_ = &ctime((stat($_[0]))[9]); # default is last modified date of file
split(/[\s-]+/,$_);
# PC date
# Fri 03-22-1996
# UNIX date
# Fri Mar 22 10:16:38 PST 1996
if ($unix == 0)
{ $_[1] = $month[$_[1]]; }
if ($_[5] =~ /19/ || $_[5] =~ /20/)
{ &fullday($_[0]).", ".$_[1]." ".$_[2].", ".$_[5]; }
elsif ($_[4] =~ /19/ || $_[4] =~ /20/)
# some ctimes don't supply time zone
{ &fullday($_[0]).", ".$_[1]." ".$_[2].", ".$_[4]; }
elsif ($_[3] =~ /19/ || $_[3] =~ /20/)
{ &fullday($_[0]).", ".$_[1]." ".$_[2].", ".$_[3]; }
else
{$_;}
}
sub fullday
{
if ($_[0] =~ /Mon/i) { "Monday";}
elsif ($_[0] =~ /Tue/i) { "Tuesday";}
elsif ($_[0] =~ /Wed/i) { "Wednesday";}
elsif ($_[0] =~ /Thu/i) { "Thursday";}
elsif ($_[0] =~ /Fri/i) { "Friday";}
elsif ($_[0] =~ /Sat/i) { "Saturday";}
elsif ($_[0] =~ /Sun/i) { "Sunday";}
else { $_[0]; }
}
# this does macro substitution
# The arguments are the replacement string and
# argument list.
sub macro_sub
{
local($replacement,@args,$i);
$replacement = $_[0];
@args = split(/,/,$_[1]);
unshift(@args,"");
for ($i=1;$i<=@args;$i++)
{
$replacement =~ s/\$$i/$args[$i]/g;
}
$replacement;
}
# Compute imp results diff = imps(a,b)
sub imps
{
local($diff);
if ($imppairs)
# subtract datum score
{$diff = $_[0] - $_[1];}
else
# add teammates' result
{$diff = $_[0] + $_[1];}
if ($diff == 0)
{ 0; }
elsif ($diff > 0)
{
if ($diff < 20 ) { 0; }
elsif ($diff < 50 ) { 1; }
elsif ($diff < 90 ) { 2; }
elsif ($diff < 130 ) { 3; }
elsif ($diff < 170 ) { 4; }
elsif ($diff < 220 ) { 5; }
elsif ($diff < 270 ) { 6; }
elsif ($diff < 320 ) { 7; }
elsif ($diff < 370 ) { 8; }
elsif ($diff < 430 ) { 9; }
elsif ($diff < 500 ) { 10; }
elsif ($diff < 600 ) { 11; }
elsif ($diff < 750 ) { 12; }
elsif ($diff < 900 ) { 13; }
elsif ($diff < 1100) { 14; }
elsif ($diff < 1300) { 15; }
elsif ($diff < 1500) { 16; }
elsif ($diff < 1750) { 17; }
elsif ($diff < 2000) { 18; }
elsif ($diff < 2250) { 19; }
elsif ($diff < 2500) { 20; }
elsif ($diff < 3000) { 21; }
elsif ($diff < 3500) { 22; }
elsif ($diff < 4000) { 23; }
else { 24; }
}
else
{
$diff = -$diff;
if ($diff < 20 ) { -0; }
elsif ($diff < 50 ) { -1; }
elsif ($diff < 90 ) { -2; }
elsif ($diff < 130 ) { -3; }
elsif ($diff < 170 ) { -4; }
elsif ($diff < 220 ) { -5; }
elsif ($diff < 270 ) { -6; }
elsif ($diff < 320 ) { -7; }
elsif ($diff < 370 ) { -8; }
elsif ($diff < 430 ) { -9; }
elsif ($diff < 500 ) { -10; }
elsif ($diff < 600 ) { -11; }
elsif ($diff < 750 ) { -12; }
elsif ($diff < 900 ) { -13; }
elsif ($diff < 1100) { -14; }
elsif ($diff < 1300) { -15; }
elsif ($diff < 1500) { -16; }
elsif ($diff < 1750) { -17; }
elsif ($diff < 2000) { -18; }
elsif ($diff < 2250) { -19; }
elsif ($diff < 2500) { -20; }
elsif ($diff < 3000) { -21; }
elsif ($diff < 3500) { -22; }
elsif ($diff < 4000) { -23; }
else { -24; }
}
}
# compute VPs on the standard 20 VP scale
sub vp20
{
local($diff);
$diff = $_[0];
if ($vp20 >= 9 && $vp20 <= 11)
{
if ($diff <= -36) {0;}
elsif ($diff <= -31) {1;}
elsif ($diff <= -26) {2;}
elsif ($diff <= -22) {3;}
elsif ($diff <= -18) {4;}
elsif ($diff <= -14) {5;}
elsif ($diff <= -10) {6;}
elsif ($diff <= -6 ) {7;}
elsif ($diff <= -3 ) {8;}
elsif ($diff <= -1 ) {9;}
elsif ($diff <= 0 ) {10;}
elsif ($diff <= 2 ) {11;}
elsif ($diff <= 5 ) {12;}
elsif ($diff <= 9 ) {13;}
elsif ($diff <= 13) {14;}
elsif ($diff <= 17) {15;}
elsif ($diff <= 21) {16;}
elsif ($diff <= 25) {17;}
elsif ($diff <= 30) {18;}
elsif ($diff <= 35) {19;}
else {20;}
}
else
{
if ($diff <= -28) {0;}
elsif ($diff <= -24) {1;}
elsif ($diff <= -20) {2;}
elsif ($diff <= -17) {3;}
elsif ($diff <= -14) {4;}
elsif ($diff <= -11) {5;}
elsif ($diff <= -8 ) {6;}
elsif ($diff <= -5 ) {7;}
elsif ($diff <= -3 ) {8;}
elsif ($diff <= -1 ) {9;}
elsif ($diff <= 0 ) {10;}
elsif ($diff <= 2 ) {11;}
elsif ($diff <= 4 ) {12;}
elsif ($diff <= 7 ) {13;}
elsif ($diff <= 10) {14;}
elsif ($diff <= 13) {15;}
elsif ($diff <= 16) {16;}
elsif ($diff <= 19) {17;}
elsif ($diff <= 23) {18;}
elsif ($diff <= 27) {19;}
else {20;}
}
}
sub printleaders
{
local($name,$xxx,$index,$score,@leaders);
local($first,$last);
$xxx = "";
# we need to compute scores; remember, we may have played any of these teams
if ($vp20)
{
# save arguments
$first = $firstboard;
$last = $lastboard;
# errors
if ($first > $last) {$first = 1; $last = 26;}
# handle scores
$_ = $scores;
s/Appeal;//g; # don't worry about appeals
split(/;/,$_);
for ($i=0;$i<@_;$i++)
{
$_ = $_[$i];
($h,$r) = /(.*):(.*)/;
$scores[$h] = $r;
}
# for each hand
$nhands = 0;
$totalmp = 0;
$vps = 0;
for ($i=$first;$i<=$last;$i++)
{
# compute score
if ($scores[$i] ne "")
{
$_ = $scores[$i];
($c,$d,$r,$mp) = split(/\./);
$nhands++;
$totalmp += $mp;
}
# is this the end of a match?
if (((($i - $first) % $vp20) == $vp20-1) && $nhands > 0)
{
# add VP computation
if ($vp20)
{
$vps += &vp20($totalmp);
# add remainder of 20 to opponent
$thisopp = $opp[$i-$first];
$theirscore = 20 - &vp20($totalmp);
$teamscore{$thisopp} += $theirscore;
$totalmp = 0;
$nhands = 0;
}
}
}
}
# add us in to the leader list
$opponent{"0"} = "You";
$teamscore{"0"} = $vps + $carryover;
# table header
$xxx .= "\n";
# sort by score
@leaders = reverse sort {$teamscore{$a} <=> $teamscore{$b}} keys(%teamscore);
for ($i = 0;$i < @leaders; $i++)
{
$index = $i + 1;
$name = $opponent{$leaders[$i]};
$score = $teamscore{$leaders[$i]};
$xxx .= sprintf("%d | %s | %g |
\n",
$index,$name,$score);
}
# table trailer
$xxx .= "
\n";
# add congrats if he won
if ($leaders[0] == 0)
{
$xxx .= 'Congratulations!!!
You Won!!!
';
$xxx .= "\n";
}
$xxx;
}