package games.strategy.engine.data; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; /** * Tracks alliances between players. * An alliance is a named entity, players are added to an alliance. * Currently only used for tracking stats (like TUV, total production, etc), and for tracking total victory cities for * alliance based * victory conditions. * Not used for determining in-game alliances (instead, see the Relationship tracker for that). */ public class AllianceTracker implements Serializable { private static final long serialVersionUID = 2815023984535209353L; // maps PlayerID to Collection of alliances names private final Multimap<PlayerID, String> alliances; public AllianceTracker() { alliances = HashMultimap.create(); } public AllianceTracker(final Multimap<PlayerID, String> alliances) { this.alliances = alliances; } @SerializationProxySupport public Object writeReplace() { return new SerializationProxy(this); } private static class SerializationProxy implements Serializable { private static final long serialVersionUID = -4193924040595347947L; private final Multimap<PlayerID, String> alliances; public SerializationProxy(final AllianceTracker allianceTracker) { alliances = ImmutableMultimap.copyOf(allianceTracker.alliances); } private Object readResolve() { return new AllianceTracker(alliances); } } /** * Adds PlayerID player to the alliance specified by allianceName. * * @param player The player to add to the alliance. * @param allianceName The alliance to add to. */ protected void addToAlliance(final PlayerID player, final String allianceName) { alliances.put(player, allianceName); } /** * @return a set of all the games alliances, this will return an empty set if you aren't using alliances. */ public Set<String> getAlliances() { final Iterator<PlayerID> keys = alliances.keySet().iterator(); final Set<String> rVal = new HashSet<>(); while (keys.hasNext()) { rVal.addAll(alliances.get(keys.next())); } return rVal; } /** * Returns the PlayerID's that are members of the alliance * specified by the String allianceName. * * @param allianceName Alliance name * @return all the players in the given alliance */ public Set<PlayerID> getPlayersInAlliance(final String allianceName) { final Iterator<PlayerID> keys = alliances.keySet().iterator(); final HashSet<PlayerID> rVal = new HashSet<>(); while (keys.hasNext()) { final PlayerID player = keys.next(); if (alliances.get(player).contains(allianceName)) { rVal.add(player); } } return rVal; } public Collection<String> getAlliancesPlayerIsIn(final PlayerID player) { final Collection<String> rVal = alliances.get(player); if (!rVal.isEmpty()) { return rVal; } else { return Collections.singleton(player.getName()); } } public Set<PlayerID> getAllies(final PlayerID currentPlayer) { final Set<PlayerID> allies = new HashSet<>(); // for each of the player alliances, add each player from that alliance to the total alliance list alliances.get(currentPlayer).forEach(alliance -> allies.addAll(getPlayersInAlliance(alliance))); return allies; } }