Last active
September 1, 2016 03:29
-
-
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
This file contains 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
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