TuneUp: Poker- Refactoring



The main idea of this refactor involves allowing Hands to sort themselves. At first, the Poker class was doing the work of sorting hands, and after adding a Hand#<=>(other_hand) method, we can simply call Array::sort on a collection of Hands to get the “Best” hands.


Poker#best_hand is SWEET!

I first want to start with the pride and joy of allowing Hands to sort themselves

Before


def best_hand
  best_hands = best_ranked_hands
  highest_card_value = 0
  best_hands.each do |hand|
    high_hand_value = hand.max_card_value
    if high_hand_value > highest_card_value
      highest_card_value = high_hand_value
    end
  end
  best_hands.select { |hand| hand.max_card_value == highest_card_value }
            .map(&:input)
end

After


def best_hand
  best_hand = @hands.sort.last
  @hands.select { |hand| hand.score_vector == best_hand.score_vector }
        .map(&:output_hand)
end

Hand#score_vector


def score_vector
  @score_vector ||= calculate_score_vector
end

def calculate_score_vector
  return 0 unless cards.size == 5
  ranking = CATEGORY_RANKINGS[category]
  [ranking, *sorted_hand]
end

The Spaceship Hand#<=> Operator


def <=>(other_hand)
  score_vector <=> other_hand.score_vector
end

While I was at it, I also refactored a few other things.

The initialize methods.


def initialize(hand_array)
  @hands = array_of_hands(hand_array)
end

def array_of_hands(hand_array)
  temp_hands = []
  hand_array.each do |hand|
    temp_hands << Hand.new(hand)
  end
  temp_hands
end

def initialize(raw_hands)
  @hands = raw_hands.map { |raw_hand| Hand.new(raw_hand) }
end

Cleaning up Hand categories


CATEGORY_RANKINGS = {
  straight_flush:  10,
  four_of_a_kind:  9,
  full_house:      8,
  flush:            7,
  straight:        6,
  three_of_a_kind: 5,
  two_pair:        4,
  one_pair:        3,
  high_card:       2
}.freeze

def calculate_category
  CATEGORY_RANKINGS.each do |category, _rank|
    return category if send("#{category}?")
  end
end

Future refactoring


Conclusion

Welp, that wraps it up for this RoadBytes TuneUp. I hope you had a good time working through this Poker code base. If you worked on this TuneUp yourself, create a repo and you can put a link to it in the comments below.