Skip to content

Instantly share code, notes, and snippets.

@jani
Forked from masak/poker hand classification
Created December 2, 2009 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jani/247670 to your computer and use it in GitHub Desktop.
Save jani/247670 to your computer and use it in GitHub Desktop.
use v6;
enum Suit <spades hearts diamonds clubs>;
enum Rank (2, 3, 4, 5, 6, 7, 8, 9, 10,
'jack', 'queen', 'king', 'ace');
class Card {
has Suit $.suit;
has Rank $.rank;
method Str {
$.rank.name ~ ' of ' ~ $.suit.name;
}
}
subset PokerHand of List where { .elems == 5 && all(|$_) ~~ Card }
sub n-of-a-kind($n, @cards) {
for @cards>>.rank.uniq -> $rank {
return True if $n == grep $rank, @cards>>.rank;
}
return False;
}
subset Quad of PokerHand where { n-of-a-kind(4, $_) }
subset ThreeOfAKind of PokerHand where { n-of-a-kind(3, $_) }
subset OnePair of PokerHand where { n-of-a-kind(2, $_) }
subset FullHouse of PokerHand where OnePair & ThreeOfAKind;
subset Flush of PokerHand where -> @cards { [==] @cards>>.suit }
subset Straight of PokerHand where sub (@cards) {
my @sorted-cards = @cards.sort({ .rank });
my ($head, @tail) = @sorted-cards;
for @tail -> $card {
return False if $card.rank != $head.rank + 1;
$head = $card;
}
return True;
}
subset StraightFlush of Flush where Straight;
subset TwoPair of PokerHand where sub (@cards) {
my $pairs = 0;
for @cards>>.rank.uniq -> $rank {
++$pairs if 2 == grep $rank, @cards>>.rank;
}
return $pairs == 2;
}
sub classify(PokerHand $_) {
when StraightFlush { 'straight flush', 8 }
when Quad { 'four of a kind', 7 }
when FullHouse { 'full house', 6 }
when Flush { 'flush', 5 }
when Straight { 'straight', 4 }
when ThreeOfAKind { 'three of a kind', 3 }
when TwoPair { 'two pair', 2 }
when OnePair { 'one pair', 1 }
when * { 'high cards', 0 }
}
my @deck = map -> $suit, $rank { Card.new(:$suit, :$rank) },
(Suit.pick(*) X Rank.pick(*));
@deck .= pick(*);
my @hand1;
@hand1.push(@deck.shift()) for ^5;
my @hand2;
@hand2.push(@deck.shift()) for ^5;
say 'Hand 1: ', map { "\n $_" }, @hand1>>.Str;
say 'Hand 2: ', map { "\n $_" }, @hand2>>.Str;
my ($hand1-description, $hand1-value) = classify(@hand1);
my ($hand2-description, $hand2-value) = classify(@hand2);
say sprintf q[The first hand is a '%s' and the second one a '%s', so %s.],
$hand1-description, $hand2-description,
$hand1-value > $hand2-value
?? 'the first hand wins'
!! $hand2-value > $hand1-value
?? 'the second hand wins'
!! "the hands are of equal value"; # XXX: probably wrong
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment