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();
}
}
}