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 <