Created
October 23, 2020 18:18
-
-
Save sampersand/4df52cf9ccd704f7ddf74ef84a0d32e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A playing card. | |
class Card | |
# All possible suits a card can have | |
SUITS = %w(Clubs Diamonds Hearts Spades).freeze | |
# All possible ranks a card can have | |
RANKS = %w(2 3 4 5 6 7 8 9 10 Jack Queen King Ace).freeze | |
# Allows us to do `some_card.rank` and `some_card.suit` | |
attr_reader :rank, :suit | |
# Returns an `Array` of all 52 cards, in order. | |
# Method declarations that start with `self.` are only callable on the class | |
# itself. In this case, you'd do `Card.full_deck`, not `my_card.full_deck`. | |
def self.full_deck | |
lowest_card = Card.new(RANKS.first, SUITS.first) | |
highest_card = Card.new(RANKS.last, SUITS.last) | |
(lowest_card..highest_card).to_a | |
end | |
# Creates a new `Card` with the given `rank` and `suit`. | |
# An `ArgumentError` is raised of the `rank` or `suit` are not valid. | |
def initialize(rank, suit) | |
raise ArgumentError, "bad rank: #{rank}" unless RANKS.include? rank | |
raise ArgumentError, "bad suit: #{suit}" unless SUITS.include? suit | |
@rank = rank | |
@suit = suit | |
end | |
# Get a human-readable representation of this card. | |
def to_s | |
"#{rank} of #{suit}" | |
end | |
# Get a debugging representation of this card. | |
def inspect | |
"Card(#{rank.inspect}, #{suit.inspect})" | |
end | |
# Two cards are equal if their ranks and suits are. | |
def ==(rhs) | |
rank == rhs.rank && suit == rhs.suit | |
end | |
# A card's larger than another card if its suit is larger or its suit | |
# is equal and its rank is larger. | |
def <=>(rhs) | |
if suit == rhs.suit | |
RANKS.index(rank) <=> RANKS.index(rhs.rank) | |
else | |
SUITS.index(suit) <=> SUITS.index(rhs.suit) | |
end | |
end | |
# Gets the next card, looping back to the start if we're the current highest | |
# card. This could probably be made more efficient, but it's clear enough. | |
def succ | |
if rank == RANKS.last | |
Card.new(RANKS.first, SUITS[SUITS.index(suit) + 1] || SUITS.first) | |
else | |
Card.new(RANKS[RANKS.index(rank) + 1], suit) | |
end | |
end | |
end | |
p Card.full_deck |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👍