diff --git a/hand.rb b/hand.rb index 983a77a..70de596 100644 --- a/hand.rb +++ b/hand.rb @@ -1,11 +1,19 @@ require "./card" +require "./hand_ranker" class Hand def initialize(cards) @cards = cards + @rank = HandRanker.new(self).rank end + attr_reader :rank, :cards + def to_s @cards.join("\n") end + + def <=>(other_hand) + rank <=> other_hand.rank + end end diff --git a/hand_classifier.rb b/hand_classifier.rb new file mode 100644 index 0000000..443e8aa --- /dev/null +++ b/hand_classifier.rb @@ -0,0 +1,88 @@ +class HandClassifier + def initialize(hand) + @hand = hand + end + + attr_reader :hand, :rank + + def classify + if straight_flush? + :straight_flush + elsif four_of_a_kind? + :four_of_a_kind + elsif full_house? + :full_house + elsif flush? + :flush + elsif straight? + :straight + elsif three_of_a_kind? + :three_of_a_kind + elsif two_pair? + :two_pair + elsif one_pair? + :one_pair + else + :high_card + end + end + + private + + def straight_flush? + straight? && flush? + end + + def four_of_a_kind? + find_pairings?(4) + end + + def full_house? + grouped_hand = find_matches + full_house = grouped_hand.length == 2 && grouped_hand.any? do |group| + group.length == 2 + end + full_house && grouped_hand.any?{ |group| group.length == 3 } + end + + def flush? + hand.cards.map(&:suit).reduce(true, :==) #i apologize for the accidental obscenity of this code + end + + def straight? + values = hand.cards.map(&:value) + values.sort! + increment = values[0] + match_tracker = true + values.each_with_index do |value, index| + match_tracker = match_tracker && index + increment == value + end + match_tracker + end + + def three_of_a_kind? + find_pairings?(3) + end + + def two_pair? + matches = find_pairings(2) + matches.length == 2 + end + + def one_pair? + find_pairings?(2) + end + + def find_matches + hand.cards.group_by { |card| card.value } + end + + def find_pairings?(length) + find_pairings(length).empty? + end + + def find_pairings(length) + find_matches.select { |number, group| group.length == length } + end +end + diff --git a/hand_ranker.rb b/hand_ranker.rb new file mode 100644 index 0000000..9186015 --- /dev/null +++ b/hand_ranker.rb @@ -0,0 +1,31 @@ +require "./hand_classifier" +class HandRanker + HAND_RANKS = { + straight_flush: 9, + four_of_a_kind: 8, + full_house: 7, + flush: 6, + straight: 5, + three_of_a_kind: 4, + two_pair: 3, + one_pair: 2, + high_card: 1 + } + + def initialize(hand) + @hand = hand + @rank = rank_hand + end + + attr_reader :hand, :rank + + def <=>(other_hand) + rank <=> other_hand.rank + end + + private + + def rank_hand + HAND_RANKS[HandClassifier.new(hand).classify] + end +end diff --git a/poker.rb b/poker.rb index dccad4b..8e998b2 100644 --- a/poker.rb +++ b/poker.rb @@ -18,13 +18,16 @@ def deal_hands end def display_hands + puts "Hands ranked highest to lowest" + @hands.sort!.reverse! @hands.each_with_index do |hand, index| puts "Player #{index + 1}:" puts hand + puts hand.rank puts end end end -poker = Poker.new(4) +poker = Poker.new(6) poker.play