mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-28 05:33:48 -08:00
Add Warp Engines
This commit is contained in:
@@ -12,6 +12,7 @@ namespace SuperStarTrek
|
||||
{
|
||||
private readonly Output _output;
|
||||
private readonly Input _input;
|
||||
private readonly Random _random;
|
||||
|
||||
private int _initialStardate;
|
||||
private int _finalStarDate;
|
||||
@@ -25,6 +26,7 @@ namespace SuperStarTrek
|
||||
{
|
||||
_output = new Output();
|
||||
_input = new Input(_output);
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
public float Stardate => _currentStardate;
|
||||
@@ -46,15 +48,19 @@ namespace SuperStarTrek
|
||||
{
|
||||
Initialise();
|
||||
var gameOver = false;
|
||||
var newQuadrantText = Strings.StartText;
|
||||
|
||||
while (!gameOver)
|
||||
{
|
||||
_enterprise.Quadrant.Display(Strings.NowEntering);
|
||||
|
||||
var command = _input.GetCommand();
|
||||
|
||||
var result = _enterprise.Execute(command);
|
||||
|
||||
gameOver = result.IsGameOver || CheckIfStranded();
|
||||
_currentStardate += result.TimeElapsed;
|
||||
gameOver |= _currentStardate > _finalStarDate;
|
||||
}
|
||||
|
||||
if (_galaxy.KlingonCount > 0)
|
||||
@@ -69,21 +75,20 @@ namespace SuperStarTrek
|
||||
|
||||
private void Initialise()
|
||||
{
|
||||
var random = new Random();
|
||||
_currentStardate = _initialStardate = _random.GetInt(20, 40) * 100;
|
||||
_finalStarDate = _initialStardate + _random.GetInt(25, 35);
|
||||
|
||||
_currentStardate = _initialStardate = random.GetInt(20, 40) * 100;
|
||||
_finalStarDate = _initialStardate + random.GetInt(25, 35);
|
||||
_currentQuadrant = _random.GetCoordinate();
|
||||
|
||||
_currentQuadrant = random.GetCoordinate();
|
||||
|
||||
_galaxy = new Galaxy();
|
||||
_galaxy = new Galaxy(_random);
|
||||
_initialKlingonCount = _galaxy.KlingonCount;
|
||||
|
||||
_enterprise = new Enterprise(3000, random.GetCoordinate(), _output, random);
|
||||
_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 PhaserControl(_enterprise, _output, _input, _random))
|
||||
.Add(new PhotonTubes(10, _enterprise, _output, _input))
|
||||
.Add(new ShieldControl(_enterprise, _output, _input))
|
||||
.Add(new DamageControl(_enterprise, _output))
|
||||
@@ -109,10 +114,12 @@ namespace SuperStarTrek
|
||||
|
||||
_input.WaitForAnyKeyButEnter("when ready to accept command");
|
||||
|
||||
var quadrant = _galaxy[_currentQuadrant].BuildQuadrant(_enterprise, random, _galaxy, _input, _output);
|
||||
_enterprise.Enter(quadrant, Strings.StartText);
|
||||
_enterprise.StartIn(BuildCurrentQuadrant());
|
||||
}
|
||||
|
||||
private Quadrant BuildCurrentQuadrant() =>
|
||||
new Quadrant(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _input, _output);
|
||||
|
||||
public bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye");
|
||||
|
||||
private bool CheckIfStranded()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using SuperStarTrek.Commands;
|
||||
|
||||
using SuperStarTrek.Space;
|
||||
using static System.StringComparison;
|
||||
|
||||
namespace SuperStarTrek
|
||||
@@ -82,6 +82,19 @@ namespace SuperStarTrek
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetCourse(string prompt, string officer, out Course course)
|
||||
{
|
||||
if (!TryGetNumber(prompt, 1, 9, out var direction))
|
||||
{
|
||||
_output.WriteLine($"{officer} reports, 'Incorrect course data, sir!'");
|
||||
course = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
course = new Course(direction);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetYesNo(string prompt, YesNoMode mode)
|
||||
{
|
||||
_output.Prompt($"{prompt} (Y/N)");
|
||||
|
||||
@@ -16,21 +16,25 @@ namespace SuperStarTrek.Objects
|
||||
private readonly List<Subsystem> _systems;
|
||||
private readonly Dictionary<Command, Subsystem> _commandExecutors;
|
||||
private readonly Random _random;
|
||||
private readonly Input _input;
|
||||
private Quadrant _quadrant;
|
||||
|
||||
public Enterprise(int maxEnergy, Coordinates sector, Output output, Random random)
|
||||
public Enterprise(int maxEnergy, Coordinates sector, Output output, Random random, Input input)
|
||||
{
|
||||
Sector = sector;
|
||||
SectorCoordinates = sector;
|
||||
TotalEnergy = _maxEnergy = maxEnergy;
|
||||
|
||||
_systems = new List<Subsystem>();
|
||||
_commandExecutors = new Dictionary<Command, Subsystem>();
|
||||
_output = output;
|
||||
_random = random;
|
||||
_input = input;
|
||||
}
|
||||
|
||||
public Coordinates Quadrant => _quadrant.Coordinates;
|
||||
public Coordinates Sector { get; }
|
||||
public Quadrant Quadrant => _quadrant;
|
||||
public Coordinates QuadrantCoordinates => _quadrant.Coordinates;
|
||||
public Coordinates SectorCoordinates { get; private set; }
|
||||
|
||||
public string Condition => GetCondition();
|
||||
public LibraryComputer Computer => (LibraryComputer)_commandExecutors[Command.COM];
|
||||
public ShieldControl ShieldControl => (ShieldControl)_commandExecutors[Command.SHE];
|
||||
@@ -50,19 +54,10 @@ namespace SuperStarTrek.Objects
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Enter(Quadrant quadrant, string entryTextFormat)
|
||||
public void StartIn(Quadrant quadrant)
|
||||
{
|
||||
_quadrant = quadrant;
|
||||
|
||||
_output.Write(entryTextFormat, quadrant);
|
||||
|
||||
if (quadrant.HasKlingons)
|
||||
{
|
||||
_output.Write(Strings.CombatArea);
|
||||
if (ShieldControl.ShieldEnergy <= 200) { _output.Write(Strings.LowShields); }
|
||||
}
|
||||
|
||||
Execute(Command.SRS);
|
||||
quadrant.Display(Strings.StartText);
|
||||
}
|
||||
|
||||
private string GetCondition() =>
|
||||
@@ -121,7 +116,100 @@ namespace SuperStarTrek.Objects
|
||||
return;
|
||||
}
|
||||
|
||||
_systems[_random.Get1To8Inclusive() - 1].TakeDamage(hitShieldRatio + 0.5f * _random.GetFloat());
|
||||
var system = _systems[_random.Get1To8Inclusive() - 1];
|
||||
system.TakeDamage(hitShieldRatio + 0.5f * _random.GetFloat());
|
||||
_output.WriteLine($"Damage Control reports, '{system.Name} damaged by the hit.'");
|
||||
}
|
||||
|
||||
internal void RepairSystems(float repairWorkDone)
|
||||
{
|
||||
var repairedSystems = new List<string>();
|
||||
|
||||
foreach (var system in _systems.Where(s => s.IsDamaged))
|
||||
{
|
||||
if (system.Repair(repairWorkDone))
|
||||
{
|
||||
repairedSystems.Add(system.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (repairedSystems.Any())
|
||||
{
|
||||
_output.WriteLine("Damage Control report:");
|
||||
foreach (var systemName in repairedSystems)
|
||||
{
|
||||
_output.WriteLine($" {systemName} repair completed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void VaryConditionOfRandomSystem()
|
||||
{
|
||||
if (_random.GetFloat() > 0.2f) { return; }
|
||||
|
||||
var system = _systems[_random.Get1To8Inclusive() - 1];
|
||||
_output.Write($"Damage Control report: {system.Name} ");
|
||||
if (_random.GetFloat() >= 0.6)
|
||||
{
|
||||
system.Repair(_random.GetFloat() * 3 + 1);
|
||||
_output.WriteLine("state of repair improved");
|
||||
}
|
||||
else
|
||||
{
|
||||
system.TakeDamage(_random.GetFloat() * 5 + 1);
|
||||
_output.WriteLine("damaged");
|
||||
}
|
||||
}
|
||||
|
||||
internal float Move(Course course, float warpFactor, int distance)
|
||||
{
|
||||
var (quadrant, sector) = MoveWithinQuadrant(course, distance) ?? MoveBeyondQuadrant(course, distance);
|
||||
|
||||
if (quadrant != _quadrant.Coordinates)
|
||||
{
|
||||
_quadrant = new Quadrant(_quadrant.Galaxy[quadrant], this, _random, _quadrant.Galaxy, _input, _output);
|
||||
}
|
||||
SectorCoordinates = sector;
|
||||
|
||||
return GetTimeElapsed(quadrant, warpFactor);
|
||||
}
|
||||
|
||||
private (Coordinates, Coordinates)? MoveWithinQuadrant(Course course, int distance)
|
||||
{
|
||||
var currentSector = SectorCoordinates;
|
||||
foreach (var (sector, index) in course.GetSectorsFrom(SectorCoordinates).Select((s, i) => (s, i)))
|
||||
{
|
||||
if (distance == 0) { break; }
|
||||
|
||||
if (_quadrant.HasObjectAt(sector))
|
||||
{
|
||||
_output.WriteLine($"Warp engines shut down at sector {currentSector} dues to bad navigation");
|
||||
distance = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
currentSector = sector;
|
||||
distance -= 1;
|
||||
}
|
||||
|
||||
return distance == 0 ? (_quadrant.Coordinates, currentSector) : null;
|
||||
}
|
||||
|
||||
private (Coordinates, Coordinates) MoveBeyondQuadrant(Course course, int distance)
|
||||
{
|
||||
var (complete, quadrant, sector) = course.GetDestination(QuadrantCoordinates, SectorCoordinates, distance);
|
||||
|
||||
if (!complete)
|
||||
{
|
||||
_output.Write(Strings.PermissionDenied, sector, quadrant);
|
||||
}
|
||||
|
||||
return (quadrant, sector);
|
||||
}
|
||||
|
||||
private float GetTimeElapsed(Coordinates finalQuadrant, float warpFactor) =>
|
||||
finalQuadrant == _quadrant.Coordinates
|
||||
? Math.Min(1, (float)Math.Round(warpFactor, 1, MidpointRounding.ToZero))
|
||||
: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SuperStarTrek.Objects
|
||||
public CommandResult FireOn(Enterprise enterprise)
|
||||
{
|
||||
var attackStrength = _random.GetFloat();
|
||||
var distanceToEnterprise = Sector.GetDistanceTo(enterprise.Sector);
|
||||
var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates);
|
||||
var hitStrength = (int)(Energy * (2 + attackStrength) / distanceToEnterprise);
|
||||
Energy /= 3 + attackStrength;
|
||||
|
||||
@@ -36,5 +36,7 @@ namespace SuperStarTrek.Objects
|
||||
Energy -= hitStrength;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void MoveTo(Coordinates newSector) => Sector = newSector;
|
||||
}
|
||||
}
|
||||
|
||||
2
84 Super Star Trek/csharp/Resources/NowEntering.txt
Normal file
2
84 Super Star Trek/csharp/Resources/NowEntering.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Now entering {0} quadrant . . .
|
||||
|
||||
5
84 Super Star Trek/csharp/Resources/PermissionDenied.txt
Normal file
5
84 Super Star Trek/csharp/Resources/PermissionDenied.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Lt. Uhura report message from Starfleet Command:
|
||||
'Permission to attempt crossing of galactic perimeter
|
||||
is hereby *Denied*. Shut down your engines.'
|
||||
Chief Engineer Scott reports, 'Warp engines shut down
|
||||
at sector {0} of quadrant {1}.'
|
||||
@@ -17,7 +17,9 @@ namespace SuperStarTrek.Resources
|
||||
public static string LowShields => GetResource();
|
||||
public static string NoEnemyShips => GetResource();
|
||||
public static string NoStarbase => GetResource();
|
||||
public static string NowEntering => GetResource();
|
||||
public static string Orders => GetResource();
|
||||
public static string PermissionDenied => GetResource();
|
||||
public static string Protected => GetResource();
|
||||
public static string RegionNames => GetResource();
|
||||
public static string RelievedOfCommand => GetResource();
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace SuperStarTrek.Space
|
||||
coordinates = default;
|
||||
return false;
|
||||
|
||||
int Round(float value) => (int)Math.Round(value, MidpointRounding.AwayFromZero);
|
||||
static int Round(float value) => (int)Math.Round(value, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
internal (float Direction, float Distance) GetDirectionAndDistanceTo(Coordinates destination) =>
|
||||
@@ -25,7 +25,7 @@ namespace SuperStarTrek.Space
|
||||
(0, 1)
|
||||
};
|
||||
|
||||
public Course(float direction)
|
||||
internal Course(float direction)
|
||||
{
|
||||
if (direction < 1 || direction > 9)
|
||||
{
|
||||
@@ -45,10 +45,10 @@ namespace SuperStarTrek.Space
|
||||
DeltaY = baseCardinal.DeltaY + (nextCardinal.DeltaY - baseCardinal.DeltaY) * fractionalDirection;
|
||||
}
|
||||
|
||||
public float DeltaX { get; }
|
||||
public float DeltaY { get; }
|
||||
internal float DeltaX { get; }
|
||||
internal float DeltaY { get; }
|
||||
|
||||
public IEnumerable<Coordinates> GetSectorsFrom(Coordinates start)
|
||||
internal IEnumerable<Coordinates> GetSectorsFrom(Coordinates start)
|
||||
{
|
||||
(float x, float y) = start;
|
||||
|
||||
@@ -65,5 +65,33 @@ namespace SuperStarTrek.Space
|
||||
yield return coordinates;
|
||||
}
|
||||
}
|
||||
|
||||
internal (bool, Coordinates, Coordinates) GetDestination(Coordinates quadrant, Coordinates sector, int distance)
|
||||
{
|
||||
var (xComplete, quadrantX, sectorX) = GetNewCoordinate(quadrant.X, sector.X, DeltaX * distance);
|
||||
var (yComplete, quadrantY, sectorY) = GetNewCoordinate(quadrant.Y, sector.Y, DeltaY * distance);
|
||||
|
||||
return (xComplete && yComplete, new Coordinates(quadrantX, quadrantY), new Coordinates(sectorX, sectorY));
|
||||
}
|
||||
|
||||
private (bool, int, int) GetNewCoordinate(int quadrant, int sector, float sectorsTravelled)
|
||||
{
|
||||
var galacticCoordinate = quadrant * 8 + sector + sectorsTravelled;
|
||||
var newQuadrant = (int)(galacticCoordinate / 8);
|
||||
var newSector = (int)(galacticCoordinate - newQuadrant * 8);
|
||||
|
||||
if (newSector == -1)
|
||||
{
|
||||
newQuadrant -= 1;
|
||||
newSector = 7;
|
||||
}
|
||||
|
||||
return newQuadrant switch
|
||||
{
|
||||
< 0 => (false, 0, 0),
|
||||
> 7 => (false, 7, 7),
|
||||
_ => (true, newQuadrant, newSector)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SuperStarTrek.Objects;
|
||||
using SuperStarTrek.Resources;
|
||||
|
||||
using static System.StringSplitOptions;
|
||||
@@ -12,6 +13,7 @@ namespace SuperStarTrek.Space
|
||||
private static readonly string[] _regionNames;
|
||||
private static readonly string[] _subRegionIdentifiers;
|
||||
private readonly QuadrantInfo[][] _quadrants;
|
||||
private readonly Random _random;
|
||||
|
||||
static Galaxy()
|
||||
{
|
||||
@@ -19,9 +21,9 @@ namespace SuperStarTrek.Space
|
||||
_subRegionIdentifiers = new[] { "I", "II", "III", "IV" };
|
||||
}
|
||||
|
||||
public Galaxy()
|
||||
public Galaxy(Random random)
|
||||
{
|
||||
var random = new Random();
|
||||
_random = random;
|
||||
|
||||
_quadrants = Enumerable
|
||||
.Range(0, 8)
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace SuperStarTrek.Space
|
||||
private readonly Random _random;
|
||||
private readonly Dictionary<Coordinates, object> _sectors;
|
||||
private readonly Enterprise _enterprise;
|
||||
private readonly Galaxy _galaxy;
|
||||
private readonly Output _output;
|
||||
private bool _displayed = false;
|
||||
|
||||
public Quadrant(
|
||||
QuadrantInfo info,
|
||||
@@ -25,9 +26,11 @@ namespace SuperStarTrek.Space
|
||||
{
|
||||
_info = info;
|
||||
_random = random;
|
||||
_galaxy = galaxy;
|
||||
_output = output;
|
||||
Galaxy = galaxy;
|
||||
|
||||
_sectors = new() { [enterprise.Sector] = _enterprise = enterprise };
|
||||
info.MarkAsKnown();
|
||||
_sectors = new() { [enterprise.SectorCoordinates] = _enterprise = enterprise };
|
||||
PositionObject(sector => new Klingon(sector, _random), _info.KlingonCount);
|
||||
if (_info.HasStarbase)
|
||||
{
|
||||
@@ -41,10 +44,11 @@ namespace SuperStarTrek.Space
|
||||
public int KlingonCount => _info.KlingonCount;
|
||||
public bool HasStarbase => _info.HasStarbase;
|
||||
public Starbase Starbase { get; }
|
||||
internal Galaxy Galaxy { get; }
|
||||
public bool EnterpriseIsNextToStarbase =>
|
||||
_info.HasStarbase &&
|
||||
Math.Abs(_enterprise.Sector.X - Starbase.Sector.X) <= 1 &&
|
||||
Math.Abs(_enterprise.Sector.Y - Starbase.Sector.Y) <= 1;
|
||||
Math.Abs(_enterprise.SectorCoordinates.X - Starbase.Sector.X) <= 1 &&
|
||||
Math.Abs(_enterprise.SectorCoordinates.Y - Starbase.Sector.Y) <= 1;
|
||||
|
||||
internal IEnumerable<Klingon> Klingons => _sectors.Values.OfType<Klingon>();
|
||||
|
||||
@@ -65,6 +69,25 @@ namespace SuperStarTrek.Space
|
||||
}
|
||||
}
|
||||
|
||||
internal void Display(string textFormat)
|
||||
{
|
||||
if (_displayed) { return; }
|
||||
|
||||
_output.Write(textFormat, this);
|
||||
|
||||
if (_info.KlingonCount > 0)
|
||||
{
|
||||
_output.Write(Strings.CombatArea);
|
||||
if (_enterprise.ShieldControl.ShieldEnergy <= 200) { _output.Write(Strings.LowShields); }
|
||||
}
|
||||
|
||||
_enterprise.Execute(Command.SRS);
|
||||
|
||||
_displayed = true;
|
||||
}
|
||||
|
||||
internal bool HasObjectAt(Coordinates coordinates) => _sectors.ContainsKey(coordinates);
|
||||
|
||||
internal bool TorpedoCollisionAt(Coordinates coordinates, out string message, out bool gameOver)
|
||||
{
|
||||
gameOver = false;
|
||||
@@ -74,7 +97,7 @@ namespace SuperStarTrek.Space
|
||||
{
|
||||
case Klingon klingon:
|
||||
message = Remove(klingon);
|
||||
gameOver = _galaxy.KlingonCount == 0;
|
||||
gameOver = Galaxy.KlingonCount == 0;
|
||||
return true;
|
||||
|
||||
case Star _:
|
||||
@@ -85,8 +108,8 @@ namespace SuperStarTrek.Space
|
||||
_sectors.Remove(coordinates);
|
||||
_info.RemoveStarbase();
|
||||
message = "*** Starbase destroyed ***" +
|
||||
(_galaxy.StarbaseCount > 0 ? Strings.CourtMartial : Strings.RelievedOfCommand);
|
||||
gameOver = _galaxy.StarbaseCount == 0;
|
||||
(Galaxy.StarbaseCount > 0 ? Strings.CourtMartial : Strings.RelievedOfCommand);
|
||||
gameOver = Galaxy.StarbaseCount == 0;
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -101,6 +124,19 @@ namespace SuperStarTrek.Space
|
||||
return "*** Klingon destroyed ***";
|
||||
}
|
||||
|
||||
internal CommandResult KlingonsMoveAndFire()
|
||||
{
|
||||
foreach (var klingon in Klingons.ToList())
|
||||
{
|
||||
var newSector = GetRandomEmptySector();
|
||||
_sectors.Remove(klingon.Sector);
|
||||
_sectors[newSector] = klingon;
|
||||
klingon.MoveTo(newSector);
|
||||
}
|
||||
|
||||
return KlingonsFireOnEnterprise();
|
||||
}
|
||||
|
||||
internal CommandResult KlingonsFireOnEnterprise()
|
||||
{
|
||||
if (EnterpriseIsNextToStarbase && Klingons.Any())
|
||||
|
||||
@@ -41,11 +41,7 @@ namespace SuperStarTrek.Space
|
||||
|
||||
internal void AddStarbase() => HasStarbase = true;
|
||||
|
||||
internal Quadrant BuildQuadrant(Enterprise enterprise, Random random, Galaxy galaxy, Input input, Output output)
|
||||
{
|
||||
_isKnown = true;
|
||||
return new(this, enterprise, random, galaxy, input, output);
|
||||
}
|
||||
internal void MarkAsKnown() => _isKnown = true;
|
||||
|
||||
internal string Scan()
|
||||
{
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
||||
internal override void Execute(Quadrant quadrant)
|
||||
{
|
||||
Output.WriteLine("Direction/distance calculator:")
|
||||
.WriteLine($"You are at quadrant {_enterprise.Quadrant} sector {_enterprise.Sector}")
|
||||
.Write($"You are at quadrant {_enterprise.QuadrantCoordinates}")
|
||||
.WriteLine($" sector {_enterprise.SectorCoordinates}")
|
||||
.WriteLine("Please enter");
|
||||
|
||||
WriteDirectionAndDistance(
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
||||
|
||||
Output.WriteLine("From Enterprise to Starbase:");
|
||||
|
||||
WriteDirectionAndDistance(_enterprise.Sector, quadrant.Starbase.Sector);
|
||||
WriteDirectionAndDistance(_enterprise.SectorCoordinates, quadrant.Starbase.Sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
||||
|
||||
foreach (var klingon in quadrant.Klingons)
|
||||
{
|
||||
WriteDirectionAndDistance(_enterprise.Sector, klingon.Sector);
|
||||
WriteDirectionAndDistance(_enterprise.SectorCoordinates, klingon.Sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace SuperStarTrek.Systems
|
||||
|
||||
private void ResolveHitOn(Klingon klingon, float perEnemyStrength, Quadrant quadrant)
|
||||
{
|
||||
var distance = _enterprise.Sector.GetDistanceTo(klingon.Sector);
|
||||
var distance = _enterprise.SectorCoordinates.GetDistanceTo(klingon.Sector);
|
||||
var hitStrength = (int)(perEnemyStrength / distance * (2 + _random.GetFloat()));
|
||||
|
||||
if (klingon.TakeHit(hitStrength))
|
||||
|
||||
@@ -34,15 +34,14 @@ namespace SuperStarTrek.Systems
|
||||
|
||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||
{
|
||||
if (!_input.TryGetNumber("Photon torpedo course", 1, 9, out var direction))
|
||||
if (!_input.TryGetCourse("Photon torpedo course", "Ensign Chekov", out var course))
|
||||
{
|
||||
_output.WriteLine("Ensign Chekov reports, 'Incorrect course data, sir!'");
|
||||
return CommandResult.Ok;
|
||||
}
|
||||
|
||||
var isHit = false;
|
||||
_output.WriteLine("Torpedo track:");
|
||||
foreach (var sector in new Course(direction).GetSectorsFrom(_enterprise.Sector))
|
||||
foreach (var sector in course.GetSectorsFrom(_enterprise.SectorCoordinates))
|
||||
{
|
||||
_output.WriteLine($" {sector}");
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace SuperStarTrek.Systems
|
||||
{
|
||||
yield return $"Stardate {_game.Stardate}";
|
||||
yield return $"Condition {_enterprise.Condition}";
|
||||
yield return $"Quadrant {_enterprise.Quadrant}";
|
||||
yield return $"Sector {_enterprise.Sector}";
|
||||
yield return $"Quadrant {_enterprise.QuadrantCoordinates}";
|
||||
yield return $"Sector {_enterprise.SectorCoordinates}";
|
||||
yield return $"Photon torpedoes {_enterprise.TorpedoCount}";
|
||||
yield return $"Total energy {Math.Ceiling(_enterprise.TotalEnergy)}";
|
||||
yield return $"Shields {(int)_enterprise.ShieldControl.ShieldEnergy}";
|
||||
|
||||
@@ -41,13 +41,26 @@ namespace SuperStarTrek.Systems
|
||||
|
||||
public virtual void Repair()
|
||||
{
|
||||
if (IsDamaged) { Condition = 0; }
|
||||
if (IsDamaged)
|
||||
{
|
||||
Condition = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal void TakeDamage(float damage)
|
||||
public virtual bool Repair(float repairWorkDone)
|
||||
{
|
||||
Condition -= damage;
|
||||
_output.WriteLine($"Damage Control reports, '{Name} damaged by the hit.'");
|
||||
if (IsDamaged)
|
||||
{
|
||||
Condition += repairWorkDone;
|
||||
if (Condition > -0.1f && Condition < 0)
|
||||
{
|
||||
Condition = -0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
return !IsDamaged;
|
||||
}
|
||||
|
||||
internal void TakeDamage(float damage) => Condition -= damage;
|
||||
}
|
||||
}
|
||||
|
||||
75
84 Super Star Trek/csharp/Systems/WarpEngines.cs
Normal file
75
84 Super Star Trek/csharp/Systems/WarpEngines.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using SuperStarTrek.Commands;
|
||||
using SuperStarTrek.Objects;
|
||||
using SuperStarTrek.Space;
|
||||
|
||||
namespace SuperStarTrek.Systems
|
||||
{
|
||||
internal class WarpEngines : Subsystem
|
||||
{
|
||||
private readonly Enterprise _enterprise;
|
||||
private readonly Output _output;
|
||||
private readonly Input _input;
|
||||
|
||||
public WarpEngines(Enterprise enterprise, Output output, Input input)
|
||||
: base("Warp Engines", Command.NAV, output)
|
||||
{
|
||||
_enterprise = enterprise;
|
||||
_output = output;
|
||||
_input = input;
|
||||
}
|
||||
|
||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||
{
|
||||
if (_input.TryGetCourse("Course", " Lt. Sulu", out var course) &&
|
||||
TryGetWarpFactor(out var warpFactor) &&
|
||||
TryGetDistanceToMove(warpFactor, out var distanceToMove))
|
||||
{
|
||||
var result = quadrant.KlingonsMoveAndFire();
|
||||
if (result.IsGameOver) { return result; }
|
||||
|
||||
_enterprise.RepairSystems(warpFactor);
|
||||
_enterprise.VaryConditionOfRandomSystem();
|
||||
var timeElapsed = _enterprise.Move(course, warpFactor, distanceToMove);
|
||||
|
||||
return CommandResult.Elapsed(timeElapsed);
|
||||
}
|
||||
|
||||
return CommandResult.Ok;
|
||||
}
|
||||
|
||||
private bool TryGetWarpFactor(out float warpFactor)
|
||||
{
|
||||
var maximumWarp = IsDamaged ? 0.2f : 8;
|
||||
if (_input.TryGetNumber("Warp Factor", 0, maximumWarp, out warpFactor))
|
||||
{
|
||||
return warpFactor > 0;
|
||||
}
|
||||
|
||||
_output.WriteLine(
|
||||
IsDamaged && warpFactor > maximumWarp
|
||||
? "Warp engines are damaged. Maximum speed = warp 0.2"
|
||||
: $" Chief Engineer Scott reports, 'The engines won't take warp {warpFactor} !'");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetDistanceToMove(float warpFactor, out int distanceToTravel)
|
||||
{
|
||||
distanceToTravel = (int)Math.Round(warpFactor * 8, MidpointRounding.AwayFromZero);
|
||||
if (distanceToTravel <= _enterprise.Energy) { return true; }
|
||||
|
||||
_output.WriteLine("Engineering reports, 'Insufficient energy available")
|
||||
.WriteLine($" for maneuvering at warp {warpFactor} !'");
|
||||
|
||||
if (distanceToTravel <= _enterprise.TotalEnergy && !_enterprise.ShieldControl.IsDamaged)
|
||||
{
|
||||
_output.Write($"Deflector control room acknowledges {_enterprise.ShieldControl.ShieldEnergy} ")
|
||||
.WriteLine("units of energy")
|
||||
.WriteLine(" presently deployed to shields.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user