Created
June 29, 2011 23:20
-
-
Save rferraz/1055255 to your computer and use it in GitHub Desktop.
Poker Hands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Card | |
attr_reader :value, :suit | |
def self.parse(str) | |
if str =~ /^([2-9AJQK])([CDHS])$/ | |
self.new($1, $2) | |
end | |
end | |
def initialize(value, suit) | |
@value, @suit = value.to_i, suit | |
end | |
def to_s | |
"#{value}#{suit}" | |
end | |
end | |
def Card(str) | |
Card.parse(str) | |
end | |
class Hand | |
include Enumerable | |
def initialize(c1, c2, c3, c4, c5) | |
@cards = [c1, c2, c3, c4, c5].sort_by { |c| c.value } | |
end | |
def each(&block) | |
@cards.each(&block) | |
end | |
end | |
class HandDetector | |
@@strategies = [] | |
def self.strategy(klass) | |
@@strategies << klass | |
end | |
def self.detect(hand) | |
self.new(hand).detect | |
end | |
def initialize(hand) | |
@hand = hand | |
end | |
def detect | |
rank = nil | |
@@strategies.each do |klass| | |
rank = klass.new(@hand).run | |
break if rank | |
end | |
rank | |
end | |
end | |
module Strategies | |
class Base | |
def self.inherited(subklass) | |
HandDetector.strategy(subklass) | |
end | |
def initialize(hand) | |
@hand = hand | |
end | |
def each_repetition(n) | |
last_card = nil | |
repeat_count = 1 | |
@hand.each do |card| | |
if last_card && last_card.value == card.value | |
repeat_count += 1 | |
yield card if repeat_count == n | |
else | |
repeat_count = 1 | |
end | |
last_card = card | |
end | |
false | |
end | |
end | |
class Straight < Base | |
def run | |
offset = -1 | |
first_value = @hand.first.value | |
:straight if @hand.all? do |card| | |
offset += 1 | |
card.value == first_value + offset | |
end | |
end | |
end | |
class ThreeOfAKind < Base | |
def run | |
each_repetition(3) do |card| | |
return :three_of_a_kind | |
end | |
end | |
end | |
class TwoPairs < Base | |
def run | |
count = 0 | |
each_repetition(2) do |card| | |
count += 1 | |
end | |
return :two_pairs if count == 2 | |
end | |
end | |
class Pair < Base | |
def run | |
each_repetition(2) do |card| | |
return :pair | |
end | |
end | |
end | |
class HighCard < Base | |
def run | |
:high_card | |
end | |
end | |
end | |
require 'test/unit' | |
class PokerTestCase < Test::Unit::TestCase | |
def detect_hand(str) | |
cards = str.split(/\s/).map { |cs| Card(cs) } | |
HandDetector.detect Hand.new(*cards) | |
end | |
def test_that_is_high_card | |
assert_equal :high_card, detect_hand("2H 3D 5S 9C KD") | |
end | |
def test_that_is_pair | |
assert_equal :pair, detect_hand("2H 3D 5S KC KD") | |
end | |
def test_that_is_two_pairs | |
assert_equal :two_pairs, detect_hand("2H 5D 5S KC KD") | |
end | |
def test_that_is_three_of_a_kind | |
assert_equal :three_of_a_kind, detect_hand("2H 3D KS KC KD") | |
end | |
def test_that_is_straight | |
assert_equal :straight, detect_hand("2H 3D 4S 5C 6D") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment