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 27f3f04..0a8e641 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 @@ -65,6 +65,9 @@ public class Game implements Runnable { isOngoing = ongoing; } + /** + * Returns this game's OG ghost as a Passenger object + */ Passenger getOgGhost(){ int[] order = gameState.getTrain().getOrderOfTrain(); Passenger[] passengerTrain = gameState.getPassengerTrain(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java index 74072f4..e5eef8e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Timer.java @@ -1,11 +1,13 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** - * A class that handles all timed events in the game, such as vote times + * A class that handles all timed events in the game, such as vote times. This class essentially + * is used to pause the main game thread for a given time / until a given event. */ public class Timer { public static final Logger LOGGER = LogManager.getLogger(Timer.class); @@ -14,36 +16,68 @@ public class Timer { /** * The maximum length of the ghost vote in the night, in seconds */ - public static final int ghostVote = 30; + public static final int ghostVoteTime = 30; + + /** + * The length of time in seconds after the ghost vote during which the ghosts visually walk to / + * from their victim and the timespan within which humans will hear a noise. After this, the day starts. + */ + public static final int ghostAfterVoteTime = 7; /** * The maximum length of the human vote in the day, in seconds */ - public static final int humanVote = 60; + public static final int humanVoteTime = 60; /** - * The checking intervall in seconds + * The length of time in seconds after the human vote, as the 'winner' of the vote is announced, + * before the night begins */ - public static final int intervall = 1; + public static final int humanAfterVoteTime = 5; /** - * The timer for the ghost vote. Checks every {@code intervall} seconds if every ghost has already voted. - * If all have voted or if the {@code ghostVote} value is reached, the timer ends + * The checking interval in seconds + */ + public static final int interval = 1; + + /** + * The timer for the ghost vote. Checks every {@code interval} seconds if every ghost has already voted. + * If all have voted or if the {@code ghostVoteTime} value is reached, the timer ends * @param game the game this Timer has been called in */ public static void ghostVoteTimer(Game game) { int counter = 0; - while(counter < ghostVote) { + while(counter < ghostVoteTime) { if(haveAllGhostsVoted(game)) { //if all ghost have voted return; } try { - Thread.sleep(intervall*1000); + Thread.sleep(interval*1000); } catch (InterruptedException e) { LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } - counter = counter + (intervall*1000); + counter += (interval); } + } + public static void humanVoteTimer(Game game) { + int counter = 0; + while (counter < humanVoteTime) { + if (haveAllHumansVoted(game)) return; + try { + Thread.sleep(interval*1000); + } catch (InterruptedException e) { + LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); + } + counter += interval; + } + } + + public static void ghostAfterVoteTimer() { + try { + Thread.sleep(ghostAfterVoteTime *1000); + } catch (InterruptedException e) { + LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); + } } /** @@ -71,5 +105,18 @@ public class Timer { return nrOfGhosts == j; } + /** + * Checks if all humans have already voted, returns true if so, else returns false + */ + public static boolean haveAllHumansVoted(Game game) { + boolean[] whoHasVoted = game.getGameState().getClientVoteData().getHasVoted(); + Passenger[] passengerArray = game.getGameState().getPassengerTrain(); + for(int i = 0; i < whoHasVoted.length; i++) { + if(!passengerArray[i].getIsGhost() && !whoHasVoted[i]) { + return false; + } + } + return true; + } } 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 48b3b75..377def6 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 @@ -50,42 +50,34 @@ public class VoteHandler { } } - //Timer.ghostVoteTimer(game); - try { - Thread.sleep(20*1000); - } catch (InterruptedException e) { - LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); - } + Timer.ghostVoteTimer(game); + int currentMax = ghostVoteEvaluation(passengers, votesForPlayers, game.getGameState().getClientVoteData(), game); LOGGER.debug("Most votes: " + currentMax + " vote(s)"); // ghostify the player with most votes - int ghostPosition = 0; + int newGhostPosition = 0; for (int i = 0; i < votesForPlayers.length; i++) { if (votesForPlayers[i] == currentMax) { // if player at position i has most votes - ghostPosition = i; + newGhostPosition = i; LOGGER.debug("Most votes for Passenger " + i); } } - LOGGER.info("Most votes for: " + ghostPosition); + LOGGER.info("Most votes for: " + newGhostPosition); for(Passenger passenger : passengers) { if(passenger.getIsGhost() || passenger.getIsSpectator()) { - passenger.send(passengers[ghostPosition].getName() + ClientGameInfoHandler.gotGhostyfied, game); + passenger.send(passengers[newGhostPosition].getName() + ClientGameInfoHandler.gotGhostyfied, game); } } - Passenger g = GhostifyHandler.ghost(passengers[ghostPosition], game); - passengers[ghostPosition] = g; - if (!passengers[ghostPosition].getIsSpectator()) { - passengers[ghostPosition].send( + Passenger g = GhostifyHandler.ghost(passengers[newGhostPosition], game); + passengers[newGhostPosition] = g; + if (!passengers[newGhostPosition].getIsSpectator()) { + passengers[newGhostPosition].send( ClientGameInfoHandler.youGotGhostyfied, game); - } - try { - Thread.sleep(10); - } catch (InterruptedException e) { - LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); + passengers[newGhostPosition].send(game.gameState.toString(), game); } /* notify passengers the ghosts passed by - for each ghost that ghostified a player, an instance of NoiseHandler @@ -96,7 +88,7 @@ public class VoteHandler { int[] noiseAmount = new int[6]; for (int i = 0; i < passengers.length; i++) { - if (passengers[i].getIsGhost() && i != ghostPosition) { + if (passengers[i].getIsGhost() && i != newGhostPosition) { NoiseHandler n = new NoiseHandler(); noiseAmount = n.noiseNotifier(passengers[i], g, noiseAmount); } @@ -107,6 +99,11 @@ public class VoteHandler { } } + /* used to wait for some time so the humans have time to hear noises and so the ghosts (& victim) + can see the infection happen. */ + Timer.ghostAfterVoteTimer(); + + // no humans left in the game --> everyone has been ghostified, ghosts win int humanCounter = 0; for(Passenger passenger : passengers) { @@ -154,11 +151,7 @@ public class VoteHandler { } } - try { // waits 60 seconds before votes get collected - Thread.sleep(20*1000); - } catch (InterruptedException e) { - LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); - } + Timer.humanVoteTimer(game); int currentMax = humanVoteEvaluation(passengers, votesForPlayers, game.getGameState().getClientVoteData(), game); 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 a9aaa32..9049128 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 @@ -35,7 +35,9 @@ public class GhostPlayer extends Ghost { } /** - * Sends a message to the client handled bye this client handler + * Sends a message to the client handled by this client handler. By default, it adds the + * protocol signature to print the given msg as is to the client console. For more detail on + * how the message gets formatted, look at the ServerGameInfoHandler.format() method. * @param msg the message that is sent to this player. * @param game the game the GhostPlayer lives on (in game.gameState.passengerTrain) */