mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-07-09 13:27:45 +00:00
feat(DevWeb): Le game fonctionne (avec beeaucoup de chance)
This commit is contained in:
@@ -42,6 +42,9 @@ public class Game implements Serializable {
|
|||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private BigDecimal id;
|
private BigDecimal id;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private int currentRound = 0;
|
||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@Column(name = "created_at")
|
@Column(name = "created_at")
|
||||||
private Date createdAt;
|
private Date createdAt;
|
||||||
@@ -78,6 +81,9 @@ public class Game implements Serializable {
|
|||||||
@Transient
|
@Transient
|
||||||
public static final int NB_ROUNDS_MIN = 3;
|
public static final int NB_ROUNDS_MIN = 3;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private GameState gameState = GameState.WAITING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur par défaut
|
||||||
*/
|
*/
|
||||||
@@ -275,6 +281,10 @@ public class Game implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Deck getDeck() {
|
public Deck getDeck() {
|
||||||
|
if (deck == null) {
|
||||||
|
deck = new Deck(nbColors, nbValuesPerColor);
|
||||||
|
deck.shuffle();
|
||||||
|
}
|
||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,5 +349,26 @@ public class Game implements Serializable {
|
|||||||
* Difficulté possible d'une partie
|
* Difficulté possible d'une partie
|
||||||
*/
|
*/
|
||||||
public enum Difficulty {EASY, HARD}
|
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 (currentRound > nbRounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ import jakarta.persistence.JoinColumn;
|
|||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.persistence.Transient;
|
import jakarta.persistence.Transient;
|
||||||
|
import jakarta.websocket.Session;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import uppa.project.json.websocket.ClickChoice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Représentation d'un joueur
|
* Représentation d'un joueur
|
||||||
@@ -60,12 +62,31 @@ public class Player implements Serializable {
|
|||||||
@Transient
|
@Transient
|
||||||
private Deck deck;
|
private Deck deck;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Session session = null;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private ClickChoice currentClick = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur par défaut
|
||||||
*/
|
*/
|
||||||
public Player() {
|
public Player() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Player(Game game, User user, Session session) {
|
||||||
|
this.game = game;
|
||||||
|
this.user = user;
|
||||||
|
this.session = session;
|
||||||
|
this.score = 0;
|
||||||
|
this.winner = false;
|
||||||
|
this.clickCount = 0;
|
||||||
|
this.rightClickCount = 0;
|
||||||
|
this.rapidClickCount = 0;
|
||||||
|
this.deck = new Deck(game.getNbColors(), game.getNbValuesPerColor());
|
||||||
|
this.deck.shuffle();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur d'un joueur
|
* Constructeur d'un joueur
|
||||||
*
|
*
|
||||||
@@ -295,4 +316,16 @@ public class Player implements Serializable {
|
|||||||
public BigDecimal getId() {
|
public BigDecimal getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Session getSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClickChoice getCurrentClick() {
|
||||||
|
return currentClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentClick(ClickChoice currentClick) {
|
||||||
|
this.currentClick = currentClick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package uppa.project.json.websocket;
|
||||||
|
|
||||||
|
public enum ClickChoice {
|
||||||
|
COLOR_VALUE,
|
||||||
|
COLOR,
|
||||||
|
VALUE,
|
||||||
|
NONE
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package uppa.project.json.websocket;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import uppa.project.database.pojo.Card;
|
||||||
|
import uppa.project.database.pojo.Game;
|
||||||
|
import uppa.project.database.pojo.Player;
|
||||||
|
|
||||||
|
public class SimpleGame {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final ArrayList<SimplePlayer> players;
|
||||||
|
private final Card currentCard;
|
||||||
|
|
||||||
|
public SimpleGame(Game game, ArrayList<Player> playerArrayList) {
|
||||||
|
this.id = game.getId().intValue();
|
||||||
|
this.players = new ArrayList<>();
|
||||||
|
for (Player p : playerArrayList) players.add(new SimplePlayer(p, game.getCurrentRound()));
|
||||||
|
this.currentCard = game.getDeck().getCards().get(game.getCurrentRound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<SimplePlayer> getPlayers() {
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Card getCurrentCard() {
|
||||||
|
return currentCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package uppa.project.json.websocket;
|
||||||
|
|
||||||
|
public class SimpleInvitation {
|
||||||
|
|
||||||
|
private final SimpleUser from;
|
||||||
|
|
||||||
|
private final SimpleUser to;
|
||||||
|
|
||||||
|
private final int game_id;
|
||||||
|
|
||||||
|
public SimpleInvitation(SimpleUser from, SimpleUser to, int game_id) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.game_id = game_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleUser getFrom() {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleUser getTo() {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGameId() {
|
||||||
|
return game_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package uppa.project.json.websocket;
|
||||||
|
|
||||||
|
import uppa.project.database.pojo.Card;
|
||||||
|
import uppa.project.database.pojo.Player;
|
||||||
|
|
||||||
|
public class SimplePlayer {
|
||||||
|
|
||||||
|
private final SimpleUser user;
|
||||||
|
private final int score;
|
||||||
|
private final boolean winner;
|
||||||
|
private final int clickCount;
|
||||||
|
private final int rightClickCount;
|
||||||
|
private final int rapidClickCount;
|
||||||
|
private final Card currentCard;
|
||||||
|
|
||||||
|
public SimplePlayer(Player player, int currentRound) {
|
||||||
|
this.user = new SimpleUser(player.getUser());
|
||||||
|
this.score = player.getScore();
|
||||||
|
this.winner = player.isWinner();
|
||||||
|
this.clickCount = player.getClickCount();
|
||||||
|
this.rightClickCount = player.getRightClickCount();
|
||||||
|
this.rapidClickCount = player.getRapidClickCount();
|
||||||
|
|
||||||
|
this.currentCard = player.getDeck().getCards().get(currentRound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimplePlayer(Player player) {
|
||||||
|
this.user = new SimpleUser(player.getUser());
|
||||||
|
this.score = player.getScore();
|
||||||
|
this.winner = player.isWinner();
|
||||||
|
this.clickCount = player.getClickCount();
|
||||||
|
this.rightClickCount = player.getRightClickCount();
|
||||||
|
this.rapidClickCount = player.getRapidClickCount();
|
||||||
|
this.currentCard = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Card getCurrentCard() {
|
||||||
|
return currentCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleUser getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWinner() {
|
||||||
|
return winner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClickCount() {
|
||||||
|
return clickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRightClickCount() {
|
||||||
|
return rightClickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRapidClickCount() {
|
||||||
|
return rapidClickCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package uppa.project.json.websocket;
|
||||||
|
|
||||||
|
import uppa.project.database.pojo.User;
|
||||||
|
|
||||||
|
public class SimpleUser {
|
||||||
|
private final int id;
|
||||||
|
private final String username;
|
||||||
|
|
||||||
|
public SimpleUser(User user) {
|
||||||
|
this.id = user.getId().intValue();
|
||||||
|
this.username = user.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package uppa.project.utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import uppa.project.database.dao.DAO;
|
||||||
|
import uppa.project.database.dao.DAOException;
|
||||||
|
import uppa.project.database.dao.jpa.DAO_JPA_Game;
|
||||||
|
import uppa.project.database.pojo.Game;
|
||||||
|
|
||||||
|
public class GameProvider {
|
||||||
|
|
||||||
|
private static DAO<Game> gameDAO;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
gameDAO = new DAO_JPA_Game();
|
||||||
|
} catch (DAOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashMap<Integer, Game> games = new HashMap<>();
|
||||||
|
|
||||||
|
public static Game getGame(int gameId) throws DAOException {
|
||||||
|
if (!games.containsKey(gameId)) {
|
||||||
|
Game game = gameDAO.findById(gameId);
|
||||||
|
games.put(gameId, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (games.get(gameId) == null) {
|
||||||
|
throw new DAOException("Game not found");
|
||||||
|
}
|
||||||
|
return games.get(gameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@ import uppa.project.database.dao.DAOException;
|
|||||||
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||||
import uppa.project.database.pojo.User;
|
import uppa.project.database.pojo.User;
|
||||||
import uppa.project.json.websocket.Message;
|
import uppa.project.json.websocket.Message;
|
||||||
|
import uppa.project.json.websocket.SimpleInvitation;
|
||||||
|
import uppa.project.json.websocket.SimpleUser;
|
||||||
|
|
||||||
@ServerEndpoint(value = "/ws/users/{user_id}")
|
@ServerEndpoint(value = "/ws/users/{user_id}")
|
||||||
public class ConnectedUsersWS {
|
public class ConnectedUsersWS {
|
||||||
@@ -99,7 +101,7 @@ public class ConnectedUsersWS {
|
|||||||
|
|
||||||
// Find session of the user who receive
|
// Find session of the user who receive
|
||||||
for (Session s : users.keySet()) {
|
for (Session s : users.keySet()) {
|
||||||
if (users.get(s).getId().intValue() == invitation.to.id) {
|
if (users.get(s).getId().intValue() == invitation.getTo().getId()) {
|
||||||
try {
|
try {
|
||||||
s.getBasicRemote().sendText(message.toJson());
|
s.getBasicRemote().sendText(message.toJson());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -110,29 +112,4 @@ public class ConnectedUsersWS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SimpleInvitation {
|
|
||||||
|
|
||||||
public SimpleUser from;
|
|
||||||
|
|
||||||
public SimpleUser to;
|
|
||||||
|
|
||||||
public int game_id;
|
|
||||||
|
|
||||||
public SimpleInvitation(SimpleUser from, SimpleUser to, int game_id) {
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
this.game_id = game_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SimpleUser {
|
|
||||||
public int id;
|
|
||||||
public String username;
|
|
||||||
|
|
||||||
public SimpleUser(User user) {
|
|
||||||
this.id = user.getId().intValue();
|
|
||||||
this.username = user.getUsername();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package uppa.project.web.websocket;
|
package uppa.project.web.websocket;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.websocket.OnClose;
|
import jakarta.websocket.OnClose;
|
||||||
import jakarta.websocket.OnError;
|
import jakarta.websocket.OnError;
|
||||||
import jakarta.websocket.OnMessage;
|
import jakarta.websocket.OnMessage;
|
||||||
@@ -9,24 +11,46 @@ import jakarta.websocket.server.PathParam;
|
|||||||
import jakarta.websocket.server.ServerEndpoint;
|
import jakarta.websocket.server.ServerEndpoint;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import uppa.project.database.dao.DAO;
|
||||||
import uppa.project.database.dao.DAOException;
|
import uppa.project.database.dao.DAOException;
|
||||||
|
import uppa.project.database.dao.EntityManagerProvider;
|
||||||
|
import uppa.project.database.dao.jpa.DAO_JPA_User;
|
||||||
|
import uppa.project.database.pojo.Card;
|
||||||
import uppa.project.database.pojo.Game;
|
import uppa.project.database.pojo.Game;
|
||||||
|
import uppa.project.database.pojo.Player;
|
||||||
import uppa.project.database.pojo.User;
|
import uppa.project.database.pojo.User;
|
||||||
|
import uppa.project.json.websocket.ClickChoice;
|
||||||
|
import uppa.project.json.websocket.Message;
|
||||||
|
import uppa.project.json.websocket.SimpleGame;
|
||||||
|
import uppa.project.json.websocket.SimplePlayer;
|
||||||
|
import uppa.project.json.websocket.SimpleUser;
|
||||||
|
import uppa.project.utils.GameProvider;
|
||||||
|
|
||||||
@ServerEndpoint(value = "/ws/game/{game_id}/{user_id}")
|
@ServerEndpoint(value = "/ws/game/{game_id}")
|
||||||
public class GameWS {
|
public class GameWS {
|
||||||
|
|
||||||
public static final HashMap<Session, User> users = new HashMap<>();
|
Gson gson = new Gson();
|
||||||
public static final HashMap<Game, ArrayList<User>> games = new HashMap<>();
|
|
||||||
|
private static final HashMap<Game, ArrayList<Player>> games = new HashMap<>();
|
||||||
|
|
||||||
|
private Game game;
|
||||||
|
private Player player;
|
||||||
|
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session, @PathParam("game_id") String gameId, @PathParam("user_id") String userId) throws DAOException {
|
public void onOpen(Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||||
|
this.game = GameProvider.getGame(Integer.parseInt(gameId));
|
||||||
|
if (!games.containsKey(game)) games.put(game, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClose
|
@OnClose
|
||||||
public void onClose(Session session, @PathParam("game_id") String gameId, @PathParam("user_id") String userId) {
|
public void onClose(Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||||
|
games.get(game).remove(this.player);
|
||||||
|
|
||||||
|
// Broadcast the new player
|
||||||
|
ArrayList<SimplePlayer> simplePlayerList = new ArrayList<>();
|
||||||
|
for (Player player : games.get(game)) simplePlayerList.add(new SimplePlayer(player));
|
||||||
|
|
||||||
|
broadcast(new Message("updatePlayerList", gson.toJson(simplePlayerList)).toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnError
|
@OnError
|
||||||
@@ -35,7 +59,137 @@ public class GameWS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OnMessage
|
@OnMessage
|
||||||
public void onMessage(String message, Session session) {
|
public void onMessage(String rawMessage, Session session, @PathParam("game_id") String gameId) throws DAOException {
|
||||||
// Do nothing
|
DAO<User> userDAO = new DAO_JPA_User();
|
||||||
|
|
||||||
|
Message message = gson.fromJson(rawMessage, Message.class);
|
||||||
|
|
||||||
|
if (message.getType().equals("connection")) {
|
||||||
|
SimpleUser simpleUser = gson.fromJson(message.getData(), SimpleUser.class);
|
||||||
|
|
||||||
|
// find the user
|
||||||
|
User user = userDAO.findById(simpleUser.getId());
|
||||||
|
|
||||||
|
this.player = new Player(game, user, session);
|
||||||
|
games.get(game).add(this.player);
|
||||||
|
|
||||||
|
ArrayList<SimplePlayer> simplePlayerList = new ArrayList<>();
|
||||||
|
for (Player p : games.get(game)) simplePlayerList.add(new SimplePlayer(p));
|
||||||
|
|
||||||
|
// Broadcast the new player
|
||||||
|
broadcast(new Message("updatePlayerList", gson.toJson(simplePlayerList)).toJson());
|
||||||
|
}
|
||||||
|
if (message.getType().equals("start")) {
|
||||||
|
game.setGameState(Game.GameState.STARTED);
|
||||||
|
broadcast(new Message("start", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||||
|
// TODO Start Timer
|
||||||
|
}
|
||||||
|
if (message.getType().equals("click")) {
|
||||||
|
ClickChoice choice = gson.fromJson(message.getData(), ClickChoice.class);
|
||||||
|
|
||||||
|
int playerScore = player.getScore();
|
||||||
|
Card gameCard = game.getDeck().getCards().get(game.getCurrentRound());
|
||||||
|
Card playerCard = player.getDeck().getCards().get(game.getCurrentRound());
|
||||||
|
|
||||||
|
player.setCurrentClick(choice);
|
||||||
|
|
||||||
|
// get the number of players who clicked
|
||||||
|
int gameClickCount = 0;
|
||||||
|
for (Player player : games.get(game)) {
|
||||||
|
if (player.getCurrentClick() != null) gameClickCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click count
|
||||||
|
player.incrementClickCount();
|
||||||
|
|
||||||
|
// Right click count
|
||||||
|
if (gameClickCount == 1) player.incrementRapidClickCount();
|
||||||
|
|
||||||
|
// Check if the player has clicked on the right card
|
||||||
|
switch (choice) {
|
||||||
|
case COLOR_VALUE -> {
|
||||||
|
if (gameCard.getColor().equals(playerCard.getColor()) && gameCard.getValue() == playerCard.getValue()) {
|
||||||
|
player.incrementRightClickCount();
|
||||||
|
player.setScore(playerScore + 2);
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case COLOR -> {
|
||||||
|
if (gameCard.getColor().equals(playerCard.getColor())) {
|
||||||
|
if (gameCard.getValue() != playerCard.getValue()) {
|
||||||
|
player.incrementRightClickCount();
|
||||||
|
player.setScore(playerScore + 2);
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case VALUE -> {
|
||||||
|
if(gameCard.getValue() == playerCard.getValue()) {
|
||||||
|
if (!gameCard.getColor().equals(playerCard.getColor())) {
|
||||||
|
player.incrementRightClickCount();
|
||||||
|
player.setScore(playerScore + 2);
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case NONE -> {
|
||||||
|
if (!gameCard.getColor().equals(playerCard.getColor()) && gameCard.getValue() != playerCard.getValue()) {
|
||||||
|
player.incrementRightClickCount();
|
||||||
|
player.setScore(playerScore + 2);
|
||||||
|
} else {
|
||||||
|
player.setScore(playerScore - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast the player choice with score
|
||||||
|
|
||||||
|
broadcast(new Message("updatePlayer", gson.toJson(new SimplePlayer(player))).toJson());
|
||||||
|
|
||||||
|
System.out.println(gameClickCount + " / " + games.get(game).size());
|
||||||
|
|
||||||
|
// If all players have clicked
|
||||||
|
if (gameClickCount >= games.get(game).size()) {
|
||||||
|
|
||||||
|
// Reset the current click for all players
|
||||||
|
for (Player p : games.get(game)) p.setCurrentClick(null);
|
||||||
|
|
||||||
|
// Check if the game is over
|
||||||
|
if (game.nextRound()) { // TODO: if score is the same add a round
|
||||||
|
broadcast(new Message("nextRound", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||||
|
// TODO Start Timer
|
||||||
|
} else {
|
||||||
|
// TODO: determine the winner
|
||||||
|
|
||||||
|
// Broadcast the end of the game
|
||||||
|
broadcast(new Message("end", gson.toJson(new SimpleGame(game, games.get(game)))).toJson());
|
||||||
|
|
||||||
|
// TODO: persist the game in the database
|
||||||
|
// EntityManager em = EntityManagerProvider.getInstance();
|
||||||
|
// game.setPlayers(games.get(game));
|
||||||
|
//
|
||||||
|
// em.getTransaction().begin();
|
||||||
|
// em.persist(game);
|
||||||
|
// em.getTransaction().commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void broadcast(String message) {
|
||||||
|
for (Player player : games.get(game)) {
|
||||||
|
try {
|
||||||
|
player.getSession().getBasicRemote().sendText(message);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,22 @@
|
|||||||
<layout:base>
|
<layout:base>
|
||||||
|
|
||||||
<component:hero>
|
<component:hero>
|
||||||
<div class="columns">
|
|
||||||
|
<div class="columns" id="gameWaiting">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<component:card title="Liste des joueurs dans la partie">
|
<component:card title="Liste des joueurs dans la partie">
|
||||||
<jsp:attribute name="footer">
|
<jsp:attribute name="footer">
|
||||||
<a data-target="#user-list-modal" class="card-footer-item modal-trigger">Ajouter</a>
|
<a data-target="#user-list-modal" class="card-footer-item modal-trigger">Ajouter</a>
|
||||||
|
<a id="start-game-button" class="is-primary card-footer-item">Démarrer</a>
|
||||||
</jsp:attribute>
|
</jsp:attribute>
|
||||||
|
<jsp:body>
|
||||||
|
<table id="playerList" class="table is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr><td>Joueur</td></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</jsp:body>
|
||||||
</component:card>
|
</component:card>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
@@ -25,6 +35,23 @@
|
|||||||
</component:card>
|
</component:card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="gameStarted" style="display:none;">
|
||||||
|
<div class="columns" id="otherCards"></div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column" id="deck"></div>
|
||||||
|
<div class="column" id="choice">
|
||||||
|
<button class="button" data-value="COLOR_VALUE">Même couleur et valeur</button>
|
||||||
|
<button class="button" data-value="VALUE">Même valeur</button>
|
||||||
|
<button class="button" data-value="COLOR">Même couleur</button>
|
||||||
|
<button class="button" data-value="NONE">Aucun</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column" id="myCard">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</component:hero>
|
</component:hero>
|
||||||
|
|
||||||
<!-- Liste des utilisateurs dans le lobby -->
|
<!-- Liste des utilisateurs dans le lobby -->
|
||||||
@@ -154,4 +181,159 @@
|
|||||||
ws.onClose(() => console.log("Disconnected from the server"));
|
ws.onClose(() => console.log("Disconnected from the server"));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="module" defer>
|
||||||
|
import WebsocketToolkit from "${pageContext.request.contextPath}/static/js/WebsocketToolkit.js";
|
||||||
|
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.pathname = "${pageContext.request.contextPath}/ws/game/${game.id}";
|
||||||
|
url.protocol = "ws:";
|
||||||
|
url.searchParams.delete("id");
|
||||||
|
|
||||||
|
const wsgame = new WebsocketToolkit(url);
|
||||||
|
wsgame.onOpen(() => {
|
||||||
|
console.log("Connected to the server (GameWS)")
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
type: "connection",
|
||||||
|
data: JSON.stringify({
|
||||||
|
id: ${user.id},
|
||||||
|
username: "${user.username}"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
wsgame.ws.send(JSON.stringify(message))
|
||||||
|
});
|
||||||
|
wsgame.onMessage("updatePlayerList", (data) => {
|
||||||
|
players = data;
|
||||||
|
updatePlayerList();
|
||||||
|
});
|
||||||
|
wsgame.onMessage("start", (game) => {
|
||||||
|
currentGame = game;
|
||||||
|
|
||||||
|
document.querySelector('#gameWaiting').style.display = 'none';
|
||||||
|
document.querySelector('#gameStarted').style.display = 'block';
|
||||||
|
|
||||||
|
const deck = document.querySelector('#deck');
|
||||||
|
const choice = document.querySelector('#choice');
|
||||||
|
const myCard = document.querySelector('#myCard');
|
||||||
|
const otherCards = document.querySelector('#otherCards');
|
||||||
|
|
||||||
|
// Choices
|
||||||
|
choice.querySelectorAll('button').forEach(button => {
|
||||||
|
button.addEventListener('click', () => {
|
||||||
|
const message = {
|
||||||
|
type: "click",
|
||||||
|
data: button.dataset.value
|
||||||
|
}
|
||||||
|
wsgame.ws.send(JSON.stringify(message));
|
||||||
|
|
||||||
|
// Disable buttons
|
||||||
|
choice.querySelectorAll('button').forEach(button => button.disabled = true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show other player cards
|
||||||
|
game.players
|
||||||
|
.filter(p => p.user.id !== ${user.id})
|
||||||
|
.forEach(p => {
|
||||||
|
// Create column in OtherCards
|
||||||
|
const column = document.createElement('div');
|
||||||
|
column.classList.add('column');
|
||||||
|
column.id = 'otherCards-' + p.id;
|
||||||
|
|
||||||
|
const cardValue = document.createElement('p');
|
||||||
|
cardValue.textContent = p.currentCard.color + " " + p.currentCard.value;
|
||||||
|
|
||||||
|
column.appendChild(cardValue);
|
||||||
|
otherCards.appendChild(column);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show my card
|
||||||
|
const myCardValue = document.createElement('p');
|
||||||
|
const me = game.players.find(p => p.user.id === ${user.id});
|
||||||
|
myCardValue.textContent = me.currentCard.color + " " + me.currentCard.value;
|
||||||
|
|
||||||
|
myCard.appendChild(myCardValue);
|
||||||
|
|
||||||
|
// Show deck
|
||||||
|
const deckValue = document.createElement('p');
|
||||||
|
deckValue.textContent = game.currentCard.color + " " + game.currentCard.value;
|
||||||
|
deck.appendChild(deckValue);
|
||||||
|
})
|
||||||
|
wsgame.onMessage("updatePlayer", (player) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
wsgame.onMessage("end", (game) => {
|
||||||
|
currentGame = game;
|
||||||
|
|
||||||
|
document.querySelector('#gameWaiting').style.display = 'block';
|
||||||
|
document.querySelector('#gameStarted').style.display = 'none';
|
||||||
|
})
|
||||||
|
wsgame.onMessage("nextRound", (game) => {
|
||||||
|
currentGame = game;
|
||||||
|
|
||||||
|
const deck = document.querySelector('#deck');
|
||||||
|
const choice = document.querySelector('#choice');
|
||||||
|
const myCard = document.querySelector('#myCard');
|
||||||
|
const otherCards = document.querySelector('#otherCards');
|
||||||
|
|
||||||
|
choice.querySelectorAll('button').forEach(button => button.disabled = false);
|
||||||
|
|
||||||
|
// Show other player cards
|
||||||
|
game.players
|
||||||
|
.filter(p => p.user.id !== ${user.id})
|
||||||
|
.forEach(p => {
|
||||||
|
const column = document.querySelector('#otherCards-' + p.id);
|
||||||
|
column.innerHTML = '';
|
||||||
|
|
||||||
|
const cardValue = document.createElement('p');
|
||||||
|
cardValue.textContent = p.currentCard.color + " " + p.currentCard.value;
|
||||||
|
|
||||||
|
column.appendChild(cardValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show my card
|
||||||
|
const myCardValue = document.querySelector('#myCard p');
|
||||||
|
const me = game.players.find(p => p.user.id === ${user.id});
|
||||||
|
myCardValue.textContent = me.currentCard.color + " " + me.currentCard.value;
|
||||||
|
|
||||||
|
// Show deck
|
||||||
|
const deckValue = document.querySelector('#deck p');
|
||||||
|
deckValue.textContent = game.currentCard.color + " " + game.currentCard.value;
|
||||||
|
})
|
||||||
|
wsgame.onError((error) => console.error(error));
|
||||||
|
wsgame.onClose(() => {
|
||||||
|
console.log("Disconnected from the server (GameWS)")
|
||||||
|
});
|
||||||
|
|
||||||
|
// Game
|
||||||
|
let currentGame;
|
||||||
|
|
||||||
|
// Player List
|
||||||
|
let players = [];
|
||||||
|
const playerList = document.querySelector('#playerList tbody');
|
||||||
|
|
||||||
|
function updatePlayerList() {
|
||||||
|
playerList.innerHTML = '';
|
||||||
|
players.forEach(player => {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
const td = document.createElement('td');
|
||||||
|
td.textContent = player.user.username;
|
||||||
|
tr.appendChild(td);
|
||||||
|
playerList.appendChild(tr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Game Button
|
||||||
|
document.querySelector('#start-game-button').addEventListener('click', () => {
|
||||||
|
if (players.length < 2 || players.length > 4) {
|
||||||
|
alert("Il faut entre 2 et 4 joueurs pour démarrer la partie");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = {type: "start", data: ""}
|
||||||
|
wsgame.ws.send(JSON.stringify(message));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
</layout:base>
|
</layout:base>
|
||||||
Reference in New Issue
Block a user