DEV Community

Mohammed mhanna
Mohammed mhanna

Posted on

🃏 A Tiny Card Game in Java

Creating a card game platform in Java is an excellent way to practice object-oriented design, arrays, and algorithmic thinking. Today, we’ll explore a full-featured deck of cards implementation with shuffling, dealing, peeking, and utility methods.

By the end, you’ll understand how to manage a deck programmatically and create a foundation for any card game.


🌱 1️⃣ Representing the Cards

Each card has a face (Ace, Two, …) and a suit (Hearts, Spades, …).

public class Card {
    private final String face;
    private final String suit;

    public Card(String face, String suit) {
        this.face = face;
        this.suit = suit;
    }

    @Override
    public String toString() {
        return face + " of " + suit;
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Using final ensures immutability of each card.
  • The toString() method allows easy printing for display or debugging.

🔄 2️⃣ Creating the Deck

public class DeckOfCards {
    private Card[] deck;
    private int currentCard;
    private static final int NUMBER_OF_CARDS = 52;
    private static final SecureRandom random = new SecureRandom();

    public DeckOfCards() {
        String[] faces = { "Ace", "Deuce", "Three", ..., "King" };
        String[] suits = { "Hearts", "Diamonds", "Clubs", "Spades" };

        deck = new Card[NUMBER_OF_CARDS];
        currentCard = 0;

        for (int i = 0; i < deck.length; i++) {
            deck[i] = new Card(faces[i % 13], suits[i / 13]);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • deck stores all 52 cards.
  • currentCard keeps track of the next card to deal.
  • The constructor populates the deck with all possible face × suit combinations.

🎴 3️⃣ Shuffle and Reshuffle

// Shuffle entire deck
public void shuffle() {
    currentCard = 0;
    for (int i = 0; i < deck.length; i++) {
        int j = random.nextInt(NUMBER_OF_CARDS);
        Card temp = deck[i];
        deck[i] = deck[j];
        deck[j] = temp;
    }
}

// Shuffle only remaining undealt cards
public void reshuffleRemaining() {
    for (int i = currentCard; i < deck.length; i++) {
        int j = currentCard + random.nextInt(deck.length - currentCard);
        Card temp = deck[i];
        deck[i] = deck[j];
        deck[j] = temp;
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • shuffle() randomizes the whole deck and resets currentCard.
  • reshuffleRemaining() only shuffles undealt cards, keeping dealt cards intact.

🃏 4️⃣ Dealing Cards

// Single card
public Card dealCard() {
    if (currentCard < deck.length) return deck[currentCard++];
    return null;
}

// Multiple cards
public Card[] dealCards(int numberOfCards) {
    int remaining = cardsRemaining();
    int cardsToDeal = Math.min(numberOfCards, remaining);
    Card[] hand = new Card[cardsToDeal];
    for (int i = 0; i < cardsToDeal; i++) {
        hand[i] = dealCard();
    }
    return hand;
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • dealCard() returns the next card and advances currentCard.
  • dealCards() safely deals multiple cards, stopping if the deck is empty.

👀 5️⃣ Peeking and Utilities

// Peek at next card
public Card peekNextCard() {
    if (currentCard < deck.length) return deck[currentCard];
    return null;
}

// How many cards are left
public int cardsRemaining() {
    return deck.length - currentCard;
}

// Check if deck is empty
public boolean isEmpty() {
    return currentCard >= deck.length;
}

// Reset deck (order unchanged)
public void reset() {
    currentCard = 0;
}

// Print remaining cards
public void printRemainingCards() {
    for (int i = currentCard; i < deck.length; i++) {
        System.out.println(deck[i]);
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • peekNextCard() allows checking the next card without dealing it.
  • cardsRemaining() and isEmpty() help control game logic.
  • reset() brings the deck back to its starting position.
  • printRemainingCards() lets you display all undealt cards.

🧩 6️⃣ Demo in Action

public class Main {
    public static void main(String[] args) {
        DeckOfCards deck = new DeckOfCards();

        deck.shuffle();

        // Deal 5 cards
        System.out.println("Dealing 5 cards:");
        Card[] hand = deck.dealCards(5);
        for (Card card : hand) System.out.println(card);

        // Peek at next card
        System.out.println("\nNext card (peek): " + deck.peekNextCard());

        // Print remaining cards
        System.out.println("\nRemaining cards in deck:");
        deck.printRemainingCards();

        // Reset deck
        deck.reset();
        System.out.println("\nDeck reset. Cards remaining: " + deck.cardsRemaining());
        System.out.println("Next card after reset: " + deck.peekNextCard());
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation: This main method demonstrates all features: shuffling, dealing, peeking, printing, and resetting.


🌍 7️⃣ Real-World Applications

Learning OOP: Classes, arrays, and methods in practice.

Game development: Base for poker, blackjack, or custom card games.

Simulation & testing: Experiment with algorithms for shuffling and dealing.


🎯 Wrapping Up

With this tiny Java card game platform, you have a complete toolkit: shuffle, deal single/multiple cards, peek, reset, and print remaining cards.

💬Questions:

Which card game would you implement first?

Would you add a discard pile or multiplayer tracking?

What other utility methods would make the deck more flexible?

Drop your thoughts in the comments — let’s share ideas! 🚀

Top comments (2)

Collapse
 
jettoss profile image
Jettoss • Edited

For multiplayer tracking, maybe add a Player class that just holds a hand and score? That way you can scale it out without touching the deck logic too much. @golf hit

Collapse
 
mohamad_mhana profile image
Mohammed mhanna

Appreciate the tip ! Separating players like that will make it way easier to extend the game.