Skip to main content
Code Review

Return to Revisions

2 of 4
Grammar

Blackjack implementation - Java

I have inspired from the recent blackjack question here and decide to code for simple blackjack console application Please review and let me know What can improve on the code?

Rules for the application:

  1. There's a single dealer and a player
  2. Initially both get two cards
  3. 2-9 cards have their numerical values that is counted as their score, Face cards have value 10, Ace value changes based on the current score
  4. Then Player asks dealer to hit, as long as Player's score is less than 17
  5. When Player reaches 17 or more then they no longer go for hit
  6. Dealer starts their turn, they go for hit as long as Dealer's score is less than 17
  7. After both are done with their turns, Outcome would be decided
  8. Every action has system out, output will be similar to this

Task :GamePlay.main()
Dealer got 4♣ score: 4 status: HIT
Dealer got K♦ score: 14 status: HIT
Player got A♦ score: 11 status: HIT
Player got J♥ score: 21 status: BLACKJACK
Dealer got 10♠ score: 24 status: BUST
Dealer Bust, Player Wins

class Card

public class Card {
 private Suit suit;
 private Type type;
 public Card(Suit suit, Type type) {
 this.suit = suit;
 this.type = type;
 }
 public Suit getSuit() {
 return suit;
 }
 public Type getType() {
 return type;
 }
 @Override
 public String toString() {
 return this.getType().toString() + this.getSuit().toString();
 }
}

enum Suit

public enum Suit {
 SPADE('♠'), DIAMOND('♦'), CLUB('♣'), HEART('♥');
 private final char symbol;
 Suit(char symbol) {
 this.symbol = symbol;
 }
 @Override
 public String toString() {
 return String.valueOf(this.symbol);
 }
}

enum Type

Type enum constructor takes two parameters, their default value and symbol to represent on output, also the enum has getDefaultValue method

Ace has overriden the method. since it has it's own implementation

import static blackjack.GamePlay.ACE_MAX_VALUE;
public enum Type {
 
 TWO(2, "2"), THREE(3, "3"), FOUR(4, "4"), FIVE(5, "5"),
 SIX(6, "6"), SEVEN(7, "7"), EIGHT(8, "8"), NINE(9, "9"),
 TEN(10, "10"),
 ACE(ACE_MAX_VALUE, "A") {
 @Override
 public int getDefaultValue(int totalValue) {
 if (totalValue + ACE_MAX_VALUE > 21) {
 return 1;
 }
 return ACE_MAX_VALUE;
 }
 },
 JACK(10, "J"), QUEEN(10, "Q"), KING(10, "K");
 
 private int defaultValue;
 private String symbol;
 Type(int defaultValue, String symbol) {
 this.defaultValue = defaultValue;
 this.symbol = symbol;
 }
 public int getDefaultValue(int totalValue) {
 return this.defaultValue;
 }
 @Override
 public String toString() {
 return this.symbol;
 }
}

class Deck

Deck has list of all 52 Cards and loads them into the list on constructor, it has getACard method which removes a card from random index and return a Card object for dealer to draw

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Deck {
 private List<Card> cards;
 public Deck() {
 this.cards = new ArrayList<>();
 loadCards();
 }
 private void loadCards() {
 for (Suit suit : Suit.values()) {
 for (Type type : Type.values()) {
 this.cards.add(new Card(suit, type));
 }
 }
 }
 public Card getACard() {
 int randomIndex = new Random().nextInt(this.cards.size());
 return this.cards.remove(randomIndex);
 }
}

class Dealer

Dealer has the Deck, on constructor it draws two cards and adds to their list of cards and updates their score and status.

It has hit method which draws a Card from the Deck and returns. based on the value of the card their score and status is updated.
play method does the orchestration also prints the state of the Dealer

canHit method checks the status of the Dealer returns true if they're in HIT status

import java.util.ArrayList;
import java.util.List;
import static blackjack.GamePlay.*;
public class Dealer {
 private Deck deck;
 private List<Card> cards;
 private int score;
 private Status status;
 public Dealer(Deck deck) {
 this.cards = new ArrayList<>();
 this.deck = deck;
 for (int i = 0; i < INITIAL_CARDS_COUNT; i++) {
 play();
 }
 }
 public Card hit() {
 return this.deck.getACard();
 }
 public void play() {
 Card card = hit();
 this.score += card.getType().getDefaultValue(this.score);
 this.cards.add(card);
 this.status = Status.getStatus(this.score);
 System.out.printf("Dealer got %s \t score: %d \t status: %s \n", card, this.score,this.status.toString());
 }
 public boolean canHit() {
 return this.status.equals(Status.HIT);
 }
 public Status getStatus() {
 return status;
 }
 public int getScore() {
 return score;
 }
}

class Player

Player has the Dealer, on constructor it draws two cards and adds to their list of cards and updates their score and status.

It has hit method which draws a Card from the Dealer and returns. based on the value of the card their score and status is updated.
play method does the orchestration also prints the state of the Player

canHit method checks the status of the Dealer returns true if they're in HIT status

import java.util.ArrayList;
import java.util.List;
import static blackjack.GamePlay.INITIAL_CARDS_COUNT;
import static blackjack.Status.HIT;
public class Player {
 private List<Card> cards;
 private Dealer dealer;
 private int score;
 private Status status;
 public Player(Dealer dealer) {
 this.cards = new ArrayList<>();
 this.dealer = dealer;
 for (int i = 0; i < INITIAL_CARDS_COUNT; i++) {
 play();
 }
 }
 public void play() {
 Card card = this.dealer.hit();
 this.score += card.getType().getDefaultValue(this.score);
 this.cards.add(card);
 this.status = Status.getStatus(this.score);
 System.out.printf("Player got %s \t score: %d \t status: %s \n", card, this.score,this.status.toString());
 }
 public boolean canHit() {
 return this.status.equals(HIT);
 }
 public Status getStatus() {
 return status;
 }
 public int getScore() {
 return score;
 }
}

enum Status

Status enum has constructor takes two params min and max, this decides which Status any score fall in

getStatus method takes score and return Status based on the score

public enum Status {
 HIT(0, 16), STAND(17, 20), BLACKJACK(21, 21), BUST(22, 100);
 private int min;
 private int max;
 Status(int min, int max) {
 this.min = min;
 this.max = max;
 }
 public static Status getStatus(int score) {
 Status[] statuses = Status.values();
 for (Status status : statuses) {
 if (status.min <= score && status.max >= score) {
 return status;
 }
 }
 return null;
 }
}

class GamePlay

This is orchestrator for the application creates All objects and decides the outcome of the game

public class GamePlay {
 public static final int INITIAL_CARDS_COUNT = 2;
 public static final int ACE_MAX_VALUE = 11;
 public static String getOutcome(Player player, Dealer dealer) {
 if (player.getStatus().equals(Status.BUST)) {
 return "Player Bust, Dealer Wins";
 } else if (player.getScore() == dealer.getScore()) {
 return "Tie";
 } else if (dealer.getStatus().equals(Status.BUST)) {
 return "Dealer Bust, Player Wins";
 } else if (player.getScore() > dealer.getScore()) {
 return "Player Wins";
 }
 return "Dealer Wins";
 }
 public static void main(String[] args) {
 Deck deck = new Deck();
 Dealer dealer = new Dealer(deck);
 Player player = new Player(dealer);
 while (player.canHit()) {
 player.play();
 }
 while (dealer.canHit()) {
 dealer.play();
 }
 System.out.println(getOutcome(player, dealer));
 }
}
lang-java

AltStyle によって変換されたページ (->オリジナル) /