mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
132 lines
4.5 KiB
C#
132 lines
4.5 KiB
C#
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);
|
|
}
|
|
}
|