package cards.maumau.model; import cards.Card; import cards.Suit; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; /** * Represents a Mau-Mau card game. */ public class MauMau { private final ActionHandler actionHandler = new ActionHandler(this); private final PlayerHandler playerHandler = new PlayerHandler(this); private final CardHandler cardHandler; private final List observers = new ArrayList<>(); /** * Constructs a MauMau game with the specified parameters. * * @param numCardsPerPlayer The number of cards each player should have initially. * @param deck The deck of cards to be used in the game. */ public MauMau(int numCardsPerPlayer, List deck) { cardHandler = new CardHandler(this, deck, numCardsPerPlayer); } /** * Adds an observer to the game. * * @param observer The observer to add. */ public void addObserver(IObserver observer) { observers.add(observer); } /** * Notifies all observers of the game. */ void notifyObservers() { for (IObserver o : observers) o.update(); } /** * Sends a message to all observers. * * @param msg The message to send. */ void sendMessage(String msg) { for (IObserver o : observers) o.message(msg); } /** * Gets the player handler for the game. * * @return The player handler. */ public PlayerHandler getPlayerHandler() { return playerHandler; } /** * Gets the card handler for the game. * * @return The card handler. */ public CardHandler getCardHandler() { return cardHandler; } /** * Gets the action handler for the game. * * @return The action handler. */ ActionHandler getActionHandler() { return actionHandler; } /** * Returns the suit chosen by a player after playing a Jack. * * @return The chosen suit. */ public Suit getChosenSuit() { return actionHandler.getChosenSuit(); } /** * Returns the number of number 7 cards played recently. * * @return The number of number 7 cards played recently. */ public int get7Counter() { return actionHandler.get7Counter(); } /** * Starts the Mau-Mau game. */ public void startGame() { actionHandler.startGame(); } /** * Returns a string representation of the game. * * @return String representation of the game. */ @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Game state: ").append(getGameState()).append("\n"); sb.append("State: ").append(actionHandler).append("\n"); sb.append("Players:\n"); sb.append(mkString(getPlayers(), " ", "\n ")); sb.append(mkString(getDrawPile(), "draw pile: ", " ")); sb.append(mkString(getDiscardPile(), "discard pile: ", " ")); sb.append(mkString(getRanking(), Player::getName, "ranking: ", ", ", "\n")); sb.append("chosen suit: ").append(getChosenSuit()).append("\n"); sb.append("7 count: ").append(get7Counter()).append("\n"); return sb.toString(); } /** * Joins the elements of the list into a single string with the specified prefix and delimiter. * * @param list The list to join. * @param func Function to convert list elements to strings. * @param prefix Prefix for the resulting string. * @param delimiter Delimiter to separate list elements. * @param suffix Suffix for the resulting string. * @param Type of elements in the list. * @return Joined string representation of the list. */ static String mkString(List list, Function func, String prefix, String delimiter, String suffix) { return list.stream() .map(func) .collect(Collectors.joining(delimiter, prefix, suffix)); } /** * Joins the elements of the list into a single string with the specified prefix and delimiter. * * @param list The list to join. * @param prefix Prefix for the resulting string. * @param delimiter Delimiter to separate list elements. * @param Type of elements in the list. * @return Joined string representation of the list. */ static String mkString(List list, String prefix, String delimiter) { return mkString(list, Objects::toString, prefix, delimiter, "\n"); } /** * Gets the list of players still participating in the game. * The first player in the list is the current player. * * @return The list of players. */ public List getPlayers() { return playerHandler.getPlayers(); } /** * Adds a player to the game. * * @param name The name of the player. * @return The player added to the game. */ public Player addPlayer(String name) { final Player player = new Player(name, this); actionHandler.addPlayer(player); return player; } /** * Returns the ranking of players that have already discarded all of their cards * and, when the game is over, also the loser. * * @return The ranking of players. */ public List getRanking() { return playerHandler.getRanking(); } /** * Returns the current player whose turn it is. * * @return The current player. */ public Player getCurrentPlayer() { return playerHandler.getCurrentPlayer(); } /** * Returns the draw pile containing remaining cards. * * @return The draw pile. */ public List getDrawPile() { return cardHandler.getDrawPile(); } /** * Returns the discard pile containing played cards. * * @return The discard pile. */ public List getDiscardPile() { return cardHandler.getDiscardPile(); } /** * Returns the current state of the game. * * @return The state of the game. */ public GameState getGameState() { return actionHandler.getGameState(); } }