Commit b7fb8ca9 authored by Corentin Guillevic's avatar Corentin Guillevic
Browse files

Add several classes and test in server ; Small add in analyse.adoc ; Small...

Add several classes and test in server ; Small add in analyse.adoc ; Small update in composant.adoc ; Upgrade the pom.xml in web
parent b4e77ff5
......@@ -4,7 +4,7 @@ namespace java fr.univnantes.alma.thrift
//Type
struct TEntity{
struct TPlayerTeam{
1: string type
}
......@@ -55,13 +55,13 @@ struct TCreature{
service GameClientService {
bool ping() throws (1:common.InvalidOperationException e)
void sendGameDescription(TEntity entity, THand hand, TScore score, TPlanet planet, list<TCardReserve> reserve, list<TTraque> traquesInformation, TCreature creatureInformation)
void sendGameDescription(TPlayerTeam team, THand hand, TScore score, TPlanet planet, list<TCardReserve> reserve, list<TTraque> traquesInformation, TCreature creatureInformation)
void sendGameStart()
void sendFirstRoundStart()
void sendStartPhase(common.TPhaseId phaseId, TEntity entity, THand hand, TScore score, TPlanet planet, list<TCardReserve> reserve, list<TTraque> traquesInformation, TCreature creatureInformation)
void sendStartPhase(common.TPhaseId phaseId, TPlayerTeam team, THand hand, TScore score, TPlanet planet, list<TCardReserve> reserve, list<TTraque> traquesInformation, TCreature creatureInformation)
}
......
......@@ -37,13 +37,13 @@ service GameServerService {
TGameId createGame(TPlayerId playerId, TBoard board, TColor color, list<common.TCard> placeCards) throws (1:common.InvalidOperationException e)
common.Response sendGameStart(TPlayerId playerId)
common.Response sendStartGame(TPlayerId playerId)
common.Response joinGame(TPlayerId playerId, TGameId gameId)
common.Response getGameDescription(TPlayerId playerId)
common.Response waitStartPhase(TPlayerId playerId, common.TPhaseId phaseId)
common.Response waitStartPhase(TPlayerId playerId, common.TPhaseId phaseId)
common.Response sendFinishPhase(TPlayerId playerId, common.TPhaseId phaseId)
......
......@@ -73,8 +73,7 @@ hide circle
skinparam monochrome true
class Réserve{
piocher() : Carte
remettre(Carte) : void
piocher(Entier) : Carte
}
Réserve o- CarteLieu
......@@ -229,6 +228,67 @@ JetonTraque <|-- JetonCible
JetonTraque <|-- JetonArtemia
....
==== Pouvoir
PouvoirPlayer et PouvoirServer
Pouvoir conteneur : Disjonction ou conjonction
===== Type du pouvoir
- Lieux multiples (2 lieux adjacents)
- Player
- OncePerRound (une fois par tour)
- ColorPower (dépend de la couleur de la partie)
- NextRound
===== Liste de pouvoirs
- Copier le pouvoir d'un lieu
- Copier le pouvoir d'un lieu de votre défausse
- Copier le pouvoir d'un lieu où le jeton Créature se trouve
- Reprendre les cartes Lieu de votre défausse
- Reprendre 1 carte Lieu de la défausse
- Reprendre cette carte Lieu et 1 carte Lieu de votre défausse
- Reprendre ette carte Lieu et 2 carte Lieu de votre défausse (Marais comment appliqué la précision ?)
- Reprendre deux cartes Lieu de votre défausse
- Prendre une carte Lieu de la Réserve
- Perdre 1 Volonté supplémentaire si attraper
- Perdre 1 Volonté supplémentaire JetonCréature
- Perdre 1 Volonté
- Récupérer un Volonté
- Placer le pion Balise sur la Plage OU retirer le pion Balise de la Plage pour avancer le pion Secours d’une case (max 1x/tour)
- Avancer le pion Secours d'1 case (max 1x/tour)
- Piocher 2 cartes Survie, en garder une et défausser l'autre
- Piocher 1 carte Survie
- Annuler les effets du Pion Artemia
- Déplacer 1 Traqué de votre choix sur un Lieu adjacent
- Traqués ne peuvent pas résister
- Défausser une carte Lieu
- Au prochain tour, jouer 2 cartes Lieu. Avant de révéler, en choisir une et reprendre l’autre en main
- Au prochain tour, jouer 2 cartes Lieu. Résoudre les deux Lieu individuellement dans l’ordre de votre choix en respectant les règles de la Phase 3. Lorsqu’un Traqué révèle ses cartes Lieu, s’il peut appliquer les effets de la Rivière et de l’Artefact bleu durant
un même tour, il doit choisir l’un des deux effets, puis il peut reprendre une carte Lieu de sa défausse.
- Utiliser jeton cible (sur un lieu)
- Pouvoir du lieu initulisable
- Lieu inaccessible
- Avancer PionAssimilation d'une case
- Désigner 1 Traqué : si vous l’attrapez avec le jeton Créature, avancez le jeton Assimilation d’1 case supplémentaire.
- Dès que les cartes Lieu sont révélées en Phase 3, reculer le pion Assimilation d'1 case pour déplacer le jeton Créature sur un Lieu adjacent.
- Considérez le jeton Cible comme un second jeton Créature.
- Aucune carte Survie ne peut être jouée ou piochée pour le reste du tour.
- Avant de résoudre les Lieux, déplacer 1 Traqué vers 1 Lieu adjacent.
ARRET A DOMINATION (Carte traque)
==== Système
Représentation du système dans son ensemble.
......
......@@ -4,7 +4,7 @@
=== Types à définir
Entity : Enumeration {Traque, Creature, CarteLieu, CarteSurvie, CarteTraque}
PlayerType : Enumeration {Traque, Creature}
Score : {Int scoreTraque, Int scoreCreature}
......@@ -35,6 +35,8 @@ TraqueInformation : Pseudo, cartes lieu defaussees, carte lieu visible, nombre d
- sendLacherPrise(String playerToken) : Player wants to give up
- sendChooseAction(String playerToken, String idAction) : Player choose an action (activate one power of CarteLieu, recover card, ...)
A RAJOUTER : sendPiocherCard()
=== Server-side
- sendConfirmation() : Send basic confirmation
- sendConfirmation(String data) : Send confirmation with data (json)
......@@ -156,10 +158,10 @@ class "«interface» \n GameService" as si{
}
class "«interface» \n ClientService" as csi{
sendGameDescription(Entity : entity, Hand : hand, Score : score, Planet : planet, Reserve : reserve, TraqueInformation[*] : traqueInformation, CreatureInformation : creatureInformation):Void
sendGameDescription(PlayerTeam : team, Hand : hand, Score : score, Planet : planet, Reserve : reserve, TraqueInformation[*] : traqueInformation, CreatureInformation : creatureInformation):Void
sendGameStart():Void
sendFirstRoundStart():Void
sendStartPhase(PhaseId : phaseId, Entity : entity, Hand : hand, Score : score, Planet : planet, Reserve : reserve, TraqueInformation[*] : traqueInformation, CreatureInformation : creatureInformation):Void
sendStartPhase(PhaseId : phaseId, PlayerTeam : team, Hand : hand, Score : score, Planet : planet, Reserve : reserve, TraqueInformation[*] : traqueInformation, CreatureInformation : creatureInformation):Void
}
....
......
package fr.univnantes.alma.common;
import fr.univnantes.alma.game.item.BoardColor;
import fr.univnantes.alma.game.item.BoardDistribution;
import fr.univnantes.alma.game.item.board.BoardColor;
import fr.univnantes.alma.game.item.board.BoardDistribution;
import fr.univnantes.alma.game.item.card.PlaceCard;
import fr.univnantes.alma.thrift.InvalidOperationException;
......
package fr.univnantes.alma.data;
import fr.univnantes.alma.game.item.Power;
import fr.univnantes.alma.game.item.card.SurvivalCard;
import fr.univnantes.alma.game.item.card.TrackingCard;
import fr.univnantes.alma.game.item.power.container.PowerConjunction;
import fr.univnantes.alma.game.item.power.container.PowerContainer;
import fr.univnantes.alma.game.item.power.type.Power;
import fr.univnantes.alma.game.item.card.PlaceCard;
import javassist.NotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DataCard {
......@@ -13,66 +19,67 @@ public class DataCard {
public static PlaceCard findPlaceCard(String name) throws NotFoundException{
PlaceCard placeCard;
Map<Integer, Power> powerMap;
switch (name) {
case "ANTRE":
powerMap = new HashMap<>();
powerMap.put(1, new Power());
placeCard = new PlaceCard("Antre", "Lorem ipsum", powerMap, 1, "/image.png", "#4466bb");
placeCard = new PlaceCard("Antre", "Lorem ipsum", new PowerContainer(), 1, "/image.png", "#4466bb");
break;
case "NEXUS":
powerMap = new HashMap<>();
powerMap.put(1, new Power());
placeCard = new PlaceCard("Nexus", "Lorem ipsum", powerMap, 1, "/image.png", "#4466bb");
placeCard = new PlaceCard("Nexus", "Lorem ipsum", new PowerContainer(), 1, "/image.png", "#4466bb");
break;
case "JUNGLE":
powerMap = new HashMap<>();
powerMap.put(2, new Power());
placeCard = new PlaceCard("Jungle", "Lorem ipsum", powerMap, 2, "/image.png", "#4466bb");
placeCard = new PlaceCard("Jungle", "Lorem ipsum", new PowerContainer(), 2, "/image.png", "#4466bb");
break;
case "RIVIERE":
powerMap = new HashMap<>();
powerMap.put(3, new Power());
placeCard = new PlaceCard("Rivière", "Lorem ipsum", powerMap, 3, "/image.png", "#4466bb");
placeCard = new PlaceCard("Rivière", "Lorem ipsum", new PowerContainer(), 3, "/image.png", "#4466bb");
break;
case "DOME":
powerMap = new HashMap<>();
powerMap.put(4, new Power());
placeCard = new PlaceCard("Dôme", "Lorem ipsum", powerMap, 4, "/image.png", "#4466bb");
placeCard = new PlaceCard("Dôme", "Lorem ipsum", new PowerContainer(), 4, "/image.png", "#4466bb");
break;
case "PLAGE":
powerMap = new HashMap<>();
powerMap.put(5, new Power());
placeCard = new PlaceCard("Plage", "Lorem ipsum", powerMap, 5, "/image.png", "#4466bb");
placeCard = new PlaceCard("Plage", "Lorem ipsum", new PowerContainer(), 5, "/image.png", "#4466bb");
break;
case "MANGROVE":
powerMap = new HashMap<>();
powerMap.put(6, new Power());
placeCard = new PlaceCard("Mangrove", "Lorem ipsum", powerMap, 6, "/image.png", "#4466bb");
placeCard = new PlaceCard("Mangrove", "Lorem ipsum", new PowerContainer(), 6, "/image.png", "#4466bb");
break;
case "ABRI":
powerMap = new HashMap<>();
powerMap.put(7, new Power());
placeCard = new PlaceCard("Abri", "Lorem ipsum", powerMap, 7, "/image.png", "#4466bb");
placeCard = new PlaceCard("Abri", "Lorem ipsum", new PowerContainer(), 7, "/image.png", "#4466bb");
break;
case "EPAVE":
powerMap = new HashMap<>();
powerMap.put(8, new Power());
placeCard = new PlaceCard("Epave", "Lorem ipsum", powerMap, 8, "/image.png", "#4466bb");
placeCard = new PlaceCard("Epave", "Lorem ipsum", new PowerContainer(), 8, "/image.png", "#4466bb");
break;
case "FUNGI":
powerMap = new HashMap<>();
powerMap.put(9, new Power());
placeCard = new PlaceCard("Fungi", "Lorem ipsum", powerMap, 9, "/image.png", "#4466bb");
placeCard = new PlaceCard("Fungi", "Lorem ipsum", new PowerContainer(), 9, "/image.png", "#4466bb");
break;
case "PORTAIL":
powerMap = new HashMap<>();
powerMap.put(10, new Power());
placeCard = new PlaceCard("Portail", "Lorem ipsum", powerMap, 10, "/image.png", "#4466bb");
placeCard = new PlaceCard("Portail", "Lorem ipsum", new PowerContainer(), 10, "/image.png", "#4466bb");
break;
default:
throw new NotFoundException("This name doesn't correspond to a valid card");
}
return placeCard;
}
public static SurvivalCard findSurvivalCard(String name) throws NotFoundException {
SurvivalCard survivalCard;
switch (name) {
default:
throw new NotFoundException("This name doesn't correspond to a valid card");
}
}
public static TrackingCard findTrackingCard(String name) throws NotFoundException {
TrackingCard trackingCard;
switch (name) {
default:
throw new NotFoundException("This name doesn't correspond to a valid card");
}
}
public static List<SurvivalCard> findAllSurvivalCards(){
return new ArrayList<>();
}
public static List<TrackingCard> findAllTrackingCards(){
return new ArrayList<>();
}
}
package fr.univnantes.alma.game;
import fr.univnantes.alma.common.GameJoinRequest;
import fr.univnantes.alma.game.item.BoardColor;
import fr.univnantes.alma.game.item.BoardDistribution;
import fr.univnantes.alma.game.item.Score;
import fr.univnantes.alma.game.item.Reserve;
import fr.univnantes.alma.game.item.board.Board;
import fr.univnantes.alma.game.item.board.BoardColor;
import fr.univnantes.alma.game.item.board.BoardDistribution;
import fr.univnantes.alma.game.item.board.Score;
import fr.univnantes.alma.game.item.card.PlaceCard;
import fr.univnantes.alma.game.item.card.SurvivalCard;
import fr.univnantes.alma.game.item.card.TrackingCard;
import fr.univnantes.alma.game.item.pioche.Pioche;
import fr.univnantes.alma.game.item.player.Creature;
import fr.univnantes.alma.game.item.player.Player;
import fr.univnantes.alma.game.item.power.container.PowerContainer;
import fr.univnantes.alma.thrift.Response;
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;
......@@ -44,42 +52,43 @@ public class Game {
private String gameId;
private BoardDistribution boardDistribution;
private String gameCreatorId;
private BoardColor boardColor;
private Board board;
private Map<Integer, PlaceCard> placeCards;
private Score score;
private Thread play;
private List<PowerContainer> currentActivatePowers;
/*
public Game(int expectedPlayers) {
this.expectedPlayers = new AtomicInteger(expectedPlayers);
this.requests = new ArrayBlockingQueue<GameJoinRequest>(expectedPlayers);
private Reserve reserve;
play = new Thread(() -> this.start());
play.start();
}
*/
private Pioche<SurvivalCard> survivalCardPioche;
private Pioche<TrackingCard> trackingCardPioche;
private boolean isStart;
private Thread play;
public Game(String gameId, String playerId, BoardDistribution board, BoardColor color, Map<Integer, PlaceCard> placeCards) {
public Game(String gameId, String gameCreatorId, BoardDistribution boardDistribution, BoardColor boardColor, Map<Integer, PlaceCard> placeCards) {
this.requests = new ArrayBlockingQueue<GameJoinRequest>(maxPlayers);
this.players = new HashMap<>();
this.players.put(playerId, new Creature());
this.numberPlayers = new AtomicInteger(1);
this.gameCreatorId = gameCreatorId;
this.players.put(gameCreatorId, new Creature(numberPlayers.get()));
this.board = new Board(boardDistribution, boardColor);
this.gameId = gameId;
this.boardDistribution = board;
this.boardColor = color;
this.placeCards = placeCards;
this.score = new Score();
this.currentActivatePowers = new ArrayList<>();
this.isStart = false;
//TODO add survival and tracking stack ; Reserve
this.play = new Thread(this::start);
initializeSurvivalCardPioche();
initializeTrackingCardPioche();
}
public String getGameId() {
......@@ -94,12 +103,8 @@ public class Game {
return players;
}
public BoardDistribution getBoardDistribution() {
return boardDistribution;
}
public BoardColor getBoardColor() {
return boardColor;
public Board getBoard(){
return board;
}
public Map<Integer, PlaceCard> getPlaceCards() {
......@@ -110,12 +115,35 @@ public class Game {
return score;
}
private void initializeReserve(){
List<PlaceCard> cards = new ArrayList<>();
for(int id = 6 ; id <= 10 ; ++id){
cards.add(placeCards.get(id));
}
reserve = new Reserve(cards, numberPlayers.get());
}
private void initializeSurvivalCardPioche(){
}
private void initializeTrackingCardPioche(){
}
public Response join(GameJoinRequest request) {
int currentNumber = numberPlayers.getAndIncrement();
Response response;
if(currentNumber <= maxPlayers){
requests.offer(request);
response = new Response(true, "");
if(isStart){
response = new Response(false, "Game has started");
}
else if(currentNumber <= maxPlayers){
if(requests.offer(request)){
response = new Response(true, "");
}
else{
response = new Response(false, "Unknown error. Please retry.");
}
}
else{
response = new Response(false, "Game is full");
......@@ -123,7 +151,13 @@ public class Game {
return response;
}
private void start() {
private void startGame(String playerId) {
if(this.gameCreatorId.equals(playerId) && numberPlayers.get() > minPlayers){
isStart = true;
initializeReserve();
board.initializeScore(numberPlayers.get());
//this.play = new Thread(this::start);
}
this.waitForPlayers();
Log.info("We can start !");
......
package fr.univnantes.alma.game;
import fr.univnantes.alma.game.item.BoardColor;
import fr.univnantes.alma.game.item.BoardDistribution;
import fr.univnantes.alma.game.item.board.BoardColor;
import fr.univnantes.alma.game.item.board.BoardDistribution;
import fr.univnantes.alma.game.item.card.PlaceCard;
import java.util.Map;
......
......@@ -3,8 +3,8 @@ package fr.univnantes.alma.game;
import fr.univnantes.alma.common.GameJoinRequest;
import fr.univnantes.alma.common.GameService;
import fr.univnantes.alma.game.item.BoardColor;
import fr.univnantes.alma.game.item.BoardDistribution;
import fr.univnantes.alma.game.item.board.BoardColor;
import fr.univnantes.alma.game.item.board.BoardDistribution;
import fr.univnantes.alma.game.item.card.PlaceCard;
import fr.univnantes.alma.thrift.InvalidOperationException;
import org.springframework.stereotype.Component;
......
package fr.univnantes.alma.game.item;
import fr.univnantes.alma.game.item.card.PlaceCard;
import fr.univnantes.alma.game.item.player.Player;
import fr.univnantes.alma.thrift.Response;
import javafx.util.Pair;
import javassist.NotFoundException;
import java.util.List;
import java.util.Map;
public class Reserve {
private Map<Integer, Pair<PlaceCard, Integer>> placeCards;
public Reserve(List<PlaceCard> cards, int playerNumber) {
if(cards.size() != 5){
throw new IllegalArgumentException("Need 5 cards");
}
for(PlaceCard c : cards){
if((c.getNumber() < 6 && c.getNumber() > 10) || placeCards.containsKey(c.getNumber())){
throw new IllegalArgumentException("Need each number once (6-10)");
}
placeCards.put(c.getNumber(), new Pair<>(c, copiesNumber(playerNumber)));
}
}
private int copiesNumber(int numberPlayer){
if(numberPlayer >= 5){
return 3;
}
else if(numberPlayer >= 3){
return 2;
}
else{
return 1;
}
}
/**
* Test if Reserve contains copies of the PlaceCard
* @param cardNumber The card number
* @return true if there is PlaceCard (cardNumber), false otherwise
*/
public boolean notEmpty(int cardNumber){
if(cardNumber < 6 || cardNumber > 10){
throw new IllegalArgumentException("CardNumber must be between 6 and 10");
}
return placeCards.containsKey(cardNumber) && placeCards.get(cardNumber).getValue() > 0;
}
/**
* Return an exemplar of place card
* @param cardNumber The card number
* @return A PlaceCard
* @throws NotFoundException if the PlaceCard (cardNumber) is empty
*/
public PlaceCard pick(int cardNumber) throws NotFoundException {
if(cardNumber < 6 || cardNumber > 10){
throw new IllegalArgumentException("CardNumber must be between 6 and 10");
}
if(placeCards.get(cardNumber).getValue() == 0){
throw new NotFoundException("CardNumber is empty");
}
else{
return (PlaceCard) placeCards.get(cardNumber).getKey();
}
}
}
package fr.univnantes.alma.game.item;
public class Score {
private int scoreTraque;
private int scoreCreature;
public Score(){
this.scoreCreature = 0;
this.scoreTraque = 0;
}
public int getScoreTraque() {
return scoreTraque;
}
public int getScoreCreature() {
return scoreCreature;
}
}
package fr.univnantes.alma.game.item.board;
import fr.univnantes.alma.game.item.player.Player;
import static fr.univnantes.alma.game.item.player.Player.PlayerTeam;
public class Board {
private Score score;
private BoardDistribution boardDistribution;
private BoardColor boardColor;
public Board(BoardDistribution boardDistribution, BoardColor boardColor){
this.boardColor = boardColor;
this.boardDistribution = boardDistribution;
this.score = new Score();
}
public Board(BoardDistribution boardDistribution, BoardColor boardColor, Score score){
this.boardColor = boardColor;
this.boardDistribution = boardDistribution;
this.score = score;
}
public Score getScore() {
return score;
}
public BoardDistribution getBoardDistribution() {
return boardDistribution;
}
public BoardColor getBoardColor() {
return boardColor;
}