Sha256: 6d9aedeef103b4bb639636b7aa4a6c12f709088ceb9262a0707b2cee6059e761

Contents?: true

Size: 1.57 KB

Versions: 1

Compression:

Stored size: 1.57 KB

Contents

# frozen_string_literal: true

module FiftyTwo
  module HasCards
    extend Enumerable
    attr_reader :cards
    delegate :shuffle!, :sort!, :<<, :[], :each, :map, :count, :first, :last, to: :cards

    CardUnavailableError = Class.new(StandardError)

    def initialize(cards = [])
      @cards = cards
    end

    def draw
      cards.shift
    end

    def render
      map(&:render).join(" ")
    end

    def locate(identifier)
      return cards[identifier] if identifier.is_a?(Integer)
      cards.find { |c| c.identifier == identifier.upcase }
    end

    def transfer(cards, destination = nil)
      gather(cards).map { |c| (destination || c.deck) << self.cards.delete(c) }
    end

    %i[rank suit].each do |attribute|
      define_method(attribute.to_s.pluralize) { cards.map { |c| c.send(attribute) }.uniq.sort }
    end

    FiftyTwo::Suit::ALL.each do |suit|
      define_method(suit.name) { select(suit.name) }
    end

    FiftyTwo::Suit::Color::ALL.each do |color|
      define_method(color.name.pluralize) { select(color.name) }
    end

    [*FiftyTwo::Rank::CATEGORIES, :jack, :king, :queen, :ace].each do |category|
      define_method(category.to_s.pluralize) { select(category) }
    end

    private

    def select(identifier)
      self.class.new(cards.select { |c| c.send("#{identifier}?") })
    end

    def gather(cards)
      Array(cards).map do |card|
        card = locate(card) unless card.is_a?(FiftyTwo::Card)
        raise CardUnavailableError if card.nil?
        raise CardUnavailableError unless self.cards.include?(card)
        card
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
fiftytwo-0.0.5 lib/fiftytwo/has_cards.rb