Skip to content

Instantly share code, notes, and snippets.

@johnmastro
Last active March 24, 2024 19:13
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save johnmastro/644409b2555e1029f50806c044392b7d to your computer and use it in GitHub Desktop.
Save johnmastro/644409b2555e1029f50806c044392b7d to your computer and use it in GitHub Desktop.
Card and Deck classes in Java (from an assignment in my Java class)
import java.util.Objects;
/**
* Class representing a playing card from a standard 52-card deck.
*/
public class Card
{
/**
* Enum representing playing card suits.
*/
public enum Suit
{
SPADES, HEARTS, DIAMONDS, CLUBS;
}
// The min and max valid card ranks
private static final int MIN_RANK = 1;
private static final int MAX_RANK = 13;
// This instance's rank and suit
private int rank;
private Suit suit;
/**
* Construct a Card with a given rank and suit.
*/
public Card(int rank, Suit suit)
{
setRank(rank);
setSuit(suit);
}
/**
* Return the card's rank.
*/
public int getRank()
{
return rank;
}
/**
* Set the card's rank, with input validation.
*/
public void setRank(int rank)
{
if (rank < MIN_RANK || rank > MAX_RANK)
throw new RuntimeException(
String.format("Invalid rank: %d (must be between %d and %d inclusive)",
rank, MIN_RANK, MAX_RANK));
this.rank = rank;
}
/**
* Return the card's suit.
*/
public Suit getSuit()
{
return suit;
}
/**
* Set the card's suit, with input validation.
*/
public void setSuit(Suit suit)
{
if (suit == null)
throw new RuntimeException("Suit must be non-null");
this.suit = suit;
}
@Override
public String toString()
{
return String.format("%s[rank=%d, suit=%s]",
getClass().getSimpleName(),
getRank(),
getSuit().name());
}
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof Card))
return false;
if (obj == this)
return true;
Card that = (Card)obj;
return that.getRank() == getRank() && that.getSuit() == getSuit();
}
@Override
public int hashCode()
{
return Objects.hash(getRank(), getSuit());
}
/**
* Return the minimum allowed rank.
*/
public static int getMinRank()
{
return MIN_RANK;
}
/**
* Return the maximum allowed rank.
*/
public static int getMaxRank()
{
return MAX_RANK;
}
/**
* Return an array of the available suits.
*/
public static Suit[] getSuits()
{
return Suit.values();
}
public static void main(String[] args)
{
Card card;
card = new Card(10, Suit.DIAMONDS);
System.out.println("And a ten of diamonds:");
System.out.println("Suit = " + card.getSuit().toString().toLowerCase());
System.out.println("Rank = " + card.getRank());
System.out.println("Hash = " + card.hashCode());
System.out.println();
card = new Card(7, Suit.CLUBS);
System.out.println("And a 7 of clubs:");
System.out.println("Suit = " + card.getSuit().toString().toLowerCase());
System.out.println("Rank = " + card.getRank());
System.out.println("Hash = " + card.hashCode());
}
}
import java.util.Iterator;
import java.util.Random;
import java.util.NoSuchElementException;
/**
* Class representing a deck of cards.
*/
class Deck implements Iterable<Card>
{
private final Card[] cards;
private int top;
/**
* Construct a deck. The cards will start out in an unspecified but
* deterministic order - you must call shuffle() yourself.
*/
public Deck()
{
cards = new Card[Card.getSuits().length * (Card.getMaxRank() - Card.getMinRank() + 1)];
refresh();
}
/**
* Repopulate the deck with a full set of cards.
*/
public void refresh()
{
Card.Suit[] suits = Card.getSuits();
int min_rank = Card.getMinRank();
int max_rank = Card.getMaxRank();
int i = 0;
for (Card.Suit suit : suits)
for (int rank = min_rank; rank <= max_rank; rank++)
cards[i++] = new Card(rank, suit);
top = cards.length - 1;
assert cards[top] != null;
}
/**
* Shuffle the deck, leaving the cards in a random order.
*/
public void shuffle()
{
// Collections.shuffle(Arrays.asArray(cards));
Random rng = new Random();
for (int i = cards.length - 1; i > 0; i--) {
// Swap the i-th card with a random one
int j = rng.nextInt(i + 1);
Card tmp = cards[j];
cards[j] = cards[i];
cards[i] = tmp;
}
}
/**
* Return true if the deck is empty.
*/
public boolean empty()
{
return top < 0;
}
/**
* Take a card from the deck and return it.
*/
public Card takeCard()
{
if (empty())
throw new IllegalStateException("Can't deal from an empty deck.");
return cards[top--];
}
/**
* Print the current state of the deck.
*/
public void print()
{
if (empty()) {
System.out.println("The deck is empty.");
return;
}
System.out.println("The current deck:");
for (Card card : this)
System.out.println(" " + card);
}
/**
* Return an iterator of the deck's cards.
*
* The behavior is unspecified if you modify the deck (including taking a
* card) during the lifetime of an iterator.
*/
public Iterator<Card> iterator()
{
return new Iterator<Card>()
{
private int cursor = top;
public boolean hasNext()
{
return cursor >= 0;
}
public Card next()
{
if (hasNext())
return cards[cursor--];
throw new NoSuchElementException();
}
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args)
{
Deck deck = new Deck();
System.out.println("Before shuffling:");
deck.print();
System.out.println();
System.out.println("After shuffling:");
deck.shuffle();
deck.print();
System.out.println();
System.out.println("After dealing every card:");
for (int i = 0; i < 52; i++)
deck.takeCard();
deck.print();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment