Files
basic-computer-games/84_Super_Star_Trek/csharp/Game.cs
2022-03-22 17:55:44 +11:00

129 lines
3.9 KiB
C#

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