package org.royaldev.thehumanity.player; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.kitteh.irc.client.library.element.User; import org.royaldev.thehumanity.cards.types.BlackCard; import org.royaldev.thehumanity.cards.types.WhiteCard; import xyz.cardstock.cardstock.players.HandedPlayer; import xyz.cardstock.cardstock.players.Player; import xyz.cardstock.cardstock.players.hands.PlayerHand; import java.util.Collections; import java.util.Set; /** * Represents a player in one game of Cards Against Humanity. */ public class TheHumanityPlayer implements Player, HandedPlayer<WhiteCard> { private final PlayerHand<WhiteCard> hand = new PlayerHand<>(); private final Multiset<BlackCard> wins = HashMultiset.create(); private User user; /** * Creates a new player, with a backing user. * * @param user User that backs this player */ public TheHumanityPlayer(@Nullable final User user) { this.user = user; } /** * Adds a win to this player's wins. This should always be used to add a winning card. * * @param win BaseCard that won a point for this player */ public void addWin(@NotNull final BlackCard win) { Preconditions.checkNotNull(win, "win was null"); this.wins.add(win); } /** * Removes all wins from this player. */ public void clearWins() { this.wins.clear(); } /** * Checks equality with another player. This will return true if and only if the objects are the same object or have * the same (case-insensitive) nickname. * * @param obj Object to check equality with * @return true if equal, false if not */ @Override public boolean equals(@Nullable final Object obj) { if (this == obj) return true; if (!(obj instanceof TheHumanityPlayer)) return false; final TheHumanityPlayer p = (TheHumanityPlayer) obj; return p.getUser().getNick().equalsIgnoreCase(this.getUser().getNick()); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("hand", this.hand) .add("wins", this.wins) .add("user", this.user) .toString(); } /** * Gets this player's hand of cards. * * @return Hand */ @NotNull public PlayerHand<WhiteCard> getHand() { return this.hand; } /** * Gets this player's current score, which is directly <code>this.getWins().size()</code>. * * @return Score */ public int getScore() { return this.getWins().size(); } /** * Gets the User backing this player. * * @return User */ @NotNull @Override public User getUser() { return this.user; } /** * Sets the User backing this player. * * @param user User */ public void setUser(@Nullable final User user) { this.user = user; } /** * Returns an unmodifiable set of the cards representing points for this player. * * @return Unmodifiable set * @see TheHumanityPlayer#addWin(BlackCard) * @see TheHumanityPlayer#removeWin(BlackCard) */ @NotNull public Set<BlackCard> getWins() { return Collections.unmodifiableSet(this.wins.elementSet()); } /** * Removes a win from this player's wins. This should always be used to remove a winning card. * * @param win BaseCard to remove */ public void removeWin(@NotNull final BlackCard win) { Preconditions.checkNotNull(win, "win was null"); this.wins.remove(win); } }