#!/usr/bin/perl use strict; my $HtmlFile = shift(); print "Saving HTML to $HtmlFile\n"; my $Name1 = GetPrompt("Player 1: "); my $Name2 = GetPrompt("Player 2: "); chomp($Name1,$Name2); Game($HtmlFile, $Name1,$Name2); sub Game(){ my ($HtmlFile, @Names) = @_; my $Visitor = 0; # Who is at the table (0 or 1) my $Reds = 10; # How many reds remain on the table my $Colour = 0; # What stage of the endgame are we in my $ColourOkay = 0; # Are we shooting for colour after a red my @Scores = (0,0); # Players' scores my $VisitScore = 0; # Score for this visit to the table my $VisitDescription = ""; my @GameLog; while(1){ # Display status ShowScore(\@Names, $Visitor, $Reds, $Colour, $ColourOkay,\@Scores); SaveScore($HtmlFile, \@Names, $Visitor, $Reds, $Colour, $ColourOkay,\@Scores, \@GameLog, 0); # Get keyboard input my $Ball = lc(GetPrompt(sprintf("%s's shot [1-7 or X]: ", $Names[$Visitor]))); # Missed shot if($Ball eq 'x'){ my $GameLogItem = sprintf("%s scores %d", $Names[$Visitor], $VisitScore) . ($VisitScore > 0 ? " ($VisitDescription)":"") . ($VisitScore > 0 ? sprintf(", total %d",$Scores[$Visitor]):""); push(@GameLog, $GameLogItem); if($VisitScore > 0){ Announce($Names[$Visitor], $VisitScore, 1); } $Visitor = 1 - $Visitor; $VisitScore = 0; $VisitDescription = ""; $ColourOkay = 0; } # Red ball elsif($Ball eq '1'){ if($Reds > 0){ if($ColourOkay){ Error("Invalid state (shooting for colour)\n"); } else{ $Reds--; $Scores[$Visitor]++; $VisitScore++; $VisitDescription .= "Red "; $ColourOkay = 1; Announce($Names[$Visitor], 1); if($Reds == 0){ $Colour = 2; } } } else{ Error("Invalid state (no reds remain)\n"); } } # Coloured ball elsif($Ball > 1 && $Ball <= 7){ # Endgame colours if($Reds == 0 && !$ColourOkay){ if($Ball == $Colour){ $Scores[$Visitor] += $Ball; $VisitScore += $Ball; $VisitDescription .= GetColour($Ball) . " "; Announce($Names[$Visitor], $Ball, 0); if($Colour == 7){ print "End of game (pot black)\n"; my $GameLogItem = sprintf("%s scores %d, ending this game (%s), total %d", $Names[$Visitor], $VisitScore, $VisitDescription, $Scores[$Visitor]); push(@GameLog, $GameLogItem); SaveScore($HtmlFile, \@Names, $Visitor, $Reds, $Colour, $ColourOkay,\@Scores, \@GameLog, 1); exit; } else{ $Colour++; } } else{ Error("Invalid state (shooting for %s)\n",GetColour($Colour)); } } # Startgame colours else{ if($ColourOkay){ $Scores[$Visitor] += $Ball; $VisitScore += $Ball; $VisitDescription .= GetColour($Ball) . " "; Announce($Names[$Visitor], $Ball, 0); $ColourOkay = 0; } else{ Error("Invalid state (not shooting for colour)\n"); } } } elsif($Ball eq '?'){ Helpfile(); } elsif($Ball eq 'q'){ exit; } else{ Error("Invalid command (q for quit, ? for help)\n"); } } } sub Announce(){ my ($Name, $Score, $IsChangeover) = @_; if($IsChangeover){ print "> Loud voice: $Name scores $Score\n"; } else{ print "> Soft voice: $Name, $Score\n"; } } sub SaveScore(){ my ($HtmlFile,$RefNames,$Visitor,$Reds,$Colour,$ColourOkay,$RefScores, $RefGameLog, $Finished) = @_; my @Names = @$RefNames; my @Scores = @$RefScores; my @GameLog = @$RefGameLog; my $Text = ""; my $Remaining = GetRemaining($Reds, $Colour); my $PlayFor = ""; if($ColourOkay){ $PlayFor = "a colour"; } else{ if($Reds > 0){ $PlayFor = "a red"; } else{ $PlayFor = "the " . lc(GetColour($Colour)); } } if($Finished){ # Finished, draw if($Scores[0] == $Scores[1]){ $Text .= sprintf("
Game is finished. %s draws with %s, at %d-all
\n", $Names[0], $Names[1], $Scores[0]); } # Finished, not a draw else{ my $First = ($Scores[0] > $Scores[1]) ? 0 : 1; my $Second = 1 - $First; # Finished, in a single break $Text .= sprintf("Game is finished. %s wins against %s with a score of %d to %d
\n", $Names[$First], $Names[$Second], $Scores[$First], $Scores[$Second]); } } # Game still in progress else{ # Display players and their scores foreach my $ii(0..1){ if($Visitor == $ii){ $Text .= sprintf("%s is at the table, playing for %s, with a score of %d
\n", $Names[$ii], $PlayFor, $Scores[$ii]); } else{ $Text .= sprintf("%s has a score of %d
\n", $Names[$ii], $Scores[$ii]); } } $Text .= "\n"; if($Reds > 0 || $ColourOkay){ $Text .= sprintf("%d %s on the table, ", $Reds, $Reds > 1 ? "reds":"red"); } else{ $Text .= sprintf("Endgame, %s is the next colour. ", lc(GetColour($Colour))); } $Text .= sprintf("%d points remaining\n", $Remaining); $Text .= "
\n"; } # Display transcript of the entire game if(length(@GameLog) > 0){ $Text .= "Transcript:\n