Inspired by a line of code on irc by krunen++, I returned to the scripting games problems (following PM's suggestion in a blog a while ago).

Perl6 rocks! 30 lines to solve the problem. The perl5 solution was a neat 45 lines. The vbscript took 197 lines! In lines of code perl6 is 50% better than perl5 and 557% better than vbscript.

But it is the power of the metaoperators that is awesome! The definition of a deck of cards took 1 line in perl6, 6 lines in perl5, and 54 lines (essentially one line per card!) in vbscript.

Note also the reduction operator [+] (see line 46) that sums in a single line a list of values.

Richard
<following code in attachment too>
# Perl6 solution to Scripting Games #10 (2008)
# Problem statement at http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/aevent10.mspx
# Not counting blank lines or extra lines used for formatting
# the model solution in vbscript took 179 lines, 54 lines to create the deck of cards # the model perl5 solution took 45 lines (neat code with overloading), 6 lines for the deck # my perl6 took 30 lines, 1 line for the deck (not counting the wrap around for visibility).

# the deck definition shows the power of metaoperators.

use v6;

my %deck = <Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King>
   X~ (" of " X~ <Spades Hearts Diamonds Clubs>)
   Z (11,2..10,10,10,10 X* 1,1,1,1);

my $dscore;
my $pscore;
my %dealer;
my %player;
draw %player, %deck, $pscore, 'Player';
draw %dealer, %deck, $dscore, 'Dealer';

repeat {
  draw(%player, %deck, $pscore, 'Player');
} until $pscore >= 21 or prompt("Stay (s) or Hit (other key)? ") ~~ m/:i s /;

given $pscore {
   when $_ > 21 { say "\nOver 21. Sorry, you lose" }
   when $_ == 21 { say "\n21 !!! You win." }
   default {
   repeat {
       draw(%dealer, %deck, $dscore, 'Dealer');
   } until $pscore <= $dscore;

   say "Dealer is bust" if $dscore > 21;
say $pscore <= $dscore <= 21 ?? "\nDealer's score >= your score. Sorry you lose." !! "\nYou win";
   }
};

sub draw (%hand is rw, %deck is rw, $score is rw, $name) {
   my %card = %deck.pick;
   %deck.delete(keys %card);
   %hand = %hand, %card;
   say "\n$name\'s hand is:";
   for keys %hand { .say };
   $score = [+] values %hand;
   say "Score is $score";
};


Attachment: game21.pl
Description: Perl program

Reply via email to