Skip to content

Instantly share code, notes, and snippets.

@kejadlen
Created June 10, 2011 06:06
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 kejadlen/1018310 to your computer and use it in GitHub Desktop.
Save kejadlen/1018310 to your computer and use it in GitHub Desktop.
#!/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