using Model.Dice; using Model.Dice.Faces; using Model.Players; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Text; namespace Model.Games { public class Game { /// /// the name of the game 😎 /// public string Name { get { return name; } set // GameRunner will need to take care of forbidding // (or allowing) having two Games with the same name etc. { if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentException("param should not be null or blank", nameof(value)); } name = value; } } private string name; /// /// whether this game is new or not /// public bool IsFirstTurn { get; private set; } = false; /// /// the turns that have been done so far /// private readonly List turns; /// /// get a READ ONLY enumerable of all turns belonging to this game /// /// a readonly enumerable of all this game's turns public IEnumerable GetHistory() => turns.AsEnumerable(); /// /// the game's player manager, doing CRUD on players and switching whose turn it is /// private readonly PlayerManager playerManager; /// /// the group of dice used for this game /// private readonly FavGroup favGroup; /// /// constructs a Game with its own history of Turns. /// If is null, starts a new history /// /// the name of the game 😎 /// the turns that have been done so far /// the game's player manager, doing CRUD on players and switching whose turn it is /// the group of dice used for this game public Game(string name, PlayerManager playerManager, FavGroup favGroup, IEnumerable turns) { Name = name; this.turns = turns.ToList() ?? new List(); this.playerManager = playerManager; this.favGroup = favGroup; } /// /// constructs a Game with no history of turns. /// /// the name of the game 😎 /// the game's player manager, doing CRUD on players and switching whose turn it is /// the group of dice used for this game public Game(string name, PlayerManager playerManager, FavGroup favGroup) : this(name, playerManager, favGroup, null) { } /// /// performs a Turn, marks this Game as "started", and logs that Turn /// /// the player whose turn it is public void PerformTurn(Player player) { if (IsFirstTurn) { IsFirstTurn = false; } // only true one time (on the first turn...) Turn turn = Turn.CreateWithDefaultTime( new Player(player), ThrowAll() //using a copy so that next line doesn't "change history" ); turns.Add(turn); } /// /// finds whose turn it is /// /// the Player whose turn it is public Player GetWhoPlaysNow() { return playerManager.WhoPlaysNow(IsFirstTurn); } /// /// throws all the Dice in FavGroup and returns a list of their Faces /// /// list of AbstractDieFaces after a throw private List ThrowAll() { List faces = new(); foreach (Die die in favGroup.Dice) { faces.Add(die.Throw()); } return faces; } /// /// asks the PlayerManager to prepare the next Player /// /// the Player whose turn it was public void PrepareNextPlayer(Player currentPlayer) { playerManager.PrepareNextPlayer(currentPlayer); } public Player AddPlayerToGame(Player player) { return playerManager.Add(player); } public IEnumerable GetPlayersFromGame() { return playerManager.GetAll(); } public Player UpdatePlayerInGame(Player oldPlayer, Player newPlayer) { return playerManager.Update(oldPlayer, newPlayer); } public void RemovePlayerFromGame(Player player) { playerManager.Remove(player); } /// /// represents a Game in string format /// /// a Game in string format public override string ToString() { StringBuilder sb = new(); sb.AppendFormat("Game: {0}===========\n" + "{1} are playing. {2} is next.\n" + "Log:\n", Name, playerManager.GetAll().ToString(), playerManager.WhoPlaysNow(IsFirstTurn)); foreach (Turn turn in this.turns) { sb.Append("\t" + turn.ToString()); } return sb.ToString(); } } }