diff --git a/README.md b/README.md index 7513ae9..33c18e8 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,9 @@ Votes are held in the night for the ghosts to decide who will be next and during * /w _username$message_ - sends a message to the specified user only. * /g - create (&join) a new lobby. * /j _1_ - join lobby 1. To join lobby 2, use /j _2_, etc. -* /l - list all connected clients and all lobbies +* /l - list all connected clients and all lobbies and their status * /p - list all players in your lobby. +* /z - list all games on the server and their status * /e - exit your lobby * /n _name_ - changes player name. If unavailable, it adds a fun and quirky suffix * /q - quit diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java index bcf72a9..bf884c7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java @@ -1,6 +1,9 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; +import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import java.util.Arrays; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** * Data structure that is used to store clientVotes in an array, where the index correponds to the @@ -8,6 +11,8 @@ import java.util.Arrays; */ public class ClientVoteData { + public static final Logger LOGGER = LogManager.getLogger(); + public static final BudaLogConfig l = new BudaLogConfig(LOGGER); private int[] vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE, index corresponds to Passenger position private boolean[] hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false, index corresponds to Passenger position @@ -33,7 +38,14 @@ public class ClientVoteData { * @param vote the vote value */ public void setVote(int position, int vote) { - this.vote[position] = vote; + if (vote == Integer.MAX_VALUE) { + setHasVoted(position, false); + } + try { + this.vote[position] = vote; + } catch (IndexOutOfBoundsException e) { + LOGGER.info("Position is: " + position); + } } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index c29fb1d..214b5f2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -19,9 +19,7 @@ public class Game implements Runnable { /** * Can be extended for optional Game-settings **/ - protected final int nrOfPlayers; //sets the length of the train - protected final int nrOfGhosts; // sets how many Ghosts we start witch - protected int nrOfUsers; // safes how many clients are active in this Game + protected GameState gameState; protected boolean isDay = false; //false means it is night, it is night by default protected VoteHandler voteHandler = new VoteHandler(); @@ -38,36 +36,23 @@ public class Game implements Runnable { */ public Game(int nrOfPlayers, int nrOfGhosts, int nrOfUsers, Lobby lobby) throws TrainOverflow { //ToDo: Who handles Exception how and where - this.nrOfPlayers = nrOfPlayers; - this.nrOfGhosts = nrOfGhosts; - this.nrOfUsers = nrOfUsers; this.gameState = new GameState(nrOfPlayers, nrOfGhosts, nrOfUsers); this.lobby = lobby; nameCounter++; - this.name = "Game-" + nameCounter; + this.name = "Game" + nameCounter; } public GameState getGameState() { return gameState; } - public int getNrOfGhosts() { - return nrOfGhosts; - } - - public int getNrOfPlayers() { - return nrOfPlayers; - } - - public int getNrOfUsers() { - return nrOfUsers; - } - public Lobby getLobby() { return lobby; } - public boolean getIsDay() {return isDay;} + public boolean getIsDay() {return isDay; } + + public String getName() {return name; } public void setDay(boolean day) { isDay = day; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index f386313..600e32b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -76,6 +76,18 @@ public class GameState { return train; } + public int getNrOfUsers() { + return nrOfUsers; + } + + public int getNrOfPlayers() { + return nrOfPlayers; + } + + public int getNrOfGhosts() { + return nrOfGhosts; + } + /** * * diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index ff85517..5c985da 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -11,7 +11,7 @@ import org.apache.logging.log4j.Logger; * vote / ghost vote) and handles votes accordingly. - Sends voting request to passengers that need * to be concerned - collects voting results - calculates who was voted for - decides consequence of * vote: - Is it OG ghost: humans win - Is it last human: ghosts win - Is it just a human: message - * "x is a human" - Is it a peasant ghost -> kickoff + * "x is a human" - Is it a peasant ghost - kickoff * *
(All messages going to Clients are handled via ServerGameInfoHandler)
*
@@ -44,7 +44,7 @@ public class VoteHandler {
* @param passengers: passengers on the train
*/
- public void ghostVote(Passenger[] passengers, Game game) {
+ public String ghostVote(Passenger[] passengers, Game game) {
LOGGER.debug("ghostVote has been called");
LOGGER.info(game.getGameState().toString());
@@ -106,12 +106,23 @@ public class VoteHandler {
n.noiseNotifier(passengers, passengers[i], g, game);
}
}
+ int humanCounter = 0;
+ for(Passenger passenger : passengers) {
+ if(!passenger.getIsGhost()) { //if it is a human
+ humanCounter++;
+ }
+ }
+
+ if (humanCounter == 0) {
+ return ClientGameInfoHandler.gameOverGhostsWin;
+ }
LOGGER.info(game.getGameState().toString());
// set hasVoted to false for all passengers for future votings
for (Passenger passenger : passengers) {
passenger.setHasVoted(false);
}
+ return "";
}
/**
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java
index d4918d7..3ae5858 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java
@@ -43,26 +43,31 @@ public class GhostNPC extends Ghost {
* but only for positions where there aren't any ghosts and sets hasVoted to true
* TODO: Make NPC smarter
*/
- public void vote(Game game){
+ public void vote(Game game) {
int ghostCounter = 0;
Passenger[] train = game.getGameState().getPassengerTrain();
- for(Passenger passenger : train) {
- if(passenger.isGhost) {
+ for (Passenger passenger : train) {
+ if (passenger.isGhost) {
ghostCounter++;
}
}
- int[] humanPositions = new int[game.getNrOfPlayers() - ghostCounter ];
- int j = 0;
- for (int i = 0; i < train.length; i++) {
- if (!train[i].isGhost) { //is human
- humanPositions[j] = train[i].getPosition();
- j++;
+ int[] humanPositions = new int[game.getGameState().getNrOfPlayers() - ghostCounter];
+ if (humanPositions.length == 0) {
+ vote = Integer.MAX_VALUE;
+ } else {
+
+ int j = 0;
+ for (int i = 0; i < train.length; i++) {
+ if (!train[i].isGhost) { //is human
+ humanPositions[j] = train[i].getPosition();
+ j++;
+ }
}
+ int randomPosition = (int) (Math.random() * humanPositions.length);
+ vote = humanPositions[randomPosition];
+ hasVoted = true;
+ LOGGER.info("GhostNPC at Position: " + this.getPosition() + " has voted for: " + vote);
}
- int randomPosition = (int) (Math.random()*humanPositions.length);
- vote = humanPositions[randomPosition];
- hasVoted = true;
- LOGGER.info("GhostNPC at Position: " + this.getPosition() + " has voted for: " + vote);
}
/**
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java
index 1d7133e..8a4e6da 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java
@@ -53,7 +53,7 @@ public class GhostPlayer extends Ghost {
public void getVoteFromGameState(ClientVoteData clientVoteData, Game game) {
vote = clientVoteData.getVote()[position];
hasVoted = clientVoteData.getHasVoted()[position];
- clientVoteData.setVote(position,Integer.MAX_VALUE);
+ clientVoteData.setVote(position, Integer.MAX_VALUE);
clientVoteData.setHasVoted(position,false);
LOGGER.info("Ghost at Pos: " + position + " has voted for: " + vote);
/*
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java
index 185cb78..38c9ca6 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java
@@ -65,6 +65,9 @@ public class MessageFormatter {
case "/p":
stringBuilder.append(Protocol.listPlayersInLobby);
break;
+ case "/z":
+ stringBuilder.append(Protocol.listGames);
+ break;
case "/j":
stringBuilder.append(Protocol.joinLobby + "$");
try {
@@ -93,7 +96,6 @@ public class MessageFormatter {
break;
case "/s":
stringBuilder.append(Protocol.startANewGame);
-
break;
default:
s = msg;
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java
index b974ff4..f53c17a 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java
@@ -122,10 +122,17 @@ public class Protocol {
/**
- * A Client decides to start the game.
+ * A Client decides to start the game. The game is started in the lobby the message came from.
+ * Only one game can be started per lobby at a time.
*/
public static final String startANewGame = "STGAM";
+ /**
+ * Client request to see a list of all games, ongoing and finished.
+ */
+
+ public static final String listGames = "LISTG";
+
/**
* Client informs server that they have voted and delivers this vote in the form of "CVOTE$position$vote"
*/
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java
index a475f9f..ea26ec9 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java
@@ -423,7 +423,7 @@ public class ClientHandler implements Runnable {
*/
public void listLobbies() {
if (Lobby.lobbies.isEmpty()) {
- sendAnnouncementToClient("No open Lobbies.");
+ sendAnnouncementToClient("No Lobbies.");
} else {
for (Lobby l : Lobby.lobbies) {
String lobbyStatus = "closed";
@@ -475,6 +475,32 @@ public class ClientHandler implements Runnable {
}
}
+ /**
+ * Lists all Games currenty running and already finished and displays it to the client handled by this
+ */
+ public void listGames() {
+ if (Lobby.runningGames.isEmpty() && Lobby.finishedGames.isEmpty()) {
+ sendAnnouncementToClient("No Games");
+ } else {
+ sendAnnouncementToClient("Running Games:");
+ try {
+ for (Game runningGame : Lobby.runningGames) {
+ sendAnnouncementToClient(" - " + runningGame.getName() + ", Lobby" + runningGame.getLobby().getLobbyID());
+ }
+ } catch (Exception e) {
+ sendAnnouncementToClient(" - No running Games");
+ }
+ sendAnnouncementToClient("Finished Games");
+ try {
+ for (Game finishedGame : Lobby.finishedGames) {
+ sendAnnouncementToClient(" - " + finishedGame.getName() + ", Lobby" + finishedGame.getLobby().getLobbyID());
+ }
+ } catch (Exception e) {
+ sendAnnouncementToClient(" - No finished Games");
+ }
+ }
+ }
+
/**
* Closes the client's socket, in, and out. and removes from global list of clients.
*/
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java
index 06a4120..d1ab373 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java
@@ -111,6 +111,9 @@ public class JServerProtocolParser {
case Protocol.startANewGame:
h.startNewGame();
break;
+ case Protocol.listGames:
+ h.listGames();
+ break;
default:
System.out.println("Received unknown command");
}
diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java
index 21bc958..92cdbfb 100644
--- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/Lobby.java
@@ -108,13 +108,6 @@ public class Lobby {
return null;
}
- public static HashSet