mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-05-13 17:11:49 +00:00
373 lines
10 KiB
Java
373 lines
10 KiB
Java
/*
|
|
* Game.java, 20/03/2024
|
|
* UPPA M1 TI 2023-2024
|
|
* Pas de copyright, aucun droits
|
|
*/
|
|
|
|
package uppa.project.database.pojo;
|
|
|
|
import jakarta.persistence.CascadeType;
|
|
import jakarta.persistence.Column;
|
|
import jakarta.persistence.Entity;
|
|
import jakarta.persistence.EnumType;
|
|
import jakarta.persistence.Enumerated;
|
|
import jakarta.persistence.FetchType;
|
|
import jakarta.persistence.GeneratedValue;
|
|
import jakarta.persistence.GenerationType;
|
|
import jakarta.persistence.Id;
|
|
import jakarta.persistence.OneToMany;
|
|
import jakarta.persistence.Table;
|
|
import jakarta.persistence.Temporal;
|
|
import jakarta.persistence.TemporalType;
|
|
import jakarta.persistence.Transient;
|
|
import java.io.Serializable;
|
|
import java.math.BigDecimal;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Représentation d'une partie de jeu
|
|
*
|
|
* @author Kevin Mitressé
|
|
* @author Lucàs Vabre
|
|
*/
|
|
@Entity
|
|
@Table(name = "game")
|
|
public class Game implements Serializable {
|
|
|
|
@Id
|
|
@Column(name = "id")
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private BigDecimal id;
|
|
|
|
@Transient
|
|
private int currentRound = 0;
|
|
|
|
@Temporal(TemporalType.TIMESTAMP)
|
|
@Column(name = "created_at")
|
|
private Date createdAt;
|
|
|
|
|
|
@Column(name = "difficulty")
|
|
@Enumerated(EnumType.STRING)
|
|
private Difficulty difficulty;
|
|
|
|
@Column(name = "nb_rounds")
|
|
private int nbRounds;
|
|
|
|
@Column(name = "nb_colors")
|
|
private int nbColors;
|
|
|
|
@Column(name = "nb_values_per_color")
|
|
private int nbValuesPerColor;
|
|
|
|
@OneToMany(mappedBy = "game", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
|
private List<Player> players;
|
|
|
|
@Transient
|
|
private Deck deck;
|
|
|
|
@Column(name = "timer")
|
|
private int timer;
|
|
|
|
@Transient
|
|
public static final int TIMER_MIN = 5;
|
|
|
|
@Transient
|
|
public static final int TIMER_MAX = 60;
|
|
|
|
@Transient
|
|
public static final int NB_ROUNDS_MIN = 3;
|
|
|
|
@Transient
|
|
private GameState gameState = GameState.WAITING;
|
|
|
|
/**
|
|
* Constructeur par défaut
|
|
*/
|
|
public Game() {
|
|
this.createdAt = new Date();
|
|
this.players = new ArrayList<>();
|
|
this.timer = 0;
|
|
}
|
|
|
|
/**
|
|
* Constructeur avec la difficulté
|
|
*
|
|
* @param difficulty la difficulté de la partie
|
|
* @see Difficulty
|
|
* @param timer le timer de chaque round en seconde
|
|
* @param nbRounds le nombre de tours de la partie
|
|
* @param nbColors le nombre de couleurs présente dans le deck
|
|
* @param nbValuesPerColor le nombre de valeurs par couleur
|
|
*/
|
|
public Game(Difficulty difficulty, int timer, int nbRounds, int nbColors, int nbValuesPerColor) {
|
|
if (isValidNumberRound(nbRounds, nbColors, nbValuesPerColor)){
|
|
throw new IllegalArgumentException("Le nombre de tours doit être compris entre 2 et " + nbColors * nbValuesPerColor);
|
|
}
|
|
if (timer < TIMER_MIN || timer > TIMER_MAX){
|
|
throw new IllegalArgumentException("Le timer doit être compris entre" + TIMER_MIN + " et " + TIMER_MAX + " secondes");
|
|
}
|
|
this.difficulty = difficulty;
|
|
this.nbRounds = nbRounds;
|
|
this.nbColors = nbColors;
|
|
this.nbValuesPerColor = nbValuesPerColor;
|
|
this.deck = new Deck(nbColors, nbValuesPerColor);
|
|
this.deck.shuffle();
|
|
this.players = new ArrayList<>();
|
|
this.createdAt = new Date();
|
|
this.timer = timer;
|
|
}
|
|
|
|
/**
|
|
* Constructeur d'une partie de jeu
|
|
*
|
|
* @param id l'identifiant de la partie
|
|
* @param createdAt la date de création de la partie
|
|
* @param difficulty la difficulté de la partie
|
|
* @param nbRounds le nombre de tours de la partie
|
|
* @param nbColors le nombre de couleurs présente dans le deck
|
|
* @param nbValuesPerColor le nombre de valeurs par couleur
|
|
* @param players les joueurs de la partie
|
|
*/
|
|
public Game(BigDecimal id, Date createdAt, Difficulty difficulty, int timer ,int nbRounds, int nbColors, int nbValuesPerColor, ArrayList<Player> players) {
|
|
if (isValidNumberRound(nbRounds, nbColors, nbValuesPerColor)){
|
|
throw new IllegalArgumentException("Le nombre de tours doit être compris entre 1 et " + nbColors * nbValuesPerColor);
|
|
}
|
|
if (timer < TIMER_MIN || timer > TIMER_MAX){
|
|
throw new IllegalArgumentException("Le timer doit être compris entre" + TIMER_MIN + " et " + TIMER_MAX + " secondes");
|
|
}
|
|
this.id = id;
|
|
this.createdAt = createdAt;
|
|
this.difficulty = difficulty;
|
|
this.nbRounds = nbRounds;
|
|
this.nbColors = nbColors;
|
|
this.nbValuesPerColor = nbValuesPerColor;
|
|
this.players = players;
|
|
this.deck = new Deck(nbColors, nbValuesPerColor);
|
|
this.timer = timer;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(id, createdAt);
|
|
}
|
|
|
|
/**
|
|
* @return l'identifiant de la partie
|
|
*/
|
|
public BigDecimal getId() {
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* @return la date de création de la partie
|
|
*/
|
|
public Date getCreatedAt() {
|
|
return createdAt;
|
|
}
|
|
|
|
/**
|
|
* @return la difficulté de la partie
|
|
*/
|
|
public Difficulty getDifficulty() {
|
|
return difficulty;
|
|
}
|
|
|
|
/**
|
|
* @param difficulty la nouvelle difficulté de la partie
|
|
* @see Difficulty
|
|
*/
|
|
public void setDifficulty(Difficulty difficulty) {
|
|
this.difficulty = difficulty;
|
|
}
|
|
|
|
/**
|
|
* @return le nombre de tours de la partie
|
|
*/
|
|
public int getNbRounds() {
|
|
return nbRounds;
|
|
}
|
|
|
|
/**
|
|
* @param nbRounds le nouveau nombre de tours de la partie
|
|
*/
|
|
public void setNbRounds(int nbRounds) {
|
|
if (nbRounds < NB_ROUNDS_MIN || nbRounds > nbColors * nbValuesPerColor){
|
|
throw new IllegalArgumentException("Le nombre de tours doit être compris entre " + NB_ROUNDS_MIN + " et " + nbColors * nbValuesPerColor);
|
|
}
|
|
if (nbColors < Deck.NB_COLORS_MIN || nbColors > Deck.NB_COLORS_MAX) {
|
|
throw new IllegalArgumentException("Le nombre de couleurs doit être compris entre" + NB_ROUNDS_MIN + " et " + Deck.NB_COLORS_MAX);
|
|
}
|
|
if (nbValuesPerColor < Deck.NB_VALUES_PER_COLOR_MIN || nbValuesPerColor > Deck.NB_VALUES_PER_COLOR_MAX) {
|
|
throw new IllegalArgumentException("Le nombre de valeurs par couleur doit être compris entre " + Deck.NB_VALUES_PER_COLOR_MIN + " et " + Deck.NB_VALUES_PER_COLOR_MAX);
|
|
}
|
|
this.nbRounds = nbRounds;
|
|
}
|
|
|
|
/**
|
|
* @return le nombre de couleurs présente dans le deck
|
|
*/
|
|
public int getNbColors() {
|
|
return nbColors;
|
|
}
|
|
|
|
/**
|
|
* @param nbColors le nouveau nombre de couleurs présente dans le deck
|
|
*/
|
|
public void setNbColors(int nbColors) {
|
|
if (nbColors < Deck.NB_COLORS_MIN || nbColors > Deck.NB_COLORS_MAX) {
|
|
throw new IllegalArgumentException("Le nombre de couleurs doit être compris entre " + Deck.NB_COLORS_MIN + " et " + Deck.NB_COLORS_MAX);
|
|
}
|
|
this.nbColors = nbColors;
|
|
}
|
|
|
|
/**
|
|
* @return le nombre de valeurs par couleur
|
|
*/
|
|
public int getNbValuesPerColor() {
|
|
return nbValuesPerColor;
|
|
}
|
|
|
|
/**
|
|
* @param nbValuesPerColor le nouveau nombre de valeurs par couleur
|
|
*/
|
|
public void setNbValuesPerColor(int nbValuesPerColor) {
|
|
if (nbValuesPerColor < Deck.NB_VALUES_PER_COLOR_MIN || nbValuesPerColor > Deck.NB_VALUES_PER_COLOR_MAX) {
|
|
throw new IllegalArgumentException("Le nombre de valeurs par couleur doit être compris entre " + Deck.NB_VALUES_PER_COLOR_MIN + " et " + Deck.NB_VALUES_PER_COLOR_MAX);
|
|
}
|
|
this.nbValuesPerColor = nbValuesPerColor;
|
|
}
|
|
|
|
/**
|
|
* @return les joueurs de la partie
|
|
*/
|
|
public List<Player> getPlayers() {
|
|
return players;
|
|
}
|
|
|
|
/**
|
|
* Modifie les joueurs de la partie
|
|
*
|
|
* @param players les nouveaux joueurs
|
|
*/
|
|
public void setPlayers(List<Player> players) {
|
|
this.players = players;
|
|
}
|
|
|
|
/**
|
|
* @return le nombre de joueurs de la partie
|
|
*/
|
|
public int getNbPlayers() {
|
|
return this.players.size();
|
|
}
|
|
|
|
/**
|
|
* Ajoute un joueur à la partie
|
|
*
|
|
* @param player le joueur à ajouter
|
|
*/
|
|
public void addPlayer(Player player) {
|
|
this.players.add(player);
|
|
}
|
|
|
|
public int getTimer() {
|
|
return timer;
|
|
}
|
|
|
|
public void setTimer(int timer) {
|
|
this.timer = timer;
|
|
}
|
|
|
|
public Deck getDeck() {
|
|
if (deck == null) {
|
|
deck = new Deck(nbColors, nbValuesPerColor);
|
|
deck.shuffle();
|
|
}
|
|
return deck;
|
|
}
|
|
|
|
/**
|
|
* Tri des joueurs de la partie par score puis par rapidité
|
|
*/
|
|
public void sortPlayersByScoreAndRapidity() {
|
|
players.sort((p1, p2) -> {
|
|
if (p1.getScore() == p2.getScore()) {
|
|
return p2.getRapidClickCount() - p1.getRapidClickCount();
|
|
}
|
|
return p2.getScore() - p1.getScore();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Récupère le gagnant de la partie
|
|
*
|
|
* @return le nom du gagnant
|
|
*/
|
|
public Player getWinner(){
|
|
this.sortPlayersByScoreAndRapidity();
|
|
return players.get(0);
|
|
}
|
|
|
|
/**
|
|
* Vérifie si le nombre de tours est valide
|
|
*
|
|
* @param nbRounds le nombre de tours
|
|
* @param nbColors le nombre de couleurs
|
|
* @param nbValuesPerColor le nombre de valeurs par couleur
|
|
* @return true si le nombre de tours est valide, false sinon
|
|
*/
|
|
public boolean isValidNumberRound(int nbRounds, int nbColors, int nbValuesPerColor){
|
|
return nbRounds < NB_ROUNDS_MIN || nbRounds > nbColors * nbValuesPerColor;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return String.format("Game{id=%s, createdAt=%s, difficulty=%s, nbRounds=%d, nbColors=%d, nbValuesPerColor=%d}",
|
|
id != null ? id.toString() : "null",
|
|
createdAt != null ? createdAt.toString() : "null",
|
|
difficulty != null ? difficulty.toString() : "null",
|
|
nbRounds != 0 ? nbRounds : 0,
|
|
nbColors != 0 ? nbColors : 0,
|
|
nbValuesPerColor != 0 ? nbValuesPerColor : 0
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) return true;
|
|
if (!(o instanceof Game)) return false;
|
|
Game game = (Game) o;
|
|
return getNbRounds() == game.getNbRounds() && getNbColors() == game.getNbColors() && getNbValuesPerColor() == game.getNbValuesPerColor() && Objects.equals(getId(), game.getId()) && Objects.equals(getCreatedAt(), game.getCreatedAt()) && getDifficulty() == game.getDifficulty() && Objects.equals(getPlayers(), game.getPlayers()) && Objects.equals(getDeck(), game.getDeck());
|
|
}
|
|
|
|
/**
|
|
* Difficulté possible d'une partie
|
|
*/
|
|
public enum Difficulty {EASY, HARD}
|
|
|
|
public enum GameState {WAITING, STARTED, FINISHED}
|
|
|
|
public GameState getGameState() {
|
|
return gameState;
|
|
}
|
|
|
|
public void setGameState(GameState gameState) {
|
|
this.gameState = gameState;
|
|
}
|
|
|
|
public int getCurrentRound() {
|
|
return currentRound;
|
|
}
|
|
|
|
public boolean nextRound() {
|
|
currentRound++;
|
|
|
|
if (currentRound >= nbRounds) gameState = GameState.FINISHED;
|
|
return gameState != GameState.FINISHED;
|
|
}
|
|
}
|
|
|