Skip to main content

What is a Player?

The Player is a core domain aggregate in the Blackjack API that represents a user who can participate in games. Players are automatically created or retrieved when starting a new game, and their statistics are tracked over time.

Player Aggregate Structure

The Player domain model is immutable and contains the following attributes:
package cat.itacademy.s05.t01.blackjack_api.domain.model;

import java.util.Objects;

public final class Player {
    private final PlayerId id;
    private final PlayerName name;
    private final int wins;
    private final int losses;

    public Player(PlayerId id, PlayerName name, int wins, int losses) {
        this.id = Objects.requireNonNull(id, "id");
        this.name = Objects.requireNonNull(name, "name");
        if (wins < 0 || losses < 0) throw new IllegalArgumentException("wins/losses cannot be negative");
        this.wins = wins;
        this.losses = losses;
    }

    public static Player newPlayer(PlayerName name) {
        return new Player(PlayerId.newId(), name, 0, 0);
    }

    public Player rename(PlayerName newName) {
        return new Player(id, newName, wins, losses);
    }

    public Player registerWin() {
        return new Player(id, name, wins + 1, losses);
    }

    public Player registerLoss() {
        return new Player(id, name, wins, losses + 1);
    }

    public int score() { return wins - losses; }
}

Player Attributes

id
PlayerId
required
Unique identifier for the player (UUID format)
name
PlayerName
required
The player’s display name (1-30 characters, trimmed)
wins
int
required
Number of games won by the player (non-negative)
losses
int
required
Number of games lost by the player (non-negative)
score
int
Calculated as wins - losses, used for ranking players

Player Creation

Players are created automatically when you start a new game. The system follows a “find or create” pattern:
  1. When you POST to /game/new with a player name, the system checks if a player with that name already exists
  2. If the player exists, it’s retrieved and used for the game
  3. If not, a new player is created with 0 wins and 0 losses
curl -X POST http://localhost:8080/game/new \
  -H "Content-Type: application/json" \
  -d '{"playerName": "Alice"}'

Player Statistics

Player statistics are automatically updated when games conclude:
  • Wins are incremented when the player beats the dealer
  • Losses are incremented when the dealer wins or the player busts
  • Score is calculated as wins - losses and is used for ranking
Statistics are updated in real-time when a game ends, either through a STAND move or a bust.

Immutability Pattern

The Player aggregate follows an immutable design pattern. Methods like registerWin(), registerLoss(), and rename() return new Player instances rather than modifying the existing one:
// Returns a NEW player instance with updated wins count
public Player registerWin() {
    return new Player(id, name, wins + 1, losses);
}
This approach ensures:
  • Thread safety
  • Predictable behavior
  • Easier debugging and testing
  • Alignment with functional programming principles

Change Player Name

Update a player’s display name

View Rankings

See all players ranked by score

Build docs developers (and LLMs) love