Created
June 10, 2011 06:06
-
-
Save kejadlen/1018310 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env ruby | |
require 'minitest/autorun' | |
module Poker | |
Suits = { 'C' => :club, | |
'D' => :diamond, | |
'H' => :heart, | |
'S' => :spade } | |
Values = Hash['0123456789TJQKA'.chars.map.with_index {|v,i| [v,i] }] | |
class Card | |
attr_reader :value, :suit | |
def initialize(str) | |
@value = Values[str[0]] | |
@suit = Suits[str[1]] | |
end | |
end | |
class Hand | |
include Comparable | |
attr_reader :cards | |
def initialize(str) | |
@cards = str.split(/\s+/).map {|s| Card.new(s) } | |
end | |
def value | |
multiples = @cards.inject(Hash.new(0)) {|n,c| n[c.value] += 1; n } | |
values = multiples.values.sort | |
sorted = multiples.sort_by {|k,v| [v, k] }.reverse | |
rank = sorted.map {|v,_| v } | |
# Now time to actually rank the hand | |
return rank.unshift(8) if straight? and flush? | |
return rank.unshift(7) if values.include?(4) | |
return rank.unshift(6) if values == [2, 3] | |
return rank.unshift(5) if flush? | |
if straight? | |
rank = [5, 4, 3, 2, 14] if rank == [14, 5, 4, 3, 2] | |
return rank.unshift(4) | |
end | |
return rank.unshift(3) if values.include?(3) | |
return rank.unshift(2) if values == [1, 2, 2] | |
return rank.unshift(1) if values.include?(2) | |
return rank.unshift(0) | |
end | |
def pair? | |
end | |
def flush? | |
@cards.map {|c| c.suit }.uniq.length == 1 | |
end | |
def straight? | |
hand = @cards.map {|c| c.value }.sort.uniq | |
# Account for Ace being able to be 1 | |
return true if hand == [2, 3, 4, 5, 14] | |
(hand.length ==5) and (hand.last - hand.first == 4) | |
end | |
def <=>(hand) | |
value <=> hand.value | |
end | |
end | |
end | |
class TestPoker < MiniTest::Unit::TestCase | |
def test_hand | |
h = Poker::Hand.new('5H 5C 6S 7S KD') | |
h = Poker::Hand.new('3D 6D 7D TD QD') | |
assert_equal(true, h.flush?) | |
h = Poker::Hand.new('2H 3D 4H 5D 6H') | |
assert_equal(true, h.straight?) | |
h = Poker::Hand.new('2D 3D 4D 5D 6D') | |
assert_equal(8, h.value[0]) | |
h = Poker::Hand.new('2D 2C 2H 2S 7D') | |
assert_equal(7, h.value[0]) | |
h = Poker::Hand.new('2D 2C 2H 7S 7D') | |
assert_equal(6, h.value[0]) | |
h = Poker::Hand.new('AD 2H 3D 4H 5D') | |
assert_equal([4, 5, 4, 3, 2, 14], h.value) | |
assert_equal(true, h.straight?) | |
end | |
def test_spaceship | |
a = Poker::Hand.new('5H 5C 6S 7S KD') | |
b = Poker::Hand.new('2C 3S 8S 8D TD') | |
assert_equal([1, 5, 13, 7, 6], a.value) | |
assert_equal([1, 8, 10, 3, 2], b.value) | |
assert_operator(b, :>, a) | |
a = Poker::Hand.new('5D 8C 9S JS AC') | |
b = Poker::Hand.new('2C 5C 7D 8S QH') | |
assert_equal([0, 14, 11, 9, 8, 5], a.value) | |
assert_equal([0, 12, 8, 7, 5, 2], b.value) | |
assert_operator(a, :>, b) | |
a = Poker::Hand.new('2D 9C AS AH AC') | |
b = Poker::Hand.new('3D 6D 7D TD QD') | |
assert_equal([3, 14, 9, 2], a.value) | |
assert_equal([5, 12, 10, 7, 6, 3], b.value) | |
assert_operator(a, :<, b) | |
a = Poker::Hand.new('4D 6S 9H QH QC') | |
b = Poker::Hand.new('3D 6D 7H QD QS') | |
assert_equal([1, 12, 9, 6, 4], a.value) | |
assert_equal([1, 12, 7, 6, 3], b.value) | |
assert_operator(a, :>, b) | |
a = Poker::Hand.new('2H 2D 4C 4D 4S') | |
b = Poker::Hand.new('3C 3D 3S 9S 9D') | |
assert_equal([6, 4, 2], a.value) | |
assert_equal([6, 3, 9], b.value) | |
assert_operator(a, :>, b) | |
end | |
end | |
if __FILE__ == $0 | |
wins = 0 | |
File.read('poker.txt').split("\r\n").each do |hands| | |
player_1 = Poker::Hand.new(hands[0..14]) | |
player_2 = Poker::Hand.new(hands[15..29]) | |
wins += 1 if player_1 > player_2 | |
end | |
p wins | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment