Task

Create a data structure and the associated methods to define and manipulate a deck of   playing cards.

The deck should contain 52 unique cards.

The methods must include the ability to:

   make a new deck
   shuffle (randomize) the deck
   deal from the deck
   print the current contents of a deck 
Each card must have a pip value and a suit value which constitute the unique value of the card.

Related tasks:

 Card shuffles
 Deal cards_for_FreeCell
 War Card_Game
 Poker hand_analyser
 Go Fish


class Card
  # class constants
  SUITS = %i[ Clubs Hearts Spades Diamonds ]
  PIPS  = %i[ 2 3 4 5 6 7 8 9 10 Jack Queen King Ace ]
 
  # class variables (private)
  @@suit_value = Hash[ SUITS.each_with_index.to_a ]
  @@pip_value  = Hash[ PIPS.each_with_index.to_a ]
 
  attr_reader :pip, :suit
 
  def initialize(pip,suit)
    @pip = pip
    @suit = suit
  end
 
  def to_s
    "#{@pip} #{@suit}"
  end
 
  # allow sorting an array of Cards: first by suit, then by value
  def <=>(other)
    (@@suit_value[@suit] <=> @@suit_value[other.suit]).nonzero? or
    @@pip_value[@pip] <=> @@pip_value[other.pip]
  end
end
 
class Deck
  def initialize
    @deck = Card::SUITS.product(Card::PIPS).map{|suit,pip| Card.new(pip,suit)}
  end
 
  def to_s
    @deck.inspect
  end
 
  def shuffle!
    @deck.shuffle!
    self
  end
 
  def deal(*args)
    @deck.shift(*args)
  end
end
 
deck = Deck.new.shuffle!
puts card = deck.deal
hand = deck.deal(5)
puts hand.join(", ")
puts hand.sort.join(", ")