🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉 # cjavdev's solution

## to Poker in the Ruby Track

Published at Mar 10 2019 · 0 comments
Instructions
Test suite
Solution

Pick the best hand(s) from a list of poker hands.

See wikipedia for an overview of poker hands.

For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

``````gem install minitest
``````

If you would like color output, you can `require 'minitest/pride'` in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

``````ruby poker_test.rb
``````

To include color from the command line:

``````ruby -r minitest/pride poker_test.rb
``````

## Source

Inspired by the training course from Udacity. https://www.udacity.com/course/viewer#!/c-cs212/

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### poker_test.rb

``````require 'minitest/autorun'
require_relative 'poker'

class PokerTest < Minitest::Test
def test_one_hand
high_of_jack = %w(4S 5S 7H 8D JC)
game = Poker.new([high_of_jack])
assert_equal [high_of_jack], game.best_hand
end

def test_highest_card
skip
high_of_8 = %w(4S 5H 6S 8D 2H)
high_of_queen = %w(2S 4H 6C 9D QH)
game = Poker.new([high_of_8, high_of_queen])
assert_equal [high_of_queen], game.best_hand
end

def test_highest_card_10
skip
high_of_8 = %w(4D 5S 6S 8D 3C)
high_of_10 = %w(2S 4C 7S 9H 10H)
game = Poker.new([high_of_8, high_of_10])
assert_equal [high_of_10], game.best_hand
end

def test_nothing_vs_one_pair
skip
high_of_king = %w(4S 5H 6C 8D KH)
pair_of_4 = %w(2S 4H 6S 4D JH)
game = Poker.new([high_of_king, pair_of_4])
assert_equal [pair_of_4], game.best_hand
end

def test_two_pair
skip
pair_of_2 = %w(4S 2H 6S 2D JH)
pair_of_4 = %w(2S 4H 6C 4D JD)
game = Poker.new([pair_of_2, pair_of_4])
assert_equal [pair_of_4], game.best_hand
end

def test_one_pair_vs_double_pair
skip
pair_of_8 = %w(2S 8H 6S 8D JH)
fives_and_fours = %w(4S 5H 4C 8C 5C)
game = Poker.new([pair_of_8, fives_and_fours])
assert_equal [fives_and_fours], game.best_hand
end

def test_two_double_pair
skip
eights_and_twos = %w(2S 8H 2D 8D 3H)
fives_and_fours = %w(4S 5H 4C 8S 5D)
game = Poker.new([eights_and_twos, fives_and_fours])
assert_equal [eights_and_twos], game.best_hand
end

def test_another_two_double_pair
skip
aces_and_twos = %w(2S AH 2C AD JH)
queens_and_jacks = %w(JD QH JS 8D QC)
game = Poker.new([aces_and_twos, queens_and_jacks])
assert_equal [aces_and_twos], game.best_hand
end

def test_double_pair_vs_three
skip
eights_and_twos = %w(2S 8H 2H 8D JH)
three_of_4 = %w(4S 5H 4C 8S 4H)
game = Poker.new([eights_and_twos, three_of_4])
assert_equal [three_of_4], game.best_hand
end

def test_two_three
skip
three_twos = %w(2S 2H 2C 8D JH)
three_aces = %w(4S AH AS 8C AD)
game = Poker.new([three_twos, three_aces])
assert_equal [three_aces], game.best_hand
end

def test_three_vs_straight
skip
three_of_4 = %w(4S 5H 4C 8D 4H)
straight = %w(3S 4D 2S 6D 5C)
game = Poker.new([three_of_4, straight])
assert_equal [straight], game.best_hand
end

def test_a_5_high_straight
skip
three_of_4 = %w(4S 5H 4C 8D 4H)
straight_to_5 = %w(4D AH 3S 2D 5C)
game = Poker.new([three_of_4, straight_to_5])
assert_equal [straight_to_5], game.best_hand
end

def test_two_straights
skip
straight_to_8 = %w(4S 6C 7S 8D 5H)
straight_to_9 = %w(5S 7H 8S 9D 6H)
game = Poker.new([straight_to_8, straight_to_9])
assert_equal [straight_to_9], game.best_hand
end

def test_5_high_straight_vs_other_straight
skip
straight_to_jack = %w(8H 7C 10D 9D JH)
straight_to_5 = %w(4S AH 3S 2D 5H)
game = Poker.new([straight_to_jack, straight_to_5])
assert_equal [straight_to_jack], game.best_hand
end

def test_straight_vs_flush
skip
straight_to_8 = %w(4C 6H 7D 8D 5H)
flush_to_7 = %w(2S 4S 5S 6S 7S)
game = Poker.new([straight_to_8, flush_to_7])
assert_equal [flush_to_7], game.best_hand
end

def test_two_flushes
skip
flush_to_8 = %w(3H 6H 7H 8H 5H)
flush_to_7 = %w(2S 4S 5S 6S 7S)
game = Poker.new([flush_to_8, flush_to_7])
assert_equal [flush_to_8], game.best_hand
end

def test_flush_vs_full
skip
flush_to_8 = %w(3H 6H 7H 8H 5C)
full = %w(4S 5H 4C 5D 4H)
game = Poker.new([flush_to_8, full])
assert_equal [full], game.best_hand
end

def test_two_fulls
skip
full_of_4_by_9 = %w(4H 4S 4D 9S 9D)
full_of_5_by_8 = %w(5H 5S 5D 8S 8D)
game = Poker.new([full_of_4_by_9, full_of_5_by_8])
assert_equal [full_of_5_by_8], game.best_hand
end

def test_full_vs_square
skip
full = %w(4S 5H 4D 5D 4H)
square_of_3 = %w(3S 3H 2S 3D 3C)
game = Poker.new([square_of_3, full])
assert_equal [square_of_3], game.best_hand
end

def test_two_square
skip
square_of_2 = %w(2S 2H 2C 8D 2D)
square_of_5 = %w(4S 5H 5S 5D 5C)
game = Poker.new([square_of_2, square_of_5])
assert_equal [square_of_5], game.best_hand
end

def test_square_vs_straight_flush
skip
square_of_5 = %w(4S 5H 5S 5D 5C)
straight_flush_to_10 = %w(7S 8S 9S 6S 10S)
game = Poker.new([square_of_5, straight_flush_to_10])
assert_equal [straight_flush_to_10], game.best_hand
end

def test_two_straight_flushes
skip
straight_flush_to_8 = %w(4H 6H 7H 8H 5H)
straight_flush_to_9 = %w(5S 7S 8S 9S 6S)
game = Poker.new([straight_flush_to_8, straight_flush_to_9])
assert_equal [straight_flush_to_9], game.best_hand
end

def test_highest_card_down_to_fifth_card
skip
high_of_8_low_of_3 = %w(3S 5H 6S 8D 7H)
high_of_8_low_of_2 = %w(2S 5D 6D 8C 7S)
game = Poker.new([high_of_8_low_of_3, high_of_8_low_of_2])
assert_equal [high_of_8_low_of_3], game.best_hand
end

def test_three_hand_with_tie
skip
spade_straight_to_9 = %w(9S 8S 7S 6S 5S)
diamond_straight_to_9 = %w(9D 8D 7D 6D 5D)
three_of_4 = %w(4D 4S 4H QS KS)
game = Poker.new(hands)
end
end``````
``````class Card

def initialize(card)
@value = card[0...-1]
@suit = card[-1]
end

def to_i
return 11 if @value == "J"
return 12 if @value == "Q"
return 13 if @value == "K"
return 14 if @value == "A"
@value.to_i
end

def to_s
"#{ @value }#{ @suit }"
end

def <=>(other)
to_i <=> other.to_i
end
end

class Hand
include Comparable

def initialize(cards)
@cards = cards.map {|c| Card.new(c)}
end

def rank
@compare = @cards.sort.reverse
return 1 if straight? && flush?
if four?
@compare = fours.first | cards
return 2
end
if three? && pairs.length == 1
@compare = threes.first | cards
return 3
end
return 4 if flush?
if straight?
if @compare.first.to_i == 14
@compare.rotate!
end
return 5
end
if three?
@compare = threes.first | cards
return 6
end
if pairs.length == 2
@compare = pairs.last | pairs.first | cards
return 7
end
if pairs.length == 1
@compare = pairs.first | cards.sort.reverse
return 8
end
9
end

def highest_card
@cards.sort.last.to_i
end

def <=>(other)
if rank != other.rank
return rank <=> other.rank
end

c1, c2 = compare, other.compare
while !c1.empty? && c1.first.to_i == c2.first.to_i
c1.shift and c2.shift
end
c2.first <=> c1.first
end

def flush?
@cards.group_by(&:suit).length == 1
end

def four?
fours.length == 1
end

def three?
!threes.empty?
end

def straight?
card_values = @cards.map(&:to_i).sort
return true if card_values == [2, 3, 4, 5, 14]
card_values.each_cons(2).all? { |x, y| x + 1 == y }
end

def fours
cards_by_kind(4)
end

def threes
cards_by_kind(3)
end

def pairs
cards_by_kind(2)
end

def cards_by_kind(n)
@cards
.group_by(&:to_i)
.select {|_, v| v.length == n}
.sort
.map {|_, x| x}
end

def to_s
@cards.map(&:to_s)
end
end

class Poker
def initialize(hands)
@hands = hands.map {|h| Hand.new(h)}
end

def best_hand
best_hands = []
@hands.each do |hand|
if best_hands.empty?
best_hands << hand
elsif hand < best_hands
best_hands = [hand]
elsif hand == best_hands
best_hands << hand
end
end
best_hands.map(&:to_s)
end
end``````