Monday, July 6, 2009

Dice Game Perl 6

Saw this lovely piece of Perl 5 code this weekend and decided to try to duplicate it in Perl 6. For my first attempt, I ended up reverting back to the original because I have no idea how to get the sweet features allowed by Pod::Usage, Getopt::Long, and Number::Format in Perl 6. But even this first simple attempt is significantly nicer than the Scala original IMO.
use v6;
sub play_game($bet, $plays)
{
my $start_money = $plays * $bet;
my $money = $start_money;
for 1 .. $plays
{
my $roll = int( rand() * 100 ) + 1;
if ( $roll <= 50 ) {
$money -= $bet;
} elsif ( 66 <= $roll <= 75 ) {
$money += 0.5 * $bet;
} elsif ( 76 <= $roll <= 99 ) {
$money += $bet;
} elsif ( $roll == 100 ) {
$money += 2 * $bet;
}
}
say "$start_money\$ became $money\$ after $plays plays: You get {$money / $start_money}\$ for a dollar";
}
play_game(1.0, 1000);
play_game(1.5, 50);
play_game(4.0, 100);
view raw dice_game.pl hosted with ❤ by GitHub

This is one example where the chained comparison operators really pays off in making cleaner and easier to understand code. The need to declare an object just to declare a function is a dumb feature Scala carries over from Java. Using say the way I have used it here pales in comparison to Perl 5, but is definitely cleaner and nicer than Scala's printf. And I don't see any advantage here to having a Random class instead of a simple rand function.

Downsides to Perl 6 (other than currently lacking the CPAN glory of the Perl 5 version, so far as I know): It's definitely slower than I would like. And not only is it slower, but it is progressively slower: 16 seconds if I use (10000, 500, 1000) plays, 4 minutes and 9 seconds if I take ten times those numbers, rather than the 2 minutes 40 seconds you would expect.

Potential improvements: Maybe given when instead of those chained ifs. Wonder how that would compare performance wise?

3 comments:

  1. When I initially read this I thought given and when would really make more sense anyway. I doubt it would give better performance, but it would be more perl6-y. OTOH I'd be afraid that if you were to use it the Scala guy would be all: that is objectively harder to read (sic) so worse.

    ReplyDelete
  2. I've just implemented another version for this in Perl 6 at http://daniel.ruoso.com/categoria/perl/dice-game-perl-6

    ReplyDelete
  3. Daniel's solution is much nicer than mine -- I strongly encourage anyone looking here to check it out.

    ReplyDelete