Commit 3399bc9b authored by Corentin Guillevic's avatar Corentin Guillevic
Browse files

Add class User (to store adress, port and name of users in a room and to allow...

Add class User (to store adress, port and name of users in a room and to allow to call methods of PlayerService) ; Refactoring of Game
parent b3ee4b96
......@@ -9,8 +9,11 @@ struct JoinRequest {
1: string name
}
struct TPlayerId {
1: string token
struct TPlayer {
1: string token,
2: string name,
3: string adress,
4: i32 port
}
struct TRoomId {
......@@ -30,27 +33,27 @@ struct TColor {
service GameService {
TRoomId createRoom(TPlayerId playerId) throws (1:common.InvalidOperationException e)
TRoomId createRoom(TPlayer player) throws (1:common.InvalidOperationException e)
common.Response sendStartGame(TPlayerId playerId, i32 creatureId, TBoard board, TColor color, list<common.TCard> placeCards)
common.Response sendStartGame(TPlayer player, i32 creatureId, TBoard board, TColor color, list<common.TCard> placeCards)
common.Response joinRoom(TPlayerId playerId, TRoomId roomId)
common.Response joinRoom(TPlayer player, TRoomId roomId)
common.Response getGameDescription(TPlayerId playerId)
common.Response getGameDescription(TPlayer player)
common.Response waitStartPhase(TPlayerId playerId, common.TPhaseId phaseId)
common.Response waitStartPhase(TPlayer player, common.TPhaseId phaseId)
common.Response sendFinishPhase(TPlayerId playerId, common.TPhaseId phaseId)
common.Response sendFinishPhase(TPlayer player, common.TPhaseId phaseId)
common.Response sendPlayCards(TPlayerId playerId, list<common.TCard> playerCards)
common.Response sendPlayCards(TPlayer player, list<common.TCard> playerCards)
common.Response sendPlaceJetons(TPlayerId playerId, list<common.TPlacedJeton> placedJetons)
common.Response sendPlaceJetons(TPlayer player, list<common.TPlacedJeton> placedJetons)
common.Response sendResist(TPlayerId playerId, i32 number)
common.Response sendResist(TPlayer player, i32 number)
common.Response sendGiveUp(TPlayerId playerId)
common.Response sendGiveUp(TPlayer player)
//Is usefull ?
common.Response sendChooseAction(TPlayerId playerId, common.TAction action)
common.Response sendChooseAction(TPlayer player, common.TAction action)
}
......@@ -2,6 +2,7 @@ package fr.univnantes.alma.common;
import fr.univnantes.alma.server.game.item.board.Board;
import fr.univnantes.alma.server.game.item.planet.Planet;
import fr.univnantes.alma.server.user.User;
import fr.univnantes.alma.thrift.InvalidOperationException;
import fr.univnantes.alma.thrift.Response;
......@@ -9,27 +10,27 @@ public interface RoomService {
/**
* Create a room if the player is not already in a room
* @param playerId The id of the game creator
* @param user The player
* @return The game id
*/
String createRoom(String playerId) throws InvalidOperationException;
String createRoom(User user) throws InvalidOperationException;
/**
* Join the room if it's not full and if the player is not in a room
* @param playerId The id of player
* @param user The player
* @param roomId The room id
* @return A response
*/
Response joinRoom(String playerId, String roomId);
Response joinRoom(User user, String roomId);
/**
* Start the game where the player is the game creator
* @param playerId The id of the game creator
* @param user The player
* @param creatureId The in game id of the creature
* @param board The board choose to play
* @param planet The planet used to play
* @return A response
*/
Response startGame(String playerId, int creatureId, Board board, Planet planet);
Response startGame(User user, int creatureId, Board board, Planet planet);
}
package fr.univnantes.alma.server.game;
import fr.univnantes.alma.data.DatabaseFactory;
import fr.univnantes.alma.common.NotAloneDatabase;
import fr.univnantes.alma.data.DatabaseFactory;
import fr.univnantes.alma.server.game.item.Phase;
import fr.univnantes.alma.server.game.item.Reserve;
import fr.univnantes.alma.server.game.item.action.*;
......@@ -20,9 +20,8 @@ import fr.univnantes.alma.server.game.item.power.PowerType;
import fr.univnantes.alma.server.game.item.power.modifier.PowerModifier;
import fr.univnantes.alma.server.game.item.power.modifier.PowerModifierType;
import fr.univnantes.alma.server.game.item.power.recurrent.PowerRecurrent;
import fr.univnantes.alma.server.game.utilitary.Conversion;
import fr.univnantes.alma.server.game.utilitary.Pair;
import fr.univnantes.alma.server.handler.PlayerServiceHandler;
import fr.univnantes.alma.server.user.User;
import fr.univnantes.alma.thrift.Response;
import fr.univnantes.alma.thrift.TAskAction;
import fr.univnantes.alma.thrift.TPair;
......@@ -39,11 +38,6 @@ import static fr.univnantes.alma.server.game.item.player.PlayerTeam.CREATURE;
import static fr.univnantes.alma.server.game.item.player.PlayerTeam.TRAQUE;
public class Game implements GameInterface {
/**
* The powers activate in the current round
*/
private List<Power> currentActivatePowers;
/**
* The powers of the next round
*/
......@@ -109,41 +103,40 @@ public class Game implements GameInterface {
*/
private GameRoundVariables gameRoundVariables;
//TODO Maybe change this
/**
* The game client handler
*/
private PlayerServiceHandler playerServiceHandler;
public Game(int playerNumber, int creatureId, Planet planet, Board board, Room room) {
this.playerServiceHandler = new PlayerServiceHandler();
public Game(List<Pair<Integer, String>> players, int creatureId, Planet planet, Board board, Room room) {
if(players.isEmpty() || players.size() > 7) {
throw new IllegalArgumentException("Need between 1 and 7 players");
}
int playerNumber = players.size();
this.planet = planet;
this.board = board;
this.board.initializeScore(playerNumber);
this.room = room;
this.database = DatabaseFactory.getDatabase();
this.currentActivatePowers = new ArrayList<>();
this.nextRoundPowers = new ArrayList<>();
this.gameRoundVariables = new GameRoundVariables();
initializePlayer(playerNumber, creatureId);
initializePlayer(players, creatureId);
initializeReserve(playerNumber);
initializeSurvivalCardPioche();
initializeTrackingCardPioche();
initializeCardsOfPlayers();
this.state = Phase.PREPHASE_1;
sendFirstRoundStart();
}
public Game(int playerNumber, int creatureId, Planet planet, Board board, Room room, PlayerServiceHandler playerServiceHandler) {
this.playerServiceHandler = playerServiceHandler;
public Game(Collection<Integer> playersId, int creatureId, Planet planet, Board board, Room room) {
if(playersId.isEmpty() || playersId.size() > 7) {
throw new IllegalArgumentException("Need between 1 and 7 players");
}
int playerNumber = playersId.size();
this.planet = planet;
this.board = board;
this.board.initializeScore(playerNumber);
this.room = room;
this.database = DatabaseFactory.getDatabase();
this.currentActivatePowers = new ArrayList<>();
this.nextRoundPowers = new ArrayList<>();
this.gameRoundVariables = new GameRoundVariables();
initializePlayer(playerNumber, creatureId);
initializePlayer(playersId, creatureId);
initializeReserve(playerNumber);
initializeSurvivalCardPioche();
initializeTrackingCardPioche();
......@@ -159,21 +152,42 @@ public class Game implements GameInterface {
/**
* Initialize Creature, Traques and the playerMap
*/
private void initializePlayer(int numberPlayer, int creatureId){
this.traques = new ArrayList<>();
if(creatureId > numberPlayer){
throw new IllegalArgumentException("The in game id of Creature must be valid");
private void initializePlayer(Collection<Integer> playersId, int creatureId){
if(!playersId.contains(creatureId)) {
throw new IllegalArgumentException(creatureId + " doesn't represent a valid in game id");
}
this.traques = new ArrayList<>();
this.playersMap = new HashMap<>();
for(int inGameId = 1 ; inGameId <= numberPlayer ; ++inGameId){
if(inGameId == creatureId){
this.creature = new Creature("Player" + inGameId, inGameId);
this.playersMap.put(inGameId, this.creature);
this.creature = new Creature("Player" + creatureId, creatureId);
this.playersMap.put(creatureId, this.creature);
for(int id : playersId) {
if(id != creatureId) {
Traque traque = new Traque("Player" + id, id);
this.traques.add(traque);
this.playersMap.put(id, traque);
}
else{
Traque traque = new Traque("Player" + inGameId, inGameId);
}
}
/**
* Initialize Creature, Traques and the playerMap
*/
private void initializePlayer(List<Pair<Integer, String>> players, int creatureId){
List<Integer> ids = players.stream().map(Pair::getKey).collect(Collectors.toList());
if(!ids.contains(creatureId)) {
throw new IllegalArgumentException(creatureId + " doesn't represent a valid in game id");
}
this.traques = new ArrayList<>();
this.playersMap = new HashMap<>();
for(Pair<Integer, String> pair : players) {
if(pair.getKey() != creatureId) {
Traque traque = new Traque(pair.getValue(), pair.getKey());
this.traques.add(traque);
this.playersMap.put(inGameId, traque);
this.playersMap.put(pair.getKey(), traque);
}
else {
this.creature = new Creature("Player" + creatureId, creatureId);
this.playersMap.put(creatureId, this.creature);
}
}
}
......@@ -216,14 +230,6 @@ public class Game implements GameInterface {
* Getters
**************************/
public List<Power> getCurrentActivatePowers() {
return currentActivatePowers;
}
public List<Power> getNextRoundPowers() {
return nextRoundPowers;
}
public Planet getPlanet() {
return planet;
}
......@@ -606,9 +612,8 @@ public class Game implements GameInterface {
@Override
public Action askAction(int inGameIdPlayer, TAskAction askedAction) {
//TODO
try{
return Conversion.toAction(playerServiceHandler.askAction(askedAction));
return room.askAction(inGameIdPlayer, askedAction);
}
catch (Exception e){
throw new IllegalArgumentException("Unknown error");
......@@ -622,16 +627,17 @@ public class Game implements GameInterface {
@Override
public void sendFirstRoundStart() {
//TODO
}
@Override
public void sendStartPhase() {
//TODO
}
@Override
public void sendDescription() {
//TODO
if(state.equals(Phase.PHASE_3)) {
//places cards played became visible
}
......@@ -639,7 +645,7 @@ public class Game implements GameInterface {
@Override
public void sendGameIsEnd() {
//TODO
}
/*************************************
......
package fr.univnantes.alma.server.game;
import fr.univnantes.alma.server.game.item.action.Action;
import fr.univnantes.alma.server.game.item.board.Board;
import fr.univnantes.alma.server.game.item.planet.Planet;
import fr.univnantes.alma.server.game.utilitary.Pair;
import fr.univnantes.alma.server.game.utilitary.request.GameJoinRequest;
import fr.univnantes.alma.server.game.utilitary.request.GameRequest;
import fr.univnantes.alma.server.user.User;
import fr.univnantes.alma.thrift.Response;
import fr.univnantes.alma.thrift.TAskAction;
import org.apache.thrift.TException;
import org.atlanmod.commons.log.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static fr.univnantes.alma.server.game.utilitary.Conversion.toAction;
public class Room {
/**
......@@ -40,15 +50,20 @@ public class Room {
private String roomId;
/**
* The id of player who has created the game
* The creator of the the game
*/
private String gameCreatorId;
private User creator;
/**
* Stores the players in game id.
* Stores the players id to their in game id.
*/
private final Map<String, Integer> players;
/**
* Stores the in game id to the user
*/
private final Map<Integer, User> users;
/**
* True if the game is start
*/
......@@ -69,14 +84,16 @@ public class Room {
*/
private Game game;
public Room(String roomId, String gameCreatorId) {
public Room(String roomId, User creator) {
this.requests = new ArrayBlockingQueue<>(MAX_PLAYERS);
this.numberPlayers = new AtomicInteger(1);
this.gameCreatorId = gameCreatorId;
this.creator = creator;
this.roomId = roomId;
this.players = new HashMap<>();
this.players.put(gameCreatorId, 1);
this.players.put(creator.getId(), 1);
this.users = new HashMap<>();
this.users.put(1, creator);
this.isStart = false;
this.isClose = false;
this.play = new Thread(this::requestManagement);
......@@ -91,18 +108,18 @@ public class Room {
return numberPlayers;
}
public boolean isCreator(String playerId){
return this.gameCreatorId.equals(playerId);
public boolean isCreator(User user){
return this.creator.equals(user);
}
public Response join(String playerId) {
public Response join(User user) {
int currentNumber = numberPlayers.getAndIncrement();
Response response;
if(isStart){
response = new Response(false, "Game has started");
}
else if(currentNumber + 1 <= MAX_PLAYERS){
if(requests.offer(new GameJoinRequest(playerId, currentNumber+1))){
if(requests.offer(new GameJoinRequest(user, currentNumber+1))){
response = new Response(true, "");
}
else{
......@@ -115,9 +132,9 @@ public class Room {
return response;
}
public Response start(String playerId, int creatureId, Board board, Planet planet) {
public Response start(User user, int creatureId, Board board, Planet planet) {
Response response;
if(!this.gameCreatorId.equals(playerId)) {
if(!isCreator(user)) {
response = new Response(false, "Only the game creator can start the game");
Log.info("1");
}
......@@ -126,7 +143,7 @@ public class Room {
}
else{
isStart = true;
this.game = new Game(players.size(), creatureId, planet, board, this);
this.game = new Game(playersToIdNamePairList(), creatureId, planet, board, this);
response = new Response(true, "");
}
return response;
......@@ -147,14 +164,65 @@ public class Room {
private void handleRequest(GameRequest request) {
switch (request.getType()){
case JOIN:
GameJoinRequest r = (GameJoinRequest) request;
players.put(r.getPlayerId(), r.getId());
GameJoinRequest gameJoinRequest = (GameJoinRequest) request;
int inGameId = gameJoinRequest.getInGameId();
User user = gameJoinRequest.getUser();
players.put(user.getId(), inGameId);
users.put(inGameId, user);
break;
}
}
public Action askAction(int inGameIdPlayer, TAskAction askedAction) throws TException {
User user = inGameIdToUser(inGameIdPlayer);
return toAction(user.askAction(askedAction));
}
public void sendActionWithoutExpectedResponse(int inGameIdPlayer, TAskAction askedAction) throws TException {
User user = inGameIdToUser(inGameIdPlayer);
user.sendActionWithoutExpectedResponse(askedAction);
}
public void sendFirstRoundStart() throws TException {
for(User user : users.values()) {
user.sendFirstRoundStart();
}
}
public void sendStartPhase() {
//TODO
}
public void sendDescription() {
//TODO
}
public void sendGameIsEnd() {
//TODO
}
/****************************
* Auxiliaries methods
***************************/
private User inGameIdToUser(int id) {
User user = users.getOrDefault(id, null);
if(user != null) {
return user;
}
else {
throw new IllegalArgumentException("Invalid in game id");
}
}
private List<Pair<Integer, String>> playersToIdNamePairList() {
return users.keySet().stream()
.map(this::playerToIdNamePair).collect(Collectors.toList());
}
private Pair<Integer, String> playerToIdNamePair(int inGameId) {
String name = users.get(inGameId).getName();
return new Pair<>(inGameId, name);
}
}
package fr.univnantes.alma.server.game;
import fr.univnantes.alma.server.user.User;
import java.util.concurrent.atomic.AtomicInteger;
public class RoomFactory {
......@@ -13,11 +15,11 @@ public class RoomFactory {
/**
* Create a game with unique id
* @param playerId The id of the game creator
* @param user The player
* @return The game
*/
public static Room createRoom(String playerId){
public static Room createRoom(User user){
String roomId = "" + idCounter.getAndIncrement();
return new Room(roomId, playerId);
return new Room(roomId, user);
}
}
......@@ -4,6 +4,7 @@ package fr.univnantes.alma.server.game;
import fr.univnantes.alma.common.RoomService;
import fr.univnantes.alma.server.game.item.board.Board;
import fr.univnantes.alma.server.game.item.planet.Planet;
import fr.univnantes.alma.server.user.User;
import fr.univnantes.alma.thrift.InvalidOperationException;
import fr.univnantes.alma.thrift.Response;
import org.springframework.stereotype.Component;
......@@ -15,40 +16,40 @@ import java.util.Map;
public class RoomServiceController implements RoomService {
private final Map<String, Room> rooms = new HashMap<>();
private final Map<String, String> players = new HashMap<>();
private final Map<User, String> players = new HashMap<>();
@Override
public String createRoom(String playerId) throws InvalidOperationException {
if(players.containsKey(playerId)){
public String createRoom(User user) throws InvalidOperationException {
if(players.containsKey(user)){
throw new InvalidOperationException(300, "Player is already in a room");
}
Room room = RoomFactory.createRoom(playerId);
Room room = RoomFactory.createRoom(user);
String roomId = room.getRoomId();
players.put(playerId, roomId);
players.put(user, roomId);
this.rooms.put(roomId, room);
return roomId;
}
@Override
public Response joinRoom(String playerId, String roomId) {
if(players.containsKey(playerId)){
public Response joinRoom(User user, String roomId) {
if(players.containsKey(user)){
return new Response(false, "Player already in a room");
}
Room room = this.rooms.get(roomId);
Response response = room.join(playerId);
Response response = room.join(user);
if(response.state){
players.put(playerId, roomId);
players.put(user, roomId);
}
return response;
}
@Override
public Response startGame(String playerId, int creatureId, Board board, Planet planet) {
if(! players.containsKey(playerId)){
public Response startGame(User user, int creatureId, Board board, Planet planet) {
if(! players.containsKey(user)){
return new Response(false, "Player is not in a room");
}
Room room = this.rooms.get(players.get(playerId));
return room.start(playerId, creatureId, board, planet);
Room room = this.rooms.get(players.get(user));
return room.start(user, creatureId, board, planet);
}
}
......@@ -11,6 +11,7 @@ import fr.univnantes.alma.server.game.item.card.CardName;
import fr.univnantes.alma.server.game.item.card.PlaceCard;
import fr.univnantes.alma.server.game.item.jeton.*;
import fr.univnantes.alma.server.game.item.planet.Place;
import fr.univnantes.alma.server.user.User;
import fr.univnantes.alma.thrift.*;
import java.util.*;
......@@ -322,4 +323,8 @@ public class Conversion {
return new ActionAssociateCardNamesToPlaces(tAction.getParams());
}
}
public static User toUser(TPlayer tPlayer) {
return new User(tPlayer.getToken(), tPlayer.getName(), tPlayer.getAdress(), tPlayer.getPort());
}
}
package fr.univnantes.alma.server.game.utilitary.request;
import fr.univnantes.alma.server.user.User;
public class GameJoinRequest extends GameRequest {
private String playerId;