Skip to content

Instantly share code, notes, and snippets.

@luikore
Last active September 1, 2016 03:29
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 luikore/0c99af986ae99d2626e601de6ae1e09a to your computer and use it in GitHub Desktop.
Save luikore/0c99af986ae99d2626e601de6ae1e09a to your computer and use it in GitHub Desktop.
Ruby Solution to Poker Hands Dealer Problem: https://ruby-china.org/topics/30918
PokerHand = Struct.new :player, :cards
class PokerHand
Card = Struct.new :name, :value, :suit
class Card
def initialize name
super name, '23456789TJQKA'.index(name[0]), name[1]
end
def <=> other
value <=> other.value
end
def succ_value
value == 12 ? 0 : value + 1
end
def desc
%w[2 3 4 5 6 7 8 9 Ten Jack Queen King Ace][value]
end
end
def initialize player, cards
super player, cards.split.map {|c| Card.new c }.sort
end
def vs other
%W[
straight_flush
four_of_a_kind
full_house
flush
straight
three_of_a_kind
two_pairs
pair
high
].each do |m|
value = send m
other_value = other.send m
if value or other_value
value&.unshift m
other_value&.unshift m
announce_win *[(value || []), (other_value || [])].sort.reverse
break
end
end
end
def announce_win win_cards, lose_cards
win_cards.zip lose_cards do |c1, c2|
if !c2
puts "#{player} Wins. - with #{c1.gsub '_', ' '}"
return
end
if (c1 <=> c2) == 1
puts "#{player} Wins. - with high card: #{c1.desc}"
return
end
end
puts "Tie"
end
def straight_flush
[cards.max] if flush and straight
end
def four_of_a_kind
k = _largest_kind
k.take 1 if k.size == 4
end
def full_house
k1, k2 = _largest_kind 2
[k1.first, k2.first] if k1.size == 3 and k2.size == 2
end
def flush
high if cards.chunk(&:suit).count == 1
end
def straight
high if cards.chunk_while{|c1, c2| c1.succ_value == c2.value}.count == 1
end
def three_of_a_kind
k = _largest_kind
k.take 1 if k.size == 3
end
def two_pairs
k1, k2 = _largest_kind 2
if k1.size == 2 and k2.size == 2
pair_cards = [k1.first, k2.first]
[pair_cards.max, pair_cards.min, *high]
end
end
def pair
k = _largest_kind
[k.first, *high] if k.size == 2
end
def high
cards.sort_by{|c| -c.value}
end
private def _largest_kind n=1
cards.group_by(&:value).values.max_by n, &:size
end
end
if __FILE__ == $PROGRAM_NAME
PokerHand.new('Black', '2H 3D 5S 9C KD').vs PokerHand.new('White', '2C 3H 4S 8C AH')
PokerHand.new('Black', '2H 4S 4C 2D 4H').vs PokerHand.new('White', '2S 8S AS QS 3S')
PokerHand.new('Black', '2H 3D 5S 9C KD').vs PokerHand.new('White', '2C 3H 4S 8C KH')
PokerHand.new('Black', '2H 3D 5S 9C KD').vs PokerHand.new('White', '2D 3H 5C 9S KH')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment