root/examples/cribbage_scoring.pl

Revision 14440, 2.5 kB (checked in by lwall, 2 years ago)

hash curlies can't end a statement

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
1use v6-alpha;
2
3# Brute force proof that every cribbage hand with a 5 is >= 2 points
4# See http://perlmonks.org/index.pl?node_id=458728 for details
5
6# The following code will not work yet as of revision 4167
7# There are two bugs and two unimplemented features
8# Bug 1     - t/pugsbugs/return_with_trailing_stuff.t
9# Bug 2     - t/pugsbugs/postincrement_in_subscripts.t
10# Feature 1 - t/operators/hyper.t (hyper dereferencing)
11# Feature 2 - t/statements/last.t (last <label>)
12
13my $next = combo(5, new_deck());
14while $combo == 1 {
15    # Skip all hands that do not contain a 5
16#    next if none( @combo.>>.<val> ) == 5;
17
18    # Skip all hands that have a score of at least 2
19#    next if score( @combo ) > 1;
20
21    # Print out the rest
22#    say ~@combo.>>.<suit>;
23}
24
25sub score ( @hand ) returns Int {
26    my $score = 0;
27
28    # [234] of a kind
29    my %ordval;
30    for @hand.>>.<num> { %ordval{$_}++ };
31    for %ordval.values { $score += $_ * $_ - 1 }
32
33    # Flush
34    $score += ([eq] @hand[0..3].>>.<suit>)
35        ?? ([eq] @hand[3,4].>>.<suit>) ?? 5 !! 4
36        !! 0;
37
38    # Check for right-jack, @hand[-1] is community card
39    $score++ if grep { $_<num> == 11 && $_<suit> eq @hand[-1]<suit> }, @hand[0..3];
40
41    # Count 15's
42    my @vals = @hand>>.<val>;
43    for 2 .. 5 {
44        my $next = combo($_, @vals);
45        while my @combo = $next() { $score += 2 if ([+] @combo) == 15 }
46    }
47
48    # Runs
49    SPAN:
50    for 5, 4, 3 -> $span {
51        for (sort { $^a <=> $^b }, %ordval.keys) -> $start {
52            if all( %ordval{$start .. $start + $span} ) > 1 {
53                $score += [*] %ordval{$start .. $start + $span}, $span;
54                last SPAN;
55            }
56        }
57    }
58    return $score;
59}
60
61sub combo (Int $by is copy, @list is copy) returns Ref {
62    my @position = 0 .. $by - 2, $by - 2;
63    my @stop     = @list.elems - $by .. @list.end;
64    my $done     = undef;
65    return sub {
66        return () if $done;
67        my $cur = @position.end;
68        while ++@position[ $cur ] > @stop[ $cur ] {
69            @position[ --$cur ]++;
70            next if @position[ $cur ] > @stop[ $cur ];
71            my $new_pos = @position[ $cur ];
72            @position[ $cur .. @position.end ] = $new_pos .. $new_pos + $by;
73            last;
74        }
75        $done = 1 if @position[ 0 ] == @stop[ 0 ];
76        return @list[ @position ];
77    };
78}
79
80sub new_deck () returns Array {
81    return (1..13).map: -> $num {
82        <H D C S>.map: -> $suit {
83            { num => $num, val => $num > 10 ?? 10 !! $num, suit => $suit };
84        }
85    };
86}
Note: See TracBrowser for help on using the browser.