Last active
March 24, 2024 19:13
-
-
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)
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
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()); | |
} | |
} |
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
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