Blackjack Java Game Challenge

Blackjack Java Game Challenge

The Blackjack game written in Java provides a graphical user interface (GUI) for players to enjoy a simplified version of the classic card game. Upon starting the game, players are dealt an initial set of two cards each, and the goal is to build a hand with a total value as close to 21 as possible without exceeding it. The game features a deck of standard playing cards, including numbered cards, face cards (King, Queen, Jack), and Aces, each contributing their respective values to the hand.

Players can interact with the game through three primary buttons: “Hit,” “Stand,” and “New Game.” The “Hit” button allows players to draw additional cards to improve their hand, while the “Stand” button signals the end of the player’s turn, transitioning to the dealer’s turn. The dealer then draws cards until their hand reaches a value of 17 or higher, as per standard Blackjack rules.

The GUI displays the player’s and dealer’s hands, along with their respective total values. Throughout the game, a status message informs players about their current actions, such as whether they’ve busted by exceeding 21 or if they’ve won or lost the round. After each game concludes, players have the option to start a new game by clicking the “New Game” button.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Card {
    private final String suit;
    private final String rank;

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

    public String getSuit() {
        return suit;
    }

    public String getRank() {
        return rank;
    }

    public int getValue() {
        switch (rank) {
            case "Ace":
                return 11;
            case "King":
            case "Queen":
            case "Jack":
                return 10;
            default:
                return Integer.parseInt(rank);
        }
    }

    @Override
    public String toString() {
        return rank + " of " + suit;
    }
}

class Deck {
    private final List<Card> cards;

    public Deck() {
        cards = new ArrayList<>();
        String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
        String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};

        for (String suit : suits) {
            for (String rank : ranks) {
                cards.add(new Card(suit, rank));
            }
        }

        shuffle();
    }

    public void shuffle() {
        Collections.shuffle(cards);
    }

    public Card dealCard() {
        if (cards.isEmpty()) {
            throw new IllegalStateException("Deck is empty");
        }
        return cards.remove(0);
    }
}

class BlackjackHand {
    private final List<Card> cards;

    public BlackjackHand() {
        cards = new ArrayList<>();
    }

    public void addCard(Card card) {
        cards.add(card);
    }

    public int getHandValue() {
        int value = 0;
        int numAces = 0;

        for (Card card : cards) {
            value += card.getValue();
            if (card.getRank().equals("Ace")) {
                numAces++;
            }
        }

        while (numAces > 0 && value > 21) {
            value -= 10;
            numAces--;
        }

        return value;
    }

    public List<Card> getCards() {
        return cards;
    }
}

public class BlackjackGame extends JFrame {

    private final Deck deck;
    private final BlackjackHand playerHand;
    private final BlackjackHand dealerHand;

    private JButton hitButton;
    private JButton standButton;
    private JButton newGameButton;

    private JLabel playerLabel;
    private JLabel dealerLabel;
    private JLabel messageLabel;
    private JLabel turnLabel;

    public BlackjackGame() {
        super("Blackjack Game");

        deck = new Deck();
        playerHand = new BlackjackHand();
        dealerHand = new BlackjackHand();

        initializeUI();
        dealInitialCards();
    }

    private void initializeUI() {
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        playerLabel = new JLabel("Player's Hand: ");
        dealerLabel = new JLabel("Dealer's Hand: ");
        messageLabel = new JLabel(" ");

        hitButton = new JButton("Hit");
        standButton = new JButton("Stand");
        newGameButton = new JButton("New Game");

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(hitButton);
        buttonPanel.add(standButton);
        buttonPanel.add(newGameButton);
        
        JPanel turnPanel = new JPanel();
        turnLabel = new JLabel("Turn: Player"); // Initial turn is for the player
        turnPanel.add(turnLabel);

        add(turnPanel, BorderLayout.WEST); // Add turnPanel to the left side of the frame

        hitButton.addActionListener(e -> handleHit());
        standButton.addActionListener(e -> handleStand());
        newGameButton.addActionListener(e -> handleNewGame());

        add(playerLabel, BorderLayout.NORTH);
        add(dealerLabel, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.PAGE_END);  // Use PAGE_END instead of SOUTH
        add(messageLabel, BorderLayout.SOUTH);  // Move messageLabel to SOUTH

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void dealInitialCards() {
        playerHand.addCard(deck.dealCard());
        dealerHand.addCard(deck.dealCard());
        playerHand.addCard(deck.dealCard());
        dealerHand.addCard(deck.dealCard());

        updateUI();
    }

    private void handleHit() {
        // Player's turn
        playerHand.addCard(deck.dealCard());
        updateUI();

        if (playerHand.getHandValue() > 21) {
            endGame("You've busted! Sorry, you lose.");
        }
    }

    private void handleStand() {
        // Player's turn ends, dealer's turn begins
        turnLabel.setText("Turn: Dealer");

        while (dealerHand.getHandValue() < 17) {
            dealerHand.addCard(deck.dealCard());
        }

        updateUI();
        determineWinner();  // This method should be responsible for checking both player's and dealer's hands
    }

    private void handleNewGame() {
        playerHand.getCards().clear();
        dealerHand.getCards().clear();
        deck.shuffle();

        dealInitialCards();
        messageLabel.setText(" ");

        // Re-enable Hit and Stand buttons
        hitButton.setEnabled(true);
        standButton.setEnabled(true);

        // Reset turn label to "Player"
        turnLabel.setText("Turn: Player");
    }

    private void endGame(String message) {
        updateUI();
        messageLabel.setText(message);
        hitButton.setEnabled(false);
        standButton.setEnabled(false);
    }

    private void updateUI() {
        updateLabel(playerLabel, "Player's Hand: ", playerHand);
        updateLabel(dealerLabel, "Dealer's Hand: ", dealerHand);
    }

    private void updateLabel(JLabel label, String labelText, BlackjackHand hand) {
        StringBuilder builder = new StringBuilder(labelText);
        for (Card card : hand.getCards()) {
            builder.append(card.toString()).append(" | ");
        }
        builder.append("Value: ").append(hand.getHandValue());
        label.setText(builder.toString());
    }
    
    private void determineWinner() {
        // Check both hands and determine the winner
        if (playerHand.getHandValue() > 21) {
            endGame("You've busted! Sorry, you lose.");
        } else if (dealerHand.getHandValue() > 21 || dealerHand.getHandValue() < playerHand.getHandValue()) {
            endGame("You win! Dealer has busted with " + dealerHand.getHandValue() + ".");
        } else if (dealerHand.getHandValue() == playerHand.getHandValue()) {
            endGame("It's a tie! Dealer wins on a tie.");
        } else {
            endGame("Sorry, you lose. Dealer wins with " + dealerHand.getHandValue() + " to " + playerHand.getHandValue() + ".");
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BlackjackGame());
    }
}

 

M. Saqib: Saqib is Master-level Senior Software Engineer with over 14 years of experience in designing and developing large-scale software and web applications. He has more than eight years experience of leading software development teams. Saqib provides consultancy to develop software systems and web services for Fortune 500 companies. He has hands-on experience in C/C++ Java, JavaScript, PHP and .NET Technologies. Saqib owns and write contents on mycplus.com since 2004.
Related Post