package org.royaldev.thehumanity.game.round; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.royaldev.thehumanity.cards.play.PlaySnapshot; import org.royaldev.thehumanity.game.GameSnapshot.Timestamps; import org.royaldev.thehumanity.util.json.JSONSerializable; import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * A historical snapshot of a round. It has no reference to its parent game, but historical games should have reference * to their historical rounds. */ public class RoundSnapshot implements Serializable, JSONSerializable { private static final long serialVersionUID = 43L; private int number; private Timestamps timestamps; private String blackCard, czar, winner, endCause; private Map<String, List<IndividualPlaySnapshot>> plays; private Set<String> players, skippedPlayers; private Map<String, Integer> scoreDelta, votes; public RoundSnapshot() {} public RoundSnapshot(final int number, final long startTime, final long endTime, final String blackCard, final String czar, final String winner, final String endCause, final List<PlaySnapshot> plays, final Set<String> players, final Set<String> skippedPlayers, final Map<String, Integer> scoreDelta, final Map<String, Integer> votes) { this.number = number; this.timestamps = new Timestamps(startTime, endTime); this.blackCard = blackCard; this.czar = czar; this.winner = winner; this.endCause = endCause; this.plays = plays.stream().collect(Collectors.toMap( PlaySnapshot::getPlayer, ps -> ps.getWhiteCards().stream() .map( wc -> new IndividualPlaySnapshot( wc, ps.getHandIndices()[ps.getWhiteCards().indexOf(wc)] ) ) .collect(Collectors.toList()) )); this.players = players; this.skippedPlayers = skippedPlayers; this.scoreDelta = scoreDelta; this.votes = votes; } /** * Gets the black card for this round. * * @return Black card */ @NotNull public String getBlackCard() { return this.blackCard; } /** * Gets the czar for this round. This may be null if and only if a house rule such as God is Dead, which removes any * singular czar and enables voting, is being used. * * @return Czar's nickname or null */ @Nullable public String getCzar() { return this.czar; } public String getEndCause() { return this.endCause; } /** * Gets the round number, starting at 1. * * @return CAHRound number */ public int getNumber() { return this.number; } public Set<String> getPlayers() { return players; } /** * Gets the plays at this point in time. * * @return List of plays (snapshotted) */ @NotNull public Map<String, List<IndividualPlaySnapshot>> getPlays() { return this.plays; } public Map<String, Integer> getScoreDelta() { return scoreDelta; } /** * Gets any skipped players' nicknames. * * @return List of nicknames */ @NotNull public Set<String> getSkippedPlayers() { return this.skippedPlayers; } public Timestamps getTimestamps() { return this.timestamps; } public Map<String, Integer> getVotes() { return votes; } /** * Gets the winner at this point in time. May be null if this snapshot is from before a winner was declared or if * the round this snapshot represents was ended before a winner could be decided. * * @return Winner's nickname or null */ @Nullable public String getWinner() { return this.winner; } public static class IndividualPlaySnapshot implements Serializable, JSONSerializable { private static final long serialVersionUID = 51L; private String text; private int handIndex; public IndividualPlaySnapshot() {} public IndividualPlaySnapshot(final String text, final int handIndex) { this.text = text; this.handIndex = handIndex; } public int getHandIndex() { return this.handIndex; } public String getText() { return this.text; } } }