Blackjack

Was looking through old code and found a ‘deck of card’ thing I did once.
To revisit and revise:

I made classes for Deck and Collections. That wasn’t a good idea.
I never will use the Deck-class for anything other than to give a fresh, shuffled deck of cards.

I think this is better:

module Deck
  Suites = 'SDCH'.chars
  Cards = [:A].concat([*2..10]).concat(%i(J Q K))
  Deck = Suites.product(Cards)

  def self.deck = Deck.shuffle
end

class Shoe
  def initialize(decks=1)
    @shoe = [].tap {|ar| decks.times { ar.concat(Deck.deck) } }
  end

  def deal(cards=1)
    abort('Not enough cards') if cards > @shoe.size
    
    # just print it here
    cards.times { p @shoe.pop }   
  end

end

This is good enough for the basics. You can set up a Shoe of decks with:

shoe = Shoe.new(4)
shoe.deal(35)

Add a Player-class. Make them have different modes.. like :auto and :dealer. (set up rule-sets with conditions and moves; fixed rule-set for :dealer)

Make Shoe keep count (lo-hi and true-count).

Insertion of re-shuffle card in the decks and handle re-shuffle.

Get the value of a card. Not sure if the card should be dealt as an array: [:A, 'C']
or a Struct that hold every meta-thing one might need:

like :long_name, :short_name, :value, :is_ace?

Having the values as Symbols and Integers makes it easy to produce value:

def value(card) # assume card comes as :A, 4, 5, :J etc.
  case card
    when Symbol then card == :Ace ? 11 : 10
    else card
  end
end