private SeasonSimulationResult SimulateSeason(SeasonState startingSeasonState, IStrategy strategy, int maxGameweek)
        {
            var seasonState = startingSeasonState;

            var result = new SeasonSimulationResult();
            for (int gameweek = 1; gameweek <= maxGameweek; gameweek++)
            {
                _logger.Log(Tag.Simulation, string.Concat("Simulating gameweek ", gameweek), true);
                _logger.Log(Tag.Simulation, string.Concat("Current points total: ", result.TotalPointsScored), true);
                _logger.Log(Tag.Simulation, string.Concat("Available money: ", seasonState.Money.ToMoney()), true);
                _logger.Log(Tag.Simulation, string.Concat("Free transfers: ", seasonState.FreeTransfers), true);

                seasonState = UpdateSeasonStateToGameweek(seasonState, gameweek);

                var strategyDecisionResult = ProcessStrategyDecisions(seasonState, strategy);

                seasonState = strategyDecisionResult.UpdatedSeasonState;

                var playerPerformances = CalculatePlayerGameweekPerformances(seasonState);

                var gameweekPerformance = new TeamGameweekPerformance
                                          {
                                              PlayerPerformances = playerPerformances,
                                              TransferActions = strategyDecisionResult.TransfersMade,
                                              TransferResults = strategyDecisionResult.TransferResults,
                                              Gameweek = gameweek
                                          };

                result.GameweekResults.Add(gameweekPerformance);

                _logger.Log(Tag.Result,
                            string.Concat("Total player points scored in gameweek ", gameweek, ": ",
                                            gameweekPerformance.TotalPlayerPointsScored), true);
                _logger.Log(Tag.Result,
                           string.Concat("Transfer penalty points in gameweek ", gameweek, ": ",
                                           gameweekPerformance.TransferResults.TransferPointsPenalty), true);

                _logger.Log(Tag.Result,
                           string.Concat("Total points for gameweek ", gameweek, ": ",
                                           gameweekPerformance.TotalPointsScored), true);
            }

            OutputResult(result);

            return result;
        }
        private void OutputResult(SeasonSimulationResult result)
        {
            _logger.Log(Tag.Result, "Outputting simulation results", true);
            _logger.Log(Tag.Result, string.Concat("Total points: ", result.TotalPointsScored), true);
            _logger.Log(Tag.Result, string.Concat("Total transfers made: ", result.TotalTransfersMade), true);
            _logger.Log(Tag.Result,
                       string.Concat("Total penalised transfers made: ", result.TotalPenalisedTransfersMade), true);

            var standardWildcardGameweek =
                result.GameweekResults.SingleOrDefault(x => x.TransferActions.PlayStandardWildcard);
            _logger.Log(Tag.Result,
                string.Format("Standard wildcard played : {0}", standardWildcardGameweek == null ? "Never!" : standardWildcardGameweek.Gameweek.ToString(CultureInfo.InvariantCulture)), true);

            var transferWindowWildcardGameweek =
                result.GameweekResults.SingleOrDefault(x => x.TransferActions.PlayTransferWindowWildcard);
            _logger.Log(Tag.Result,
                string.Format("Transfer window wildcard played : {0}", transferWindowWildcardGameweek == null ? "Never!" : transferWindowWildcardGameweek.Gameweek.ToString(CultureInfo.InvariantCulture)), true);
        }