mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
Add Damage Control
This commit is contained in:
@@ -33,11 +33,7 @@ namespace SuperStarTrek
|
||||
{
|
||||
_output.Write(Strings.Title);
|
||||
|
||||
_output.Write("Do you need instructions (Y/N)? ");
|
||||
var response = Console.ReadLine();
|
||||
_output.WriteLine();
|
||||
|
||||
if (!response.Equals("N", InvariantCultureIgnoreCase))
|
||||
if (_input.GetYesNo("Do you need instructions", Input.YesNoMode.FalseOnN))
|
||||
{
|
||||
_output.Write(Strings.Instructions);
|
||||
|
||||
@@ -68,7 +64,16 @@ namespace SuperStarTrek
|
||||
{
|
||||
var command = _input.GetCommand();
|
||||
|
||||
gameOver = command == Command.XXX || _enterprise.Execute(command);
|
||||
gameOver = command == Command.XXX || _enterprise.Execute(command) || CheckIfStranded();
|
||||
}
|
||||
|
||||
if (_galaxy.KlingonCount > 0)
|
||||
{
|
||||
_output.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
_output.Write(Strings.Congratulations, GetEfficiency());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +91,29 @@ namespace SuperStarTrek
|
||||
_initialKlingonCount = _galaxy.KlingonCount;
|
||||
|
||||
_enterprise = new Enterprise(3000, random.GetCoordinate());
|
||||
_enterprise.Add(new ShortRangeSensors(_enterprise, _galaxy, this, _output))
|
||||
.Add(new ShieldControl(_enterprise, _output, _input));
|
||||
_enterprise
|
||||
.Add(new ShortRangeSensors(_enterprise, _galaxy, this, _output))
|
||||
.Add(new ShieldControl(_enterprise, _output, _input))
|
||||
.Add(new DamageControl(_enterprise, _output));
|
||||
|
||||
return new Quadrant(_galaxy[_currentQuadrant], _enterprise);
|
||||
}
|
||||
|
||||
public bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye");
|
||||
|
||||
private bool CheckIfStranded()
|
||||
{
|
||||
if (_enterprise.TotalEnergy < 10 ||
|
||||
_enterprise.Energy < 10 && _enterprise.Shields.IsDamaged)
|
||||
{
|
||||
_output.Write(Strings.Stranded);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private double GetEfficiency() =>
|
||||
1000 * Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,5 +72,26 @@ namespace SuperStarTrek
|
||||
_output.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetYesNo(string prompt, YesNoMode mode)
|
||||
{
|
||||
_output.Prompt($"{prompt} (Y/N)");
|
||||
var response = Console.ReadLine().ToUpperInvariant();
|
||||
|
||||
return (mode, response) switch
|
||||
{
|
||||
(YesNoMode.FalseOnN, "N") => false,
|
||||
(YesNoMode.FalseOnN, _) => true,
|
||||
(YesNoMode.TrueOnY, "Y") => true,
|
||||
(YesNoMode.TrueOnY, _) => false,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Invalid value")
|
||||
};
|
||||
}
|
||||
|
||||
public enum YesNoMode
|
||||
{
|
||||
TrueOnY,
|
||||
FalseOnN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SuperStarTrek.Resources;
|
||||
using SuperStarTrek.Space;
|
||||
@@ -13,7 +14,6 @@ namespace SuperStarTrek.Objects
|
||||
private readonly List<Subsystem> _systems;
|
||||
private readonly Dictionary<Command, Subsystem> _commandExecutors;
|
||||
private Quadrant _quadrant;
|
||||
private ShieldControl _shieldControl;
|
||||
|
||||
public Enterprise(int maxEnergy, Coordinates sector)
|
||||
{
|
||||
@@ -27,11 +27,12 @@ namespace SuperStarTrek.Objects
|
||||
public Coordinates Quadrant => _quadrant.Coordinates;
|
||||
public Coordinates Sector { get; }
|
||||
public string Condition => GetCondition();
|
||||
public double Shields => _shieldControl.Energy;
|
||||
public double Energy => TotalEnergy - Shields;
|
||||
public ShieldControl Shields => (ShieldControl)_commandExecutors[Command.SHE];
|
||||
public double Energy => TotalEnergy - Shields.Energy;
|
||||
public double TotalEnergy { get; private set; }
|
||||
public int DamagedSystemCount => _systems.Count(s => s.IsDamaged);
|
||||
public IEnumerable<Subsystem> Systems => _systems;
|
||||
public int TorpedoCount { get; }
|
||||
|
||||
public bool IsDocked { get; private set; }
|
||||
|
||||
public Enterprise Add(Subsystem system)
|
||||
@@ -39,23 +40,9 @@ namespace SuperStarTrek.Objects
|
||||
_systems.Add(system);
|
||||
_commandExecutors[system.Command] = system;
|
||||
|
||||
if (system is ShieldControl shieldControl) { _shieldControl = shieldControl; }
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public string GetDamageReport()
|
||||
{
|
||||
var report = new StringBuilder();
|
||||
report.AppendLine().AppendLine().AppendLine("Device State of Repair");
|
||||
foreach (var system in _systems)
|
||||
{
|
||||
report.Append(system.Name.PadRight(25)).AppendLine(system.Condition.ToString(" 0.00;-0.00"));
|
||||
}
|
||||
report.AppendLine();
|
||||
return report.ToString();
|
||||
}
|
||||
|
||||
public void Enter(Quadrant quadrant, string entryTextFormat)
|
||||
{
|
||||
_quadrant = quadrant;
|
||||
@@ -66,7 +53,7 @@ namespace SuperStarTrek.Objects
|
||||
if (quadrant.HasKlingons)
|
||||
{
|
||||
_output.Write(Strings.CombatArea);
|
||||
if (Shields <= 200) { _output.Write(Strings.LowShields); }
|
||||
if (Shields.Energy <= 200) { _output.Write(Strings.LowShields); }
|
||||
}
|
||||
|
||||
IsDocked = quadrant.EnterpriseIsNextToStarbase;
|
||||
|
||||
@@ -1,7 +1,38 @@
|
||||
using SuperStarTrek.Resources;
|
||||
|
||||
namespace SuperStarTrek.Objects
|
||||
{
|
||||
internal class Starbase
|
||||
{
|
||||
private readonly Input _input;
|
||||
private readonly Output _output;
|
||||
private readonly double _repairDelay;
|
||||
|
||||
public Starbase(Random random, Input input)
|
||||
{
|
||||
_repairDelay = random.GetDouble() * 0.5;
|
||||
_input = input;
|
||||
}
|
||||
|
||||
public override string ToString() => ">!<";
|
||||
|
||||
internal bool TryRepair(Enterprise enterprise, out double repairTime)
|
||||
{
|
||||
repairTime = enterprise.DamagedSystemCount * 0.1 + _repairDelay;
|
||||
if (repairTime >= 1) { repairTime = 0.9; }
|
||||
|
||||
_output.Write(Strings.RepairEstimate, repairTime);
|
||||
if (_input.GetYesNo(Strings.RepairPrompt, Input.YesNoMode.TrueOnY))
|
||||
{
|
||||
foreach (var system in enterprise.Systems)
|
||||
{
|
||||
system.Repair();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
repairTime = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,37 @@ namespace SuperStarTrek
|
||||
{
|
||||
internal class Output
|
||||
{
|
||||
public void Write(string text) => Console.Write(text);
|
||||
public void Write(string format, params object[] args) => Console.Write(format, args);
|
||||
public void WriteLine(string text = "") => Console.WriteLine(text);
|
||||
public Output Write(string text)
|
||||
{
|
||||
Console.Write(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void NextLine() => Console.WriteLine();
|
||||
public Output Write(string format, params object[] args)
|
||||
{
|
||||
Console.Write(format, args);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Output WriteLine(string text = "")
|
||||
{
|
||||
Console.WriteLine(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Output NextLine()
|
||||
{
|
||||
Console.WriteLine();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Output Prompt(string text = "")
|
||||
{
|
||||
Console.Write($"{text}? ");
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Prompt(string text = "") => Console.Write($"{text}? ");
|
||||
}
|
||||
}
|
||||
|
||||
4
84 Super Star Trek/csharp/Resources/Congratulations.txt
Normal file
4
84 Super Star Trek/csharp/Resources/Congratulations.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Congratulations, Captain! The last Klingon battle cruiser
|
||||
menacing the Federation has been destroyed.
|
||||
|
||||
Your efficiency rating is {0}.
|
||||
1
84 Super Star Trek/csharp/Resources/Destroyed.txt
Normal file
1
84 Super Star Trek/csharp/Resources/Destroyed.txt
Normal file
@@ -0,0 +1 @@
|
||||
The Enterprise has been destroyed. The Federation will be conquered.
|
||||
3
84 Super Star Trek/csharp/Resources/EndOfMission.txt
Normal file
3
84 Super Star Trek/csharp/Resources/EndOfMission.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Is is stardate {0}.
|
||||
There were {1} Klingon battle cruisers left at
|
||||
the end of your mission.
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
INSTRUCTIONS FOR 'SUPER STAR TREK'
|
||||
|
||||
1. When you see "Command ?" printed, enter one of the legal
|
||||
|
||||
2
84 Super Star Trek/csharp/Resources/RepairEstimate.txt
Normal file
2
84 Super Star Trek/csharp/Resources/RepairEstimate.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Technicians standing by to effect repairs to your ship;
|
||||
Estimated time to repair: {0} stardates.
|
||||
1
84 Super Star Trek/csharp/Resources/RepairPrompt.txt
Normal file
1
84 Super Star Trek/csharp/Resources/RepairPrompt.txt
Normal file
@@ -0,0 +1 @@
|
||||
Will you authorize the repair order (Y/N)
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
The Federation is in need of a new starship commander
|
||||
for a similar mission -- if there is a volunteer
|
||||
let him step forward and enter 'Aye'
|
||||
3
84 Super Star Trek/csharp/Resources/Stranded.txt
Normal file
3
84 Super Star Trek/csharp/Resources/Stranded.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
** FATAL ERROR ** You've just stranded your ship in space
|
||||
You have insufficient maneuvering energy, and shield control
|
||||
is presently incapable of cross-circuiting to engine room!!
|
||||
@@ -7,14 +7,20 @@ namespace SuperStarTrek.Resources
|
||||
internal static class Strings
|
||||
{
|
||||
public static string CombatArea => GetResource();
|
||||
public static string Congratulations => GetResource();
|
||||
public static string Destroyed => GetResource();
|
||||
public static string EndOfMission => GetResource();
|
||||
public static string Enterprise => GetResource();
|
||||
public static string Instructions => GetResource();
|
||||
public static string LowShields => GetResource();
|
||||
public static string Orders => GetResource();
|
||||
public static string RepairEstimate => GetResource();
|
||||
public static string RepairPrompt => GetResource();
|
||||
public static string ReplayPrompt => GetResource();
|
||||
public static string ShieldsDropped => GetResource();
|
||||
public static string ShortRangeSensorsOut => GetResource();
|
||||
public static string StartText => GetResource();
|
||||
public static string Stranded => GetResource();
|
||||
public static string Title => GetResource();
|
||||
|
||||
private static string GetResource([CallerMemberName] string name = "")
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace SuperStarTrek.Space
|
||||
PositionObject(() => new Klingon(), _info.KlingonCount);
|
||||
if (_info.HasStarbase)
|
||||
{
|
||||
_starbaseSector = PositionObject(() => new Starbase());
|
||||
_starbaseSector = PositionObject(() => new Starbase(_random, new Input(new Output())));
|
||||
}
|
||||
PositionObject(() => new Star(), _info.StarCount);
|
||||
}
|
||||
@@ -31,6 +31,7 @@ namespace SuperStarTrek.Space
|
||||
public Coordinates Coordinates => _info.Coordinates;
|
||||
public bool HasKlingons => _info.KlingonCount > 0;
|
||||
public bool HasStarbase => _info.HasStarbase;
|
||||
public Starbase Starbase => HasStarbase ? (Starbase)_sectors[_starbaseSector] : null;
|
||||
public bool EnterpriseIsNextToStarbase =>
|
||||
_info.HasStarbase &&
|
||||
Math.Abs(_enterpriseSector.X - _starbaseSector.X) <= 1 &&
|
||||
|
||||
49
84 Super Star Trek/csharp/Systems/DamageControl.cs
Normal file
49
84 Super Star Trek/csharp/Systems/DamageControl.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using SuperStarTrek.Objects;
|
||||
using SuperStarTrek.Space;
|
||||
|
||||
namespace SuperStarTrek.Systems
|
||||
{
|
||||
internal class DamageControl : Subsystem
|
||||
{
|
||||
private readonly Enterprise _enterprise;
|
||||
private readonly Output _output;
|
||||
|
||||
public DamageControl(Enterprise enterprise, Output output)
|
||||
: base("Damage Control", Command.DAM)
|
||||
{
|
||||
_enterprise = enterprise;
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public override void ExecuteCommand(Quadrant quadrant)
|
||||
{
|
||||
if (IsDamaged)
|
||||
{
|
||||
_output.WriteLine("Damage Control report not available");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteDamageReport();
|
||||
}
|
||||
|
||||
if (_enterprise.DamagedSystemCount > 0 && _enterprise.IsDocked)
|
||||
{
|
||||
if (quadrant.Starbase.TryRepair(_enterprise, out var repairTime))
|
||||
{
|
||||
WriteDamageReport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteDamageReport()
|
||||
{
|
||||
_output.NextLine().NextLine().WriteLine("Device State of Repair");
|
||||
foreach (var system in _enterprise.Systems)
|
||||
{
|
||||
_output.Write(system.Name.PadRight(25))
|
||||
.WriteLine(((int)(system.Condition * 100) * 0.01).ToString(" 0.##;-0.##"));
|
||||
}
|
||||
_output.NextLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,8 @@ namespace SuperStarTrek.Systems
|
||||
yield return $"Quadrant {_enterprise.Quadrant}";
|
||||
yield return $"Sector {_enterprise.Sector}";
|
||||
yield return $"Photon torpedoes {_enterprise.TorpedoCount}";
|
||||
yield return $"Total energy {Math.Ceiling(_enterprise.Energy)}";
|
||||
yield return $"Shields {(int)_enterprise.Shields}";
|
||||
yield return $"Total energy {Math.Ceiling(_enterprise.TotalEnergy)}";
|
||||
yield return $"Shields {(int)_enterprise.Shields.Energy}";
|
||||
yield return $"Klingons remaining {_galaxy.KlingonCount}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,14 @@ namespace SuperStarTrek.Systems
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public double Condition { get; }
|
||||
public double Condition { get; private set; }
|
||||
public bool IsDamaged => Condition < 0;
|
||||
public Command Command { get; }
|
||||
|
||||
public abstract void ExecuteCommand(Quadrant quadrant);
|
||||
public void Repair()
|
||||
{
|
||||
if (Condition < 0) { Condition = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user