sub score {
# score is reported in millions.
my $t = .1; # there is an actual minimum score.
my $b = 0; # this counts the balls.
my $round = 0;
while (++$round) {
# it's a 3 ball table, so ...
last if $b > 3;
# get some points,
$t += int(rand $round*10)/10;
# risk draining
(++$b && redo) if (int rand int sqrt (9*$round));
# possibly get an extra ball
$b-- unless int rand(5);
# get the big points if we made it this far
$t += 2 * $round;
# the rest of this isn't interesting
# let me know if something too unlikely happens...
print ("Divine Intervention: $t points in $round rounds.\n")
and last if not $round % 20;
# ... and stop it if it gets out of hand
print ("Apocolypse!") and last if $round > 400;
}
# point out statistically unlikely games;
# otoh, they should range up to 200 ~ .01% of the time,
# and some real games do fail to get off the ground.
warn "Great game: $t in $round!\n" if ($round > 12 or $t > 150);
warn "Horrid try: $t in $round!\n" if ($round < 1 or $t < .2);
return $t;
}
####
###
#
# this sub was originally separated out so i could try averages vs.
# weighting the averages toward the most recent game.
# i chose to weight them because it won't allow any one game to be too hard.
sub game {
my $historic = shift;
my $game = score;
return (($historic+$game)/2);
}
### the meta game itself.
#
# basically, each round you are trying to keep your (weighted) average score above
# the target (set at the start of the metagame, and incremented with each game).
# $spares is the number of games you can "do over";
# pretend that didn't happen and play that game again.
sub meta {
my ($historic, $target, $spares) = @_;
my $games = 0;
my $archive = 0;
do {
{
$archive = $historic;
($historic) = game($historic);
if ($historic < $target and $spares) {
--$spares;
$historic = $archive;
redo;
}
}
} while (++$games and $historic > $target and ++$target);
return ($archive, --$target, $games);
}
####
sub show_meta {
my ($first, $target, $spares) = @_;
my ($lastgood, $made, $games) = meta (@_);
print <