using System; using SuperStarTrek.Objects; using SuperStarTrek.Resources; using SuperStarTrek.Space; using SuperStarTrek.Systems; using SuperStarTrek.Systems.ComputerFunctions; namespace SuperStarTrek { internal class Game { private readonly Output _output; private readonly Input _input; private readonly Random _random; private int _initialStardate; private int _finalStarDate; private float _currentStardate; private Coordinates _currentQuadrant; private Galaxy _galaxy; private int _initialKlingonCount; private Enterprise _enterprise; internal Game(Output output, Input input, Random random) { _output = output; _input = input; _random = random; } internal float Stardate => _currentStardate; internal float StardatesRemaining => _finalStarDate - _currentStardate; internal void DoIntroduction() { _output.Write(Strings.Title); if (_input.GetYesNo("Do you need instructions", Input.YesNoMode.FalseOnN)) { _output.Write(Strings.Instructions); _input.WaitForAnyKeyButEnter("to continue"); } } internal void Play() { Initialise(); var gameOver = false; while (!gameOver) { var command = _input.GetCommand(); var result = _enterprise.Execute(command); gameOver = result.IsGameOver || CheckIfStranded(); _currentStardate += result.TimeElapsed; gameOver |= _currentStardate > _finalStarDate; } if (_galaxy.KlingonCount > 0) { _output.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount); } else { _output.Write(Strings.Congratulations, GetEfficiency()); } } private void Initialise() { _currentStardate = _initialStardate = _random.GetInt(20, 40) * 100; _finalStarDate = _initialStardate + _random.GetInt(25, 35); _currentQuadrant = _random.GetCoordinate(); _galaxy = new Galaxy(_random); _initialKlingonCount = _galaxy.KlingonCount; _enterprise = new Enterprise(3000, _random.GetCoordinate(), _output, _random, _input); _enterprise .Add(new WarpEngines(_enterprise, _output, _input)) .Add(new ShortRangeSensors(_enterprise, _galaxy, this, _output)) .Add(new LongRangeSensors(_galaxy, _output)) .Add(new PhaserControl(_enterprise, _output, _input, _random)) .Add(new PhotonTubes(10, _enterprise, _output, _input)) .Add(new ShieldControl(_enterprise, _output, _input)) .Add(new DamageControl(_enterprise, _output)) .Add(new LibraryComputer( _output, _input, new CumulativeGalacticRecord(_output, _galaxy), new StatusReport(this, _galaxy, _enterprise, _output), new TorpedoDataCalculator(_enterprise, _output), new StarbaseDataCalculator(_enterprise, _output), new DirectionDistanceCalculator(_enterprise, _output, _input), new GalaxyRegionMap(_output, _galaxy))); _output.Write(Strings.Enterprise); _output.Write( Strings.Orders, _galaxy.KlingonCount, _finalStarDate, _finalStarDate - _initialStardate, _galaxy.StarbaseCount > 1 ? "are" : "is", _galaxy.StarbaseCount, _galaxy.StarbaseCount > 1 ? "s" : ""); _input.WaitForAnyKeyButEnter("when ready to accept command"); _enterprise.StartIn(BuildCurrentQuadrant()); } private Quadrant BuildCurrentQuadrant() => new Quadrant(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _input, _output); internal bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye"); private bool CheckIfStranded() { if (_enterprise.IsStranded) { _output.Write(Strings.Stranded); } return _enterprise.IsStranded; } private float GetEfficiency() => 1000 * (float)Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2); } }