mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
Use common library in SuperStarTrek
This commit is contained in:
@@ -12,4 +12,6 @@ public sealed class ConsoleIO : TextIO
|
|||||||
: base(Console.In, Console.Out)
|
: base(Console.In, Console.Out)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override char ReadCharacter() => Console.ReadKey(intercept: true).KeyChar;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ namespace Games.Common.IO;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IReadWrite
|
public interface IReadWrite
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a character from input.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The character read.</returns>
|
||||||
|
char ReadCharacter();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a <see cref="float" /> value from input.
|
/// Reads a <see cref="float" /> value from input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -99,6 +105,13 @@ public interface IReadWrite
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="format">The format <see cref="string" /> to be written.</param>
|
/// <param name="format">The format <see cref="string" /> to be written.</param>
|
||||||
/// <param name="value">The values to be inserted into the format.</param>
|
/// <param name="value">The values to be inserted into the format.</param>
|
||||||
|
void Write(string format, params object[] values);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a formatted string to output followed by a new-line.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">The format <see cref="string" /> to be written.</param>
|
||||||
|
/// <param name="value">The values to be inserted into the format.</param>
|
||||||
void WriteLine(string format, params object[] values);
|
void WriteLine(string format, params object[] values);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ public class TextIO : IReadWrite
|
|||||||
_numberTokenReader = TokenReader.ForNumbers(this);
|
_numberTokenReader = TokenReader.ForNumbers(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual char ReadCharacter()
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
var ch = _input.Read();
|
||||||
|
if (ch != -1) { return (char)ch; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float ReadNumber(string prompt) => ReadNumbers(prompt, 1)[0];
|
public float ReadNumber(string prompt) => ReadNumbers(prompt, 1)[0];
|
||||||
|
|
||||||
public (float, float) Read2Numbers(string prompt)
|
public (float, float) Read2Numbers(string prompt)
|
||||||
@@ -99,6 +108,8 @@ public class TextIO : IReadWrite
|
|||||||
|
|
||||||
public void WriteLine(object value) => _output.WriteLine(value.ToString());
|
public void WriteLine(object value) => _output.WriteLine(value.ToString());
|
||||||
|
|
||||||
|
public void Write(string format, params object[] values) => _output.Write(format, values);
|
||||||
|
|
||||||
public void WriteLine(string format, params object[] values) => _output.WriteLine(format, values);
|
public void WriteLine(string format, params object[] values) => _output.WriteLine(format, values);
|
||||||
|
|
||||||
public void Write(Stream stream, bool keepOpen = false)
|
public void Write(Stream stream, bool keepOpen = false)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace SuperStarTrek.Commands
|
namespace SuperStarTrek.Commands;
|
||||||
{
|
|
||||||
internal enum Command
|
internal enum Command
|
||||||
{
|
{
|
||||||
[Description("To set course")]
|
[Description("To set course")]
|
||||||
@@ -31,4 +31,3 @@ namespace SuperStarTrek.Commands
|
|||||||
[Description("To resign your command")]
|
[Description("To resign your command")]
|
||||||
XXX
|
XXX
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace SuperStarTrek.Commands
|
namespace SuperStarTrek.Commands;
|
||||||
{
|
|
||||||
internal static class CommandExtensions
|
internal static class CommandExtensions
|
||||||
{
|
{
|
||||||
internal static string GetDescription(this Command command) =>
|
internal static string GetDescription(this Command command) =>
|
||||||
@@ -11,4 +11,3 @@ namespace SuperStarTrek.Commands
|
|||||||
.GetCustomAttribute<DescriptionAttribute>()
|
.GetCustomAttribute<DescriptionAttribute>()
|
||||||
.Description;
|
.Description;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace SuperStarTrek.Commands
|
namespace SuperStarTrek.Commands;
|
||||||
{
|
|
||||||
internal class CommandResult
|
internal class CommandResult
|
||||||
{
|
{
|
||||||
public static readonly CommandResult Ok = new(false);
|
public static readonly CommandResult Ok = new(false);
|
||||||
@@ -20,4 +20,3 @@ namespace SuperStarTrek.Commands
|
|||||||
|
|
||||||
public static CommandResult Elapsed(float timeElapsed) => new(timeElapsed);
|
public static CommandResult Elapsed(float timeElapsed) => new(timeElapsed);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Games.Common.IO;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
using SuperStarTrek.Systems;
|
using SuperStarTrek.Systems;
|
||||||
using SuperStarTrek.Systems.ComputerFunctions;
|
using SuperStarTrek.Systems.ComputerFunctions;
|
||||||
|
|
||||||
namespace SuperStarTrek
|
namespace SuperStarTrek;
|
||||||
{
|
|
||||||
internal class Game
|
internal class Game
|
||||||
{
|
{
|
||||||
private readonly Output _output;
|
private readonly TextIO _io;
|
||||||
private readonly Input _input;
|
private readonly IRandom _random;
|
||||||
private readonly Random _random;
|
|
||||||
|
|
||||||
private int _initialStardate;
|
private int _initialStardate;
|
||||||
private int _finalStarDate;
|
private int _finalStarDate;
|
||||||
@@ -21,10 +22,9 @@ namespace SuperStarTrek
|
|||||||
private int _initialKlingonCount;
|
private int _initialKlingonCount;
|
||||||
private Enterprise _enterprise;
|
private Enterprise _enterprise;
|
||||||
|
|
||||||
internal Game(Output output, Input input, Random random)
|
internal Game(TextIO io, IRandom random)
|
||||||
{
|
{
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
_random = random;
|
_random = random;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ namespace SuperStarTrek
|
|||||||
|
|
||||||
internal void DoIntroduction()
|
internal void DoIntroduction()
|
||||||
{
|
{
|
||||||
_output.Write(Strings.Title);
|
_io.Write(Strings.Title);
|
||||||
|
|
||||||
if (_input.GetYesNo("Do you need instructions", Input.YesNoMode.FalseOnN))
|
if (_io.GetYesNo("Do you need instructions", IReadWriteExtensions.YesNoMode.FalseOnN))
|
||||||
{
|
{
|
||||||
_output.Write(Strings.Instructions);
|
_io.Write(Strings.Instructions);
|
||||||
|
|
||||||
_input.WaitForAnyKeyButEnter("to continue");
|
_io.WaitForAnyKeyButEnter("to continue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ namespace SuperStarTrek
|
|||||||
|
|
||||||
while (!gameOver)
|
while (!gameOver)
|
||||||
{
|
{
|
||||||
var command = _input.GetCommand();
|
var command = _io.ReadCommand();
|
||||||
|
|
||||||
var result = _enterprise.Execute(command);
|
var result = _enterprise.Execute(command);
|
||||||
|
|
||||||
@@ -62,45 +62,44 @@ namespace SuperStarTrek
|
|||||||
|
|
||||||
if (_galaxy.KlingonCount > 0)
|
if (_galaxy.KlingonCount > 0)
|
||||||
{
|
{
|
||||||
_output.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount);
|
_io.Write(Strings.EndOfMission, _currentStardate, _galaxy.KlingonCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_output.Write(Strings.Congratulations, GetEfficiency());
|
_io.Write(Strings.Congratulations, CalculateEfficiency());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialise()
|
private void Initialise()
|
||||||
{
|
{
|
||||||
_currentStardate = _initialStardate = _random.GetInt(20, 40) * 100;
|
_currentStardate = _initialStardate = _random.Next(20, 40) * 100;
|
||||||
_finalStarDate = _initialStardate + _random.GetInt(25, 35);
|
_finalStarDate = _initialStardate + _random.Next(25, 35);
|
||||||
|
|
||||||
_currentQuadrant = _random.GetCoordinate();
|
_currentQuadrant = _random.NextCoordinate();
|
||||||
|
|
||||||
_galaxy = new Galaxy(_random);
|
_galaxy = new Galaxy(_random);
|
||||||
_initialKlingonCount = _galaxy.KlingonCount;
|
_initialKlingonCount = _galaxy.KlingonCount;
|
||||||
|
|
||||||
_enterprise = new Enterprise(3000, _random.GetCoordinate(), _output, _random, _input);
|
_enterprise = new Enterprise(3000, _random.NextCoordinate(), _io, _random);
|
||||||
_enterprise
|
_enterprise
|
||||||
.Add(new WarpEngines(_enterprise, _output, _input))
|
.Add(new WarpEngines(_enterprise, _io))
|
||||||
.Add(new ShortRangeSensors(_enterprise, _galaxy, this, _output))
|
.Add(new ShortRangeSensors(_enterprise, _galaxy, this, _io))
|
||||||
.Add(new LongRangeSensors(_galaxy, _output))
|
.Add(new LongRangeSensors(_galaxy, _io))
|
||||||
.Add(new PhaserControl(_enterprise, _output, _input, _random))
|
.Add(new PhaserControl(_enterprise, _io, _random))
|
||||||
.Add(new PhotonTubes(10, _enterprise, _output, _input))
|
.Add(new PhotonTubes(10, _enterprise, _io))
|
||||||
.Add(new ShieldControl(_enterprise, _output, _input))
|
.Add(new ShieldControl(_enterprise, _io))
|
||||||
.Add(new DamageControl(_enterprise, _output))
|
.Add(new DamageControl(_enterprise, _io))
|
||||||
.Add(new LibraryComputer(
|
.Add(new LibraryComputer(
|
||||||
_output,
|
_io,
|
||||||
_input,
|
new CumulativeGalacticRecord(_io, _galaxy),
|
||||||
new CumulativeGalacticRecord(_output, _galaxy),
|
new StatusReport(this, _galaxy, _enterprise, _io),
|
||||||
new StatusReport(this, _galaxy, _enterprise, _output),
|
new TorpedoDataCalculator(_enterprise, _io),
|
||||||
new TorpedoDataCalculator(_enterprise, _output),
|
new StarbaseDataCalculator(_enterprise, _io),
|
||||||
new StarbaseDataCalculator(_enterprise, _output),
|
new DirectionDistanceCalculator(_enterprise, _io),
|
||||||
new DirectionDistanceCalculator(_enterprise, _output, _input),
|
new GalaxyRegionMap(_io, _galaxy)));
|
||||||
new GalaxyRegionMap(_output, _galaxy)));
|
|
||||||
|
|
||||||
_output.Write(Strings.Enterprise);
|
_io.Write(Strings.Enterprise);
|
||||||
_output.Write(
|
_io.Write(
|
||||||
Strings.Orders,
|
Strings.Orders,
|
||||||
_galaxy.KlingonCount,
|
_galaxy.KlingonCount,
|
||||||
_finalStarDate,
|
_finalStarDate,
|
||||||
@@ -109,23 +108,21 @@ namespace SuperStarTrek
|
|||||||
_galaxy.StarbaseCount,
|
_galaxy.StarbaseCount,
|
||||||
_galaxy.StarbaseCount > 1 ? "s" : "");
|
_galaxy.StarbaseCount > 1 ? "s" : "");
|
||||||
|
|
||||||
_input.WaitForAnyKeyButEnter("when ready to accept command");
|
_io.WaitForAnyKeyButEnter("when ready to accept command");
|
||||||
|
|
||||||
_enterprise.StartIn(BuildCurrentQuadrant());
|
_enterprise.StartIn(BuildCurrentQuadrant());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Quadrant BuildCurrentQuadrant() =>
|
private Quadrant BuildCurrentQuadrant() => new(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _io);
|
||||||
new Quadrant(_galaxy[_currentQuadrant], _enterprise, _random, _galaxy, _input, _output);
|
|
||||||
|
|
||||||
internal bool Replay() => _galaxy.StarbaseCount > 0 && _input.GetString(Strings.ReplayPrompt, "Aye");
|
internal bool Replay() => _galaxy.StarbaseCount > 0 && _io.ReadExpectedString(Strings.ReplayPrompt, "Aye");
|
||||||
|
|
||||||
private bool CheckIfStranded()
|
private bool CheckIfStranded()
|
||||||
{
|
{
|
||||||
if (_enterprise.IsStranded) { _output.Write(Strings.Stranded); }
|
if (_enterprise.IsStranded) { _io.Write(Strings.Stranded); }
|
||||||
return _enterprise.IsStranded;
|
return _enterprise.IsStranded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetEfficiency() =>
|
private float CalculateEfficiency() =>
|
||||||
1000 * (float)Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2);
|
1000 * (float)Math.Pow(_initialKlingonCount / (_currentStardate - _initialStardate), 2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
16
84_Super_Star_Trek/csharp/IRandomExtensions.cs
Normal file
16
84_Super_Star_Trek/csharp/IRandomExtensions.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using Games.Common.Randomness;
|
||||||
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
|
namespace SuperStarTrek;
|
||||||
|
|
||||||
|
internal static class IRandomExtensions
|
||||||
|
{
|
||||||
|
internal static Coordinates NextCoordinate(this IRandom random) =>
|
||||||
|
new Coordinates(random.Next1To8Inclusive() - 1, random.Next1To8Inclusive() - 1);
|
||||||
|
|
||||||
|
// Duplicates the algorithm used in the original code to get an integer value from 1 to 8, inclusive:
|
||||||
|
// 475 DEF FNR(R)=INT(RND(R)*7.98+1.01)
|
||||||
|
// Returns a value from 1 to 8, inclusive.
|
||||||
|
// Note there's a slight bias away from the extreme values, 1 and 8.
|
||||||
|
internal static int Next1To8Inclusive(this IRandom random) => (int)(random.NextFloat() * 7.98 + 1.01);
|
||||||
|
}
|
||||||
89
84_Super_Star_Trek/csharp/IReadWriteExtensions.cs
Normal file
89
84_Super_Star_Trek/csharp/IReadWriteExtensions.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
|
using SuperStarTrek.Commands;
|
||||||
|
using SuperStarTrek.Space;
|
||||||
|
using static System.StringComparison;
|
||||||
|
|
||||||
|
namespace SuperStarTrek;
|
||||||
|
|
||||||
|
internal static class IReadWriteExtensions
|
||||||
|
{
|
||||||
|
internal static void WaitForAnyKeyButEnter(this IReadWrite io, string prompt)
|
||||||
|
{
|
||||||
|
io.Write($"Hit any key but Enter {prompt} ");
|
||||||
|
while (io.ReadCharacter() == '\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static (float X, float Y) GetCoordinates(this IReadWrite io, string prompt) =>
|
||||||
|
io.Read2Numbers($"{prompt} (X,Y)");
|
||||||
|
|
||||||
|
internal static bool TryReadNumberInRange(
|
||||||
|
this IReadWrite io,
|
||||||
|
string prompt,
|
||||||
|
float minValue,
|
||||||
|
float maxValue,
|
||||||
|
out float value)
|
||||||
|
{
|
||||||
|
value = io.ReadNumber($"{prompt} ({minValue}-{maxValue})");
|
||||||
|
|
||||||
|
return value >= minValue && value <= maxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool ReadExpectedString(this IReadWrite io, string prompt, string trueValue) =>
|
||||||
|
io.ReadString(prompt).Equals(trueValue, InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
|
internal static Command ReadCommand(this IReadWrite io)
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
var response = io.ReadString("Command");
|
||||||
|
|
||||||
|
if (response.Length >= 3 &&
|
||||||
|
Enum.TryParse(response.Substring(0, 3), ignoreCase: true, out Command parsedCommand))
|
||||||
|
{
|
||||||
|
return parsedCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
io.WriteLine("Enter one of the following:");
|
||||||
|
foreach (var command in Enum.GetValues(typeof(Command)).OfType<Command>())
|
||||||
|
{
|
||||||
|
io.WriteLine($" {command} ({command.GetDescription()})");
|
||||||
|
}
|
||||||
|
io.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryReadCourse(this IReadWrite io, string prompt, string officer, out Course course)
|
||||||
|
{
|
||||||
|
if (!io.TryReadNumberInRange(prompt, 1, 9, out var direction))
|
||||||
|
{
|
||||||
|
io.WriteLine($"{officer} reports, 'Incorrect course data, sir!'");
|
||||||
|
course = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
course = new Course(direction);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool GetYesNo(this IReadWrite io, string prompt, YesNoMode mode)
|
||||||
|
{
|
||||||
|
var response = io.ReadString($"{prompt} (Y/N)").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")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum YesNoMode
|
||||||
|
{
|
||||||
|
TrueOnY,
|
||||||
|
FalseOnN
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using SuperStarTrek.Commands;
|
|
||||||
using SuperStarTrek.Space;
|
|
||||||
using static System.StringComparison;
|
|
||||||
|
|
||||||
namespace SuperStarTrek
|
|
||||||
{
|
|
||||||
internal class Input
|
|
||||||
{
|
|
||||||
private readonly Output _output;
|
|
||||||
|
|
||||||
internal Input(Output output)
|
|
||||||
{
|
|
||||||
_output = output;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void WaitForAnyKeyButEnter(string prompt)
|
|
||||||
{
|
|
||||||
_output.Write($"Hit any key but Enter {prompt} ");
|
|
||||||
while (Console.ReadKey(intercept: true).Key == ConsoleKey.Enter);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal string GetString(string prompt)
|
|
||||||
{
|
|
||||||
_output.Prompt(prompt);
|
|
||||||
return Console.ReadLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal float GetNumber(string prompt)
|
|
||||||
{
|
|
||||||
_output.Prompt(prompt);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var response = Console.ReadLine();
|
|
||||||
if (float.TryParse(response, out var value))
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
_output.WriteLine("!Number expected - retry input line");
|
|
||||||
_output.Prompt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal (float X, float Y) GetCoordinates(string prompt)
|
|
||||||
{
|
|
||||||
_output.Prompt($"{prompt} (X,Y)");
|
|
||||||
var responses = ReadNumbers(2);
|
|
||||||
return (responses[0], responses[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool TryGetNumber(string prompt, float minValue, float maxValue, out float value)
|
|
||||||
{
|
|
||||||
value = GetNumber($"{prompt} ({minValue}-{maxValue})");
|
|
||||||
|
|
||||||
return value >= minValue && value <= maxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool GetString(string replayPrompt, string trueValue) =>
|
|
||||||
GetString(replayPrompt).Equals(trueValue, InvariantCultureIgnoreCase);
|
|
||||||
|
|
||||||
internal Command GetCommand()
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
var response = GetString("Command");
|
|
||||||
|
|
||||||
if (response.Length >= 3 &&
|
|
||||||
Enum.TryParse(response.Substring(0, 3), ignoreCase: true, out Command parsedCommand))
|
|
||||||
{
|
|
||||||
return parsedCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
_output.WriteLine("Enter one of the following:");
|
|
||||||
foreach (var command in Enum.GetValues(typeof(Command)).OfType<Command>())
|
|
||||||
{
|
|
||||||
_output.WriteLine($" {command} ({command.GetDescription()})");
|
|
||||||
}
|
|
||||||
_output.WriteLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal 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")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private float[] ReadNumbers(int quantity)
|
|
||||||
{
|
|
||||||
var numbers = new float[quantity];
|
|
||||||
var index = 0;
|
|
||||||
bool tryAgain;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
tryAgain = false;
|
|
||||||
var responses = Console.ReadLine().Split(',');
|
|
||||||
if (responses.Length > quantity)
|
|
||||||
{
|
|
||||||
_output.WriteLine("!Extra input ingored");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; index < responses.Length; index++)
|
|
||||||
{
|
|
||||||
if (!float.TryParse(responses[index], out numbers[index]))
|
|
||||||
{
|
|
||||||
_output.WriteLine("!Number expected - retry input line");
|
|
||||||
_output.Prompt();
|
|
||||||
tryAgain = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (tryAgain);
|
|
||||||
|
|
||||||
if (index < quantity)
|
|
||||||
{
|
|
||||||
_output.Prompt("?");
|
|
||||||
var responses = ReadNumbers(quantity - index);
|
|
||||||
for (int i = 0; i < responses.Length; i++, index++)
|
|
||||||
{
|
|
||||||
numbers[index] = responses[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return numbers;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum YesNoMode
|
|
||||||
{
|
|
||||||
TrueOnY,
|
|
||||||
FalseOnN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
using SuperStarTrek.Systems;
|
using SuperStarTrek.Systems;
|
||||||
|
|
||||||
namespace SuperStarTrek.Objects
|
namespace SuperStarTrek.Objects;
|
||||||
{
|
|
||||||
internal class Enterprise
|
internal class Enterprise
|
||||||
{
|
{
|
||||||
private readonly int _maxEnergy;
|
private readonly int _maxEnergy;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly List<Subsystem> _systems;
|
private readonly List<Subsystem> _systems;
|
||||||
private readonly Dictionary<Command, Subsystem> _commandExecutors;
|
private readonly Dictionary<Command, Subsystem> _commandExecutors;
|
||||||
private readonly Random _random;
|
private readonly IRandom _random;
|
||||||
private readonly Input _input;
|
|
||||||
private Quadrant _quadrant;
|
private Quadrant _quadrant;
|
||||||
|
|
||||||
public Enterprise(int maxEnergy, Coordinates sector, Output output, Random random, Input input)
|
public Enterprise(int maxEnergy, Coordinates sector, IReadWrite io, IRandom random)
|
||||||
{
|
{
|
||||||
SectorCoordinates = sector;
|
SectorCoordinates = sector;
|
||||||
TotalEnergy = _maxEnergy = maxEnergy;
|
TotalEnergy = _maxEnergy = maxEnergy;
|
||||||
|
|
||||||
_systems = new List<Subsystem>();
|
_systems = new List<Subsystem>();
|
||||||
_commandExecutors = new Dictionary<Command, Subsystem>();
|
_commandExecutors = new Dictionary<Command, Subsystem>();
|
||||||
_output = output;
|
_io = io;
|
||||||
_random = random;
|
_random = random;
|
||||||
_input = input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Quadrant Quadrant => _quadrant;
|
internal Quadrant Quadrant => _quadrant;
|
||||||
@@ -97,16 +97,16 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
internal CommandResult TakeHit(Coordinates sector, int hitStrength)
|
internal CommandResult TakeHit(Coordinates sector, int hitStrength)
|
||||||
{
|
{
|
||||||
_output.WriteLine($"{hitStrength} unit hit on Enterprise from sector {sector}");
|
_io.WriteLine($"{hitStrength} unit hit on Enterprise from sector {sector}");
|
||||||
ShieldControl.AbsorbHit(hitStrength);
|
ShieldControl.AbsorbHit(hitStrength);
|
||||||
|
|
||||||
if (ShieldControl.ShieldEnergy <= 0)
|
if (ShieldControl.ShieldEnergy <= 0)
|
||||||
{
|
{
|
||||||
_output.WriteLine(Strings.Destroyed);
|
_io.WriteLine(Strings.Destroyed);
|
||||||
return CommandResult.GameOver;
|
return CommandResult.GameOver;
|
||||||
}
|
}
|
||||||
|
|
||||||
_output.WriteLine($" <Shields down to {ShieldControl.ShieldEnergy} units>");
|
_io.WriteLine($" <Shields down to {ShieldControl.ShieldEnergy} units>");
|
||||||
|
|
||||||
if (hitStrength >= 20)
|
if (hitStrength >= 20)
|
||||||
{
|
{
|
||||||
@@ -119,14 +119,14 @@ namespace SuperStarTrek.Objects
|
|||||||
private void TakeDamage(float hitStrength)
|
private void TakeDamage(float hitStrength)
|
||||||
{
|
{
|
||||||
var hitShieldRatio = hitStrength / ShieldControl.ShieldEnergy;
|
var hitShieldRatio = hitStrength / ShieldControl.ShieldEnergy;
|
||||||
if (_random.GetFloat() > 0.6 || hitShieldRatio <= 0.02f)
|
if (_random.NextFloat() > 0.6 || hitShieldRatio <= 0.02f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var system = _systems[_random.Get1To8Inclusive() - 1];
|
var system = _systems[_random.Next1To8Inclusive() - 1];
|
||||||
system.TakeDamage(hitShieldRatio + 0.5f * _random.GetFloat());
|
system.TakeDamage(hitShieldRatio + 0.5f * _random.NextFloat());
|
||||||
_output.WriteLine($"Damage Control reports, '{system.Name} damaged by the hit.'");
|
_io.WriteLine($"Damage Control reports, '{system.Name} damaged by the hit.'");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RepairSystems(float repairWorkDone)
|
internal void RepairSystems(float repairWorkDone)
|
||||||
@@ -143,29 +143,29 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
if (repairedSystems.Any())
|
if (repairedSystems.Any())
|
||||||
{
|
{
|
||||||
_output.WriteLine("Damage Control report:");
|
_io.WriteLine("Damage Control report:");
|
||||||
foreach (var systemName in repairedSystems)
|
foreach (var systemName in repairedSystems)
|
||||||
{
|
{
|
||||||
_output.WriteLine($" {systemName} repair completed.");
|
_io.WriteLine($" {systemName} repair completed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void VaryConditionOfRandomSystem()
|
internal void VaryConditionOfRandomSystem()
|
||||||
{
|
{
|
||||||
if (_random.GetFloat() > 0.2f) { return; }
|
if (_random.NextFloat() > 0.2f) { return; }
|
||||||
|
|
||||||
var system = _systems[_random.Get1To8Inclusive() - 1];
|
var system = _systems[_random.Next1To8Inclusive() - 1];
|
||||||
_output.Write($"Damage Control report: {system.Name} ");
|
_io.Write($"Damage Control report: {system.Name} ");
|
||||||
if (_random.GetFloat() >= 0.6)
|
if (_random.NextFloat() >= 0.6)
|
||||||
{
|
{
|
||||||
system.Repair(_random.GetFloat() * 3 + 1);
|
system.Repair(_random.NextFloat() * 3 + 1);
|
||||||
_output.WriteLine("state of repair improved");
|
_io.WriteLine("state of repair improved");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
system.TakeDamage(_random.GetFloat() * 5 + 1);
|
system.TakeDamage(_random.NextFloat() * 5 + 1);
|
||||||
_output.WriteLine("damaged");
|
_io.WriteLine("damaged");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
if (quadrant != _quadrant.Coordinates)
|
if (quadrant != _quadrant.Coordinates)
|
||||||
{
|
{
|
||||||
_quadrant = new Quadrant(_quadrant.Galaxy[quadrant], this, _random, _quadrant.Galaxy, _input, _output);
|
_quadrant = new Quadrant(_quadrant.Galaxy[quadrant], this, _random, _quadrant.Galaxy, _io);
|
||||||
}
|
}
|
||||||
_quadrant.SetEnterpriseSector(sector);
|
_quadrant.SetEnterpriseSector(sector);
|
||||||
SectorCoordinates = sector;
|
SectorCoordinates = sector;
|
||||||
@@ -183,7 +183,7 @@ namespace SuperStarTrek.Objects
|
|||||||
TotalEnergy -= distance + 10;
|
TotalEnergy -= distance + 10;
|
||||||
if (Energy < 0)
|
if (Energy < 0)
|
||||||
{
|
{
|
||||||
_output.WriteLine("Shield Control supplies energy to complete the maneuver.");
|
_io.WriteLine("Shield Control supplies energy to complete the maneuver.");
|
||||||
ShieldControl.ShieldEnergy = Math.Max(0, TotalEnergy);
|
ShieldControl.ShieldEnergy = Math.Max(0, TotalEnergy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
if (_quadrant.HasObjectAt(sector))
|
if (_quadrant.HasObjectAt(sector))
|
||||||
{
|
{
|
||||||
_output.WriteLine($"Warp engines shut down at sector {currentSector} dues to bad navigation");
|
_io.WriteLine($"Warp engines shut down at sector {currentSector} dues to bad navigation");
|
||||||
distance = 0;
|
distance = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
if (!complete)
|
if (!complete)
|
||||||
{
|
{
|
||||||
_output.Write(Strings.PermissionDenied, sector, quadrant);
|
_io.Write(Strings.PermissionDenied, sector, quadrant);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (quadrant, sector);
|
return (quadrant, sector);
|
||||||
@@ -228,4 +228,3 @@ namespace SuperStarTrek.Objects
|
|||||||
? Math.Min(1, (float)Math.Round(warpFactor, 1, MidpointRounding.ToZero))
|
? Math.Min(1, (float)Math.Round(warpFactor, 1, MidpointRounding.ToZero))
|
||||||
: 1;
|
: 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Objects
|
namespace SuperStarTrek.Objects;
|
||||||
{
|
|
||||||
internal class Klingon
|
internal class Klingon
|
||||||
{
|
{
|
||||||
private readonly Random _random;
|
private readonly IRandom _random;
|
||||||
|
|
||||||
internal Klingon(Coordinates sector, Random random)
|
internal Klingon(Coordinates sector, IRandom random)
|
||||||
{
|
{
|
||||||
Sector = sector;
|
Sector = sector;
|
||||||
_random = random;
|
_random = random;
|
||||||
Energy = _random.GetFloat(100, 300);
|
Energy = _random.NextFloat(100, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal float Energy { get; private set; }
|
internal float Energy { get; private set; }
|
||||||
@@ -22,7 +23,7 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
internal CommandResult FireOn(Enterprise enterprise)
|
internal CommandResult FireOn(Enterprise enterprise)
|
||||||
{
|
{
|
||||||
var attackStrength = _random.GetFloat();
|
var attackStrength = _random.NextFloat();
|
||||||
var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates);
|
var distanceToEnterprise = Sector.GetDistanceTo(enterprise.SectorCoordinates);
|
||||||
var hitStrength = (int)(Energy * (2 + attackStrength) / distanceToEnterprise);
|
var hitStrength = (int)(Energy * (2 + attackStrength) / distanceToEnterprise);
|
||||||
Energy /= 3 + attackStrength;
|
Energy /= 3 + attackStrength;
|
||||||
@@ -40,4 +41,3 @@ namespace SuperStarTrek.Objects
|
|||||||
|
|
||||||
internal void MoveTo(Coordinates newSector) => Sector = newSector;
|
internal void MoveTo(Coordinates newSector) => Sector = newSector;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace SuperStarTrek.Objects
|
namespace SuperStarTrek.Objects;
|
||||||
{
|
|
||||||
internal class Star
|
internal class Star
|
||||||
{
|
{
|
||||||
public override string ToString() => " * ";
|
public override string ToString() => " * ";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Objects
|
namespace SuperStarTrek.Objects;
|
||||||
{
|
|
||||||
internal class Starbase
|
internal class Starbase
|
||||||
{
|
{
|
||||||
private readonly Input _input;
|
private readonly IReadWrite _io;
|
||||||
private readonly Output _output;
|
|
||||||
private readonly float _repairDelay;
|
private readonly float _repairDelay;
|
||||||
|
|
||||||
internal Starbase(Coordinates sector, Random random, Input input, Output output)
|
internal Starbase(Coordinates sector, IRandom random, IReadWrite io)
|
||||||
{
|
{
|
||||||
Sector = sector;
|
Sector = sector;
|
||||||
_repairDelay = random.GetFloat() * 0.5f;
|
_repairDelay = random.NextFloat(0.5f);
|
||||||
_input = input;
|
_io = io;
|
||||||
_output = output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Coordinates Sector { get; }
|
internal Coordinates Sector { get; }
|
||||||
@@ -26,8 +26,8 @@ namespace SuperStarTrek.Objects
|
|||||||
repairTime = enterprise.DamagedSystemCount * 0.1f + _repairDelay;
|
repairTime = enterprise.DamagedSystemCount * 0.1f + _repairDelay;
|
||||||
if (repairTime >= 1) { repairTime = 0.9f; }
|
if (repairTime >= 1) { repairTime = 0.9f; }
|
||||||
|
|
||||||
_output.Write(Strings.RepairEstimate, repairTime);
|
_io.Write(Strings.RepairEstimate, repairTime);
|
||||||
if (_input.GetYesNo(Strings.RepairPrompt, Input.YesNoMode.TrueOnY))
|
if (_io.GetYesNo(Strings.RepairPrompt, IReadWriteExtensions.YesNoMode.TrueOnY))
|
||||||
{
|
{
|
||||||
foreach (var system in enterprise.Systems)
|
foreach (var system in enterprise.Systems)
|
||||||
{
|
{
|
||||||
@@ -40,6 +40,5 @@ namespace SuperStarTrek.Objects
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ProtectEnterprise() => _output.WriteLine(Strings.Protected);
|
internal void ProtectEnterprise() => _io.WriteLine(Strings.Protected);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace SuperStarTrek
|
|
||||||
{
|
|
||||||
internal class Output
|
|
||||||
{
|
|
||||||
internal Output Write(string text)
|
|
||||||
{
|
|
||||||
Console.Write(text);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Output Write(string format, params object[] args)
|
|
||||||
{
|
|
||||||
Console.Write(format, args);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Output WriteLine(string text = "")
|
|
||||||
{
|
|
||||||
Console.WriteLine(text);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal Output NextLine()
|
|
||||||
{
|
|
||||||
Console.WriteLine();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal Output Prompt(string text = "")
|
|
||||||
{
|
|
||||||
Console.Write($"{text}? ");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,17 +23,14 @@
|
|||||||
// **** CONVERTED TO MICROSOFT C# 2/20/21 BY ANDREW COOPER
|
// **** CONVERTED TO MICROSOFT C# 2/20/21 BY ANDREW COOPER
|
||||||
// ****
|
// ****
|
||||||
|
|
||||||
namespace SuperStarTrek
|
using Games.Common.IO;
|
||||||
{
|
using Games.Common.Randomness;
|
||||||
internal class Program
|
using SuperStarTrek;
|
||||||
{
|
|
||||||
static void Main()
|
|
||||||
{
|
|
||||||
var output = new Output();
|
|
||||||
var input = new Input(output);
|
|
||||||
var random = new Random();
|
|
||||||
|
|
||||||
var game = new Game(output, input, random);
|
var io = new ConsoleIO();
|
||||||
|
var random = new RandomNumberGenerator();
|
||||||
|
|
||||||
|
var game = new Game(io, random);
|
||||||
|
|
||||||
game.DoIntroduction();
|
game.DoIntroduction();
|
||||||
|
|
||||||
@@ -41,6 +38,3 @@ namespace SuperStarTrek
|
|||||||
{
|
{
|
||||||
game.Play();
|
game.Play();
|
||||||
} while (game.Replay());
|
} while (game.Replay());
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
using SuperStarTrek.Space;
|
|
||||||
|
|
||||||
namespace SuperStarTrek
|
|
||||||
{
|
|
||||||
internal class Random
|
|
||||||
{
|
|
||||||
private readonly System.Random _random = new();
|
|
||||||
|
|
||||||
internal Coordinates GetCoordinate() => new Coordinates(Get1To8Inclusive() - 1, Get1To8Inclusive() - 1);
|
|
||||||
|
|
||||||
// Duplicates the algorithm used in the original code to get an integer value from 1 to 8, inclusive:
|
|
||||||
// 475 DEF FNR(R)=INT(RND(R)*7.98+1.01)
|
|
||||||
// Returns a value from 1 to 8, inclusive.
|
|
||||||
// Note there's a slight bias away from the extreme values, 1 and 8.
|
|
||||||
internal int Get1To8Inclusive() => (int)(GetFloat() * 7.98 + 1.01);
|
|
||||||
|
|
||||||
internal int GetInt(int inclusiveMinValue, int exclusiveMaxValue) =>
|
|
||||||
_random.Next(inclusiveMinValue, exclusiveMaxValue);
|
|
||||||
|
|
||||||
internal float GetFloat() => (float)_random.NextDouble();
|
|
||||||
|
|
||||||
internal float GetFloat(float inclusiveMinValue, float exclusiveMaxValue)
|
|
||||||
=> GetFloat() * (exclusiveMaxValue - inclusiveMinValue) + inclusiveMinValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,3 +16,9 @@
|
|||||||
'----------------'
|
'----------------'
|
||||||
|
|
||||||
THE USS ENTERPRISE --- NCC-1701
|
THE USS ENTERPRISE --- NCC-1701
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -104,3 +104,4 @@ COM command = Library-Computer
|
|||||||
Option 5 = Galactic Region Name Map
|
Option 5 = Galactic Region Name Map
|
||||||
This option prints the names of the sixteen major
|
This option prints the names of the sixteen major
|
||||||
galactic regions referred to in the game.
|
galactic regions referred to in the game.
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
|
|
||||||
Now entering {0} quadrant . . .
|
Now entering {0} quadrant . . .
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ Your orders are as follows:
|
|||||||
the galaxy before they can attack federation headquarters
|
the galaxy before they can attack federation headquarters
|
||||||
on stardate {1}. This gives you {2} days. There {3}
|
on stardate {1}. This gives you {2} days. There {3}
|
||||||
{4} starbase{5} in the galaxy for resupplying your ship.
|
{4} starbase{5} in the galaxy for resupplying your ship.
|
||||||
|
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
Your mission begins with your starship located
|
Your mission begins with your starship located
|
||||||
in the galactic quadrant, '{0}'.
|
in the galactic quadrant, '{0}'.
|
||||||
|
|
||||||
|
|||||||
@@ -17,3 +17,11 @@
|
|||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
*************************************
|
*************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using SuperStarTrek.Utils;
|
using SuperStarTrek.Utils;
|
||||||
|
|
||||||
namespace SuperStarTrek.Space
|
namespace SuperStarTrek.Space;
|
||||||
{
|
|
||||||
// Represents the corrdintate of a quadrant in the galaxy, or a sector in a quadrant.
|
// Represents the corrdintate of a quadrant in the galaxy, or a sector in a quadrant.
|
||||||
// Note that the origin is top-left, x increase downwards, and y increases to the right.
|
// Note that the origin is top-left, x increase downwards, and y increases to the right.
|
||||||
internal record Coordinates
|
internal record Coordinates
|
||||||
@@ -67,4 +67,3 @@ namespace SuperStarTrek.Space
|
|||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SuperStarTrek.Space
|
namespace SuperStarTrek.Space;
|
||||||
{
|
|
||||||
// Implements the course calculations from the original code:
|
// Implements the course calculations from the original code:
|
||||||
// 530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI
|
// 530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI
|
||||||
// 540 C(3,1)=-1:C(2,1)=-1:C(4,1)=-1:C(4,2)=-1:C(5,2)=-1:C(6,2)=-1
|
// 540 C(3,1)=-1:C(2,1)=-1:C(4,1)=-1:C(4,2)=-1:C(5,2)=-1:C(6,2)=-1
|
||||||
@@ -95,4 +95,3 @@ namespace SuperStarTrek.Space
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
|
|
||||||
using static System.StringSplitOptions;
|
using static System.StringSplitOptions;
|
||||||
|
|
||||||
namespace SuperStarTrek.Space
|
namespace SuperStarTrek.Space;
|
||||||
{
|
|
||||||
internal class Galaxy
|
internal class Galaxy
|
||||||
{
|
{
|
||||||
private static readonly string[] _regionNames;
|
private static readonly string[] _regionNames;
|
||||||
@@ -18,7 +19,7 @@ namespace SuperStarTrek.Space
|
|||||||
_subRegionIdentifiers = new[] { "I", "II", "III", "IV" };
|
_subRegionIdentifiers = new[] { "I", "II", "III", "IV" };
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Galaxy(Random random)
|
internal Galaxy(IRandom random)
|
||||||
{
|
{
|
||||||
_quadrants = Enumerable
|
_quadrants = Enumerable
|
||||||
.Range(0, 8)
|
.Range(0, 8)
|
||||||
@@ -31,7 +32,7 @@ namespace SuperStarTrek.Space
|
|||||||
|
|
||||||
if (StarbaseCount == 0)
|
if (StarbaseCount == 0)
|
||||||
{
|
{
|
||||||
var randomQuadrant = this[random.GetCoordinate()];
|
var randomQuadrant = this[random.NextCoordinate()];
|
||||||
randomQuadrant.AddStarbase();
|
randomQuadrant.AddStarbase();
|
||||||
|
|
||||||
if (randomQuadrant.KlingonCount < 2)
|
if (randomQuadrant.KlingonCount < 2)
|
||||||
@@ -61,4 +62,3 @@ namespace SuperStarTrek.Space
|
|||||||
.Select(dy => dy + quadrant.Coordinates.Y)
|
.Select(dy => dy + quadrant.Coordinates.Y)
|
||||||
.Select(y => y < 0 || y > 7 || x < 0 || x > 7 ? null : _quadrants[x][y]);
|
.Select(y => y < 0 || y > 7 || x < 0 || x > 7 ? null : _quadrants[x][y]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,32 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
|
|
||||||
namespace SuperStarTrek.Space
|
namespace SuperStarTrek.Space;
|
||||||
{
|
|
||||||
internal class Quadrant
|
internal class Quadrant
|
||||||
{
|
{
|
||||||
private readonly QuadrantInfo _info;
|
private readonly QuadrantInfo _info;
|
||||||
private readonly Random _random;
|
private readonly IRandom _random;
|
||||||
private readonly Dictionary<Coordinates, object> _sectors;
|
private readonly Dictionary<Coordinates, object> _sectors;
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private bool _entered = false;
|
private bool _entered = false;
|
||||||
|
|
||||||
internal Quadrant(
|
internal Quadrant(
|
||||||
QuadrantInfo info,
|
QuadrantInfo info,
|
||||||
Enterprise enterprise,
|
Enterprise enterprise,
|
||||||
Random random,
|
IRandom random,
|
||||||
Galaxy galaxy,
|
Galaxy galaxy,
|
||||||
Input input,
|
IReadWrite io)
|
||||||
Output output)
|
|
||||||
{
|
{
|
||||||
_info = info;
|
_info = info;
|
||||||
_random = random;
|
_random = random;
|
||||||
_output = output;
|
_io = io;
|
||||||
Galaxy = galaxy;
|
Galaxy = galaxy;
|
||||||
|
|
||||||
info.MarkAsKnown();
|
info.MarkAsKnown();
|
||||||
@@ -34,7 +35,7 @@ namespace SuperStarTrek.Space
|
|||||||
PositionObject(sector => new Klingon(sector, _random), _info.KlingonCount);
|
PositionObject(sector => new Klingon(sector, _random), _info.KlingonCount);
|
||||||
if (_info.HasStarbase)
|
if (_info.HasStarbase)
|
||||||
{
|
{
|
||||||
Starbase = PositionObject(sector => new Starbase(sector, _random, input, output));
|
Starbase = PositionObject(sector => new Starbase(sector, _random, io));
|
||||||
}
|
}
|
||||||
PositionObject(_ => new Star(), _info.StarCount);
|
PositionObject(_ => new Star(), _info.StarCount);
|
||||||
}
|
}
|
||||||
@@ -79,14 +80,14 @@ namespace SuperStarTrek.Space
|
|||||||
{
|
{
|
||||||
if (!_entered)
|
if (!_entered)
|
||||||
{
|
{
|
||||||
_output.Write(textFormat, this);
|
_io.Write(textFormat, this);
|
||||||
_entered = true;
|
_entered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_info.KlingonCount > 0)
|
if (_info.KlingonCount > 0)
|
||||||
{
|
{
|
||||||
_output.Write(Strings.CombatArea);
|
_io.Write(Strings.CombatArea);
|
||||||
if (_enterprise.ShieldControl.ShieldEnergy <= 200) { _output.Write(Strings.LowShields); }
|
if (_enterprise.ShieldControl.ShieldEnergy <= 200) { _io.Write(Strings.LowShields); }
|
||||||
}
|
}
|
||||||
|
|
||||||
_enterprise.Execute(Command.SRS);
|
_enterprise.Execute(Command.SRS);
|
||||||
@@ -164,7 +165,7 @@ namespace SuperStarTrek.Space
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var sector = _random.GetCoordinate();
|
var sector = _random.NextCoordinate();
|
||||||
if (!_sectors.ContainsKey(sector))
|
if (!_sectors.ContainsKey(sector))
|
||||||
{
|
{
|
||||||
return sector;
|
return sector;
|
||||||
@@ -189,4 +190,3 @@ namespace SuperStarTrek.Space
|
|||||||
_sectors[sector] = _enterprise;
|
_sectors[sector] = _enterprise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
namespace SuperStarTrek.Space
|
using Games.Common.Randomness;
|
||||||
{
|
|
||||||
|
namespace SuperStarTrek.Space;
|
||||||
|
|
||||||
internal class QuadrantInfo
|
internal class QuadrantInfo
|
||||||
{
|
{
|
||||||
private bool _isKnown;
|
private bool _isKnown;
|
||||||
@@ -23,17 +25,17 @@ namespace SuperStarTrek.Space
|
|||||||
|
|
||||||
internal int StarCount { get; }
|
internal int StarCount { get; }
|
||||||
|
|
||||||
internal static QuadrantInfo Create(Coordinates coordinates, string name, Random random)
|
internal static QuadrantInfo Create(Coordinates coordinates, string name, IRandom random)
|
||||||
{
|
{
|
||||||
var klingonCount = random.GetFloat() switch
|
var klingonCount = random.NextFloat() switch
|
||||||
{
|
{
|
||||||
> 0.98f => 3,
|
> 0.98f => 3,
|
||||||
> 0.95f => 2,
|
> 0.95f => 2,
|
||||||
> 0.80f => 1,
|
> 0.80f => 1,
|
||||||
_ => 0
|
_ => 0
|
||||||
};
|
};
|
||||||
var hasStarbase = random.GetFloat() > 0.96f;
|
var hasStarbase = random.NextFloat() > 0.96f;
|
||||||
var starCount = random.Get1To8Inclusive();
|
var starCount = random.Next1To8Inclusive();
|
||||||
|
|
||||||
return new QuadrantInfo(coordinates, name, klingonCount, starCount, hasStarbase);
|
return new QuadrantInfo(coordinates, name, klingonCount, starCount, hasStarbase);
|
||||||
}
|
}
|
||||||
@@ -62,4 +64,3 @@ namespace SuperStarTrek.Space
|
|||||||
|
|
||||||
internal void RemoveStarbase() => HasStarbase = false;
|
internal void RemoveStarbase() => HasStarbase = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace SuperStarTrek
|
namespace SuperStarTrek;
|
||||||
{
|
|
||||||
internal static class StringExtensions
|
internal static class StringExtensions
|
||||||
{
|
{
|
||||||
internal static string Pluralize(this string singular, int quantity) => singular + (quantity > 1 ? "s" : "");
|
internal static string Pluralize(this string singular, int quantity) => singular + (quantity > 1 ? "s" : "");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Resources\*.txt" />
|
<EmbeddedResource Include="Resources\*.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\00_Common\dotnet\Games.Common\Games.Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal abstract class ComputerFunction
|
internal abstract class ComputerFunction
|
||||||
{
|
{
|
||||||
protected ComputerFunction(string description, Output output)
|
protected ComputerFunction(string description, IReadWrite io)
|
||||||
{
|
{
|
||||||
Description = description;
|
Description = description;
|
||||||
Output = output;
|
IO = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string Description { get; }
|
internal string Description { get; }
|
||||||
|
|
||||||
protected Output Output { get; }
|
protected IReadWrite IO { get; }
|
||||||
|
|
||||||
internal abstract void Execute(Quadrant quadrant);
|
internal abstract void Execute(Quadrant quadrant);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class CumulativeGalacticRecord : GalacticReport
|
internal class CumulativeGalacticRecord : GalacticReport
|
||||||
{
|
{
|
||||||
internal CumulativeGalacticRecord(Output output, Galaxy galaxy)
|
internal CumulativeGalacticRecord(IReadWrite io, Galaxy galaxy)
|
||||||
: base("Cumulative galactic record", output, galaxy)
|
: base("Cumulative galactic record", io, galaxy)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void WriteHeader(Quadrant quadrant) =>
|
protected override void WriteHeader(Quadrant quadrant)
|
||||||
Output.NextLine().WriteLine($"Computer record of galaxy for quadrant {quadrant.Coordinates}").NextLine();
|
{
|
||||||
|
IO.WriteLine();
|
||||||
|
IO.WriteLine($"Computer record of galaxy for quadrant {quadrant.Coordinates}");
|
||||||
|
IO.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
protected override IEnumerable<string> GetRowData() =>
|
protected override IEnumerable<string> GetRowData() =>
|
||||||
Galaxy.Quadrants.Select(row => " " + string.Join(" ", row));
|
Galaxy.Quadrants.Select(row => " " + string.Join(" ", row));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class DirectionDistanceCalculator : NavigationCalculator
|
internal class DirectionDistanceCalculator : NavigationCalculator
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Input _input;
|
private readonly IReadWrite _io;
|
||||||
|
|
||||||
internal DirectionDistanceCalculator(Enterprise enterprise, Output output, Input input)
|
internal DirectionDistanceCalculator(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Direction/distance calculator", output)
|
: base("Direction/distance calculator", io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_input = input;
|
_io = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Execute(Quadrant quadrant)
|
internal override void Execute(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
Output.WriteLine("Direction/distance calculator:")
|
IO.WriteLine("Direction/distance calculator:");
|
||||||
.Write($"You are at quadrant {_enterprise.QuadrantCoordinates}")
|
IO.Write($"You are at quadrant {_enterprise.QuadrantCoordinates}");
|
||||||
.WriteLine($" sector {_enterprise.SectorCoordinates}")
|
IO.WriteLine($" sector {_enterprise.SectorCoordinates}");
|
||||||
.WriteLine("Please enter");
|
IO.WriteLine("Please enter");
|
||||||
|
|
||||||
WriteDirectionAndDistance(
|
WriteDirectionAndDistance(
|
||||||
_input.GetCoordinates(" Initial coordinates"),
|
_io.GetCoordinates(" Initial coordinates"),
|
||||||
_input.GetCoordinates(" Final coordinates"));
|
_io.GetCoordinates(" Final coordinates"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal abstract class GalacticReport : ComputerFunction
|
internal abstract class GalacticReport : ComputerFunction
|
||||||
{
|
{
|
||||||
internal GalacticReport(string description, Output output, Galaxy galaxy)
|
internal GalacticReport(string description, IReadWrite io, Galaxy galaxy)
|
||||||
: base(description, output)
|
: base(description, io)
|
||||||
{
|
{
|
||||||
Galaxy = galaxy;
|
Galaxy = galaxy;
|
||||||
}
|
}
|
||||||
@@ -21,14 +22,13 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
internal sealed override void Execute(Quadrant quadrant)
|
internal sealed override void Execute(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
WriteHeader(quadrant);
|
WriteHeader(quadrant);
|
||||||
Output.WriteLine(" 1 2 3 4 5 6 7 8")
|
IO.WriteLine(" 1 2 3 4 5 6 7 8");
|
||||||
.WriteLine(" ----- ----- ----- ----- ----- ----- ----- -----");
|
IO.WriteLine(" ----- ----- ----- ----- ----- ----- ----- -----");
|
||||||
|
|
||||||
foreach (var (row, index) in GetRowData().Select((r, i) => (r, i)))
|
foreach (var (row, index) in GetRowData().Select((r, i) => (r, i)))
|
||||||
{
|
{
|
||||||
Output.WriteLine($" {index+1} {row}")
|
IO.WriteLine($" {index+1} {row}");
|
||||||
.WriteLine(" ----- ----- ----- ----- ----- ----- ----- -----");
|
IO.WriteLine(" ----- ----- ----- ----- ----- ----- ----- -----");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class GalaxyRegionMap : GalacticReport
|
internal class GalaxyRegionMap : GalacticReport
|
||||||
{
|
{
|
||||||
internal GalaxyRegionMap(Output output, Galaxy galaxy)
|
internal GalaxyRegionMap(IReadWrite io, Galaxy galaxy)
|
||||||
: base("Galaxy 'region name' map", output, galaxy)
|
: base("Galaxy 'region name' map", io, galaxy)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void WriteHeader(Quadrant quadrant) =>
|
protected override void WriteHeader(Quadrant quadrant) =>
|
||||||
Output.WriteLine(" The Galaxy");
|
IO.WriteLine(" The Galaxy");
|
||||||
|
|
||||||
protected override IEnumerable<string> GetRowData() =>
|
protected override IEnumerable<string> GetRowData() =>
|
||||||
Strings.RegionNames.Split('\n').Select(n => n.TrimEnd('\r'));
|
Strings.RegionNames.Split('\n').Select(n => n.TrimEnd('\r'));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
using SuperStarTrek.Utils;
|
using SuperStarTrek.Utils;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal abstract class NavigationCalculator : ComputerFunction
|
internal abstract class NavigationCalculator : ComputerFunction
|
||||||
{
|
{
|
||||||
protected NavigationCalculator(string description, Output output)
|
protected NavigationCalculator(string description, IReadWrite io)
|
||||||
: base(description, output)
|
: base(description, io)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,8 +23,9 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
Write(direction, distance);
|
Write(direction, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Write(float direction, float distance) =>
|
private void Write(float direction, float distance)
|
||||||
Output.WriteLine($"Direction = {direction}")
|
{
|
||||||
.WriteLine($"Distance = {distance}");
|
IO.WriteLine($"Direction = {direction}");
|
||||||
|
IO.WriteLine($"Distance = {distance}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class StarbaseDataCalculator : NavigationCalculator
|
internal class StarbaseDataCalculator : NavigationCalculator
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
|
|
||||||
internal StarbaseDataCalculator(Enterprise enterprise, Output output)
|
internal StarbaseDataCalculator(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Starbase nav data", output)
|
: base("Starbase nav data", io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
}
|
}
|
||||||
@@ -18,13 +19,12 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
{
|
{
|
||||||
if (!quadrant.HasStarbase)
|
if (!quadrant.HasStarbase)
|
||||||
{
|
{
|
||||||
Output.WriteLine(Strings.NoStarbase);
|
IO.WriteLine(Strings.NoStarbase);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output.WriteLine("From Enterprise to Starbase:");
|
IO.WriteLine("From Enterprise to Starbase:");
|
||||||
|
|
||||||
WriteDirectionAndDistance(_enterprise.SectorCoordinates, quadrant.Starbase.Sector);
|
WriteDirectionAndDistance(_enterprise.SectorCoordinates, quadrant.Starbase.Sector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class StatusReport : ComputerFunction
|
internal class StatusReport : ComputerFunction
|
||||||
{
|
{
|
||||||
private readonly Game _game;
|
private readonly Game _game;
|
||||||
private readonly Galaxy _galaxy;
|
private readonly Galaxy _galaxy;
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
|
|
||||||
internal StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, Output output)
|
internal StatusReport(Game game, Galaxy galaxy, Enterprise enterprise, IReadWrite io)
|
||||||
: base("Status report", output)
|
: base("Status report", io)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
_galaxy = galaxy;
|
_galaxy = galaxy;
|
||||||
@@ -20,22 +21,23 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
|
|
||||||
internal override void Execute(Quadrant quadrant)
|
internal override void Execute(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
Output.WriteLine(" Status report:")
|
IO.WriteLine(" Status report:");
|
||||||
.Write("Klingon".Pluralize(_galaxy.KlingonCount)).WriteLine($" left: {_galaxy.KlingonCount}")
|
IO.Write("Klingon".Pluralize(_galaxy.KlingonCount));
|
||||||
.WriteLine($"Mission must be completed in {_game.StardatesRemaining:0.#} stardates.");
|
IO.WriteLine($" left: {_galaxy.KlingonCount}");
|
||||||
|
IO.WriteLine($"Mission must be completed in {_game.StardatesRemaining:0.#} stardates.");
|
||||||
|
|
||||||
if (_galaxy.StarbaseCount > 0)
|
if (_galaxy.StarbaseCount > 0)
|
||||||
{
|
{
|
||||||
Output.Write($"The Federation is maintaining {_galaxy.StarbaseCount} ")
|
IO.Write($"The Federation is maintaining {_galaxy.StarbaseCount} ");
|
||||||
.Write("starbase".Pluralize(_galaxy.StarbaseCount)).WriteLine(" in the galaxy.");
|
IO.Write("starbase".Pluralize(_galaxy.StarbaseCount));
|
||||||
|
IO.WriteLine(" in the galaxy.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Output.WriteLine("Your stupidity has left you on your own in")
|
IO.WriteLine("Your stupidity has left you on your own in");
|
||||||
.WriteLine(" the galaxy -- you have no starbases left!");
|
IO.WriteLine(" the galaxy -- you have no starbases left!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_enterprise.Execute(Command.DAM);
|
_enterprise.Execute(Command.DAM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems.ComputerFunctions
|
namespace SuperStarTrek.Systems.ComputerFunctions;
|
||||||
{
|
|
||||||
internal class TorpedoDataCalculator : NavigationCalculator
|
internal class TorpedoDataCalculator : NavigationCalculator
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
|
|
||||||
internal TorpedoDataCalculator(Enterprise enterprise, Output output)
|
internal TorpedoDataCalculator(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Photon torpedo data", output)
|
: base("Photon torpedo data", io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
}
|
}
|
||||||
@@ -18,11 +19,11 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
{
|
{
|
||||||
if (!quadrant.HasKlingons)
|
if (!quadrant.HasKlingons)
|
||||||
{
|
{
|
||||||
Output.WriteLine(Strings.NoEnemyShips);
|
IO.WriteLine(Strings.NoEnemyShips);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output.WriteLine("From Enterprise to Klingon battle cruiser".Pluralize(quadrant.KlingonCount));
|
IO.WriteLine("From Enterprise to Klingon battle cruiser".Pluralize(quadrant.KlingonCount));
|
||||||
|
|
||||||
foreach (var klingon in quadrant.Klingons)
|
foreach (var klingon in quadrant.Klingons)
|
||||||
{
|
{
|
||||||
@@ -30,4 +31,3 @@ namespace SuperStarTrek.Systems.ComputerFunctions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,30 +1,31 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class DamageControl : Subsystem
|
internal class DamageControl : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
|
|
||||||
internal DamageControl(Enterprise enterprise, Output output)
|
internal DamageControl(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Damage Control", Command.DAM, output)
|
: base("Damage Control", Command.DAM, io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_output = output;
|
_io = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
if (IsDamaged)
|
if (IsDamaged)
|
||||||
{
|
{
|
||||||
_output.WriteLine("Damage Control report not available");
|
_io.WriteLine("Damage Control report not available");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_output.NextLine();
|
_io.WriteLine();
|
||||||
WriteDamageReport();
|
WriteDamageReport();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,13 +43,13 @@ namespace SuperStarTrek.Systems
|
|||||||
|
|
||||||
internal void WriteDamageReport()
|
internal void WriteDamageReport()
|
||||||
{
|
{
|
||||||
_output.NextLine().WriteLine("Device State of Repair");
|
_io.WriteLine();
|
||||||
|
_io.WriteLine("Device State of Repair");
|
||||||
foreach (var system in _enterprise.Systems)
|
foreach (var system in _enterprise.Systems)
|
||||||
{
|
{
|
||||||
_output.Write(system.Name.PadRight(25))
|
_io.Write(system.Name.PadRight(25));
|
||||||
.WriteLine(((int)(system.Condition * 100) * 0.01).ToString(" 0.##;-0.##"));
|
_io.WriteLine((int)(system.Condition * 100) * 0.01F);
|
||||||
}
|
|
||||||
_output.NextLine();
|
|
||||||
}
|
}
|
||||||
|
_io.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
using SuperStarTrek.Systems.ComputerFunctions;
|
using SuperStarTrek.Systems.ComputerFunctions;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class LibraryComputer : Subsystem
|
internal class LibraryComputer : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly Input _input;
|
|
||||||
private readonly ComputerFunction[] _functions;
|
private readonly ComputerFunction[] _functions;
|
||||||
|
|
||||||
internal LibraryComputer(Output output, Input input, params ComputerFunction[] functions)
|
internal LibraryComputer(IReadWrite io, params ComputerFunction[] functions)
|
||||||
: base("Library-Computer", Command.COM, output)
|
: base("Library-Computer", Command.COM, io)
|
||||||
{
|
{
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
_functions = functions;
|
_functions = functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ namespace SuperStarTrek.Systems
|
|||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
var index = GetFunctionIndex();
|
var index = GetFunctionIndex();
|
||||||
_output.NextLine();
|
_io.WriteLine();
|
||||||
|
|
||||||
_functions[index].Execute(quadrant);
|
_functions[index].Execute(quadrant);
|
||||||
|
|
||||||
@@ -34,13 +33,12 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var index = (int)_input.GetNumber("Computer active and waiting command");
|
var index = (int)_io.ReadNumber("Computer active and waiting command");
|
||||||
if (index >= 0 && index <= 5) { return index; }
|
if (index >= 0 && index <= 5) { return index; }
|
||||||
|
|
||||||
for (int i = 0; i < _functions.Length; i++)
|
for (int i = 0; i < _functions.Length; i++)
|
||||||
{
|
{
|
||||||
_output.WriteLine($" {i} = {_functions[i].Description}");
|
_io.WriteLine($" {i} = {_functions[i].Description}");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,35 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class LongRangeSensors : Subsystem
|
internal class LongRangeSensors : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Galaxy _galaxy;
|
private readonly Galaxy _galaxy;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
|
|
||||||
internal LongRangeSensors(Galaxy galaxy, Output output)
|
internal LongRangeSensors(Galaxy galaxy, IReadWrite io)
|
||||||
: base("Long Range Sensors", Command.LRS, output)
|
: base("Long Range Sensors", Command.LRS, io)
|
||||||
{
|
{
|
||||||
_galaxy = galaxy;
|
_galaxy = galaxy;
|
||||||
_output = output;
|
_io = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CanExecuteCommand() => IsOperational("{name} are inoperable");
|
protected override bool CanExecuteCommand() => IsOperational("{name} are inoperable");
|
||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
_output.WriteLine($"Long range scan for quadrant {quadrant.Coordinates}");
|
_io.WriteLine($"Long range scan for quadrant {quadrant.Coordinates}");
|
||||||
_output.WriteLine("-------------------");
|
_io.WriteLine("-------------------");
|
||||||
foreach (var quadrants in _galaxy.GetNeighborhood(quadrant))
|
foreach (var quadrants in _galaxy.GetNeighborhood(quadrant))
|
||||||
{
|
{
|
||||||
_output.WriteLine(": " + string.Join(" : ", quadrants.Select(q => q?.Scan() ?? "***")) + " :");
|
_io.WriteLine(": " + string.Join(" : ", quadrants.Select(q => q?.Scan() ?? "***")) + " :");
|
||||||
_output.WriteLine("-------------------");
|
_io.WriteLine("-------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandResult.Ok;
|
return CommandResult.Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
|
using Games.Common.Randomness;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class PhaserControl : Subsystem
|
internal class PhaserControl : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly Input _input;
|
private readonly IRandom _random;
|
||||||
private readonly Random _random;
|
|
||||||
|
|
||||||
internal PhaserControl(Enterprise enterprise, Output output, Input input, Random random)
|
internal PhaserControl(Enterprise enterprise, IReadWrite io, IRandom random)
|
||||||
: base("Phaser Control", Command.PHA, output)
|
: base("Phaser Control", Command.PHA, io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
_random = random;
|
_random = random;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,16 +28,16 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
if (!quadrant.HasKlingons)
|
if (!quadrant.HasKlingons)
|
||||||
{
|
{
|
||||||
_output.WriteLine(Strings.NoEnemyShips);
|
_io.WriteLine(Strings.NoEnemyShips);
|
||||||
return CommandResult.Ok;
|
return CommandResult.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_enterprise.Computer.IsDamaged)
|
if (_enterprise.Computer.IsDamaged)
|
||||||
{
|
{
|
||||||
_output.WriteLine("Computer failure hampers accuracy");
|
_io.WriteLine("Computer failure hampers accuracy");
|
||||||
}
|
}
|
||||||
|
|
||||||
_output.Write($"Phasers locked on target; ");
|
_io.Write($"Phasers locked on target; ");
|
||||||
|
|
||||||
var phaserStrength = GetPhaserStrength();
|
var phaserStrength = GetPhaserStrength();
|
||||||
if (phaserStrength < 0) { return CommandResult.Ok; }
|
if (phaserStrength < 0) { return CommandResult.Ok; }
|
||||||
@@ -58,8 +58,8 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_output.WriteLine($"Energy available = {_enterprise.Energy} units");
|
_io.WriteLine($"Energy available = {_enterprise.Energy} units");
|
||||||
var phaserStrength = _input.GetNumber("Number of units to fire");
|
var phaserStrength = _io.ReadNumber("Number of units to fire");
|
||||||
|
|
||||||
if (phaserStrength <= _enterprise.Energy) { return phaserStrength; }
|
if (phaserStrength <= _enterprise.Energy) { return phaserStrength; }
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
if (_enterprise.Computer.IsDamaged)
|
if (_enterprise.Computer.IsDamaged)
|
||||||
{
|
{
|
||||||
phaserStrength *= _random.GetFloat();
|
phaserStrength *= _random.NextFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
return phaserStrength / targetCount;
|
return phaserStrength / targetCount;
|
||||||
@@ -78,20 +78,19 @@ namespace SuperStarTrek.Systems
|
|||||||
private void ResolveHitOn(Klingon klingon, float perEnemyStrength, Quadrant quadrant)
|
private void ResolveHitOn(Klingon klingon, float perEnemyStrength, Quadrant quadrant)
|
||||||
{
|
{
|
||||||
var distance = _enterprise.SectorCoordinates.GetDistanceTo(klingon.Sector);
|
var distance = _enterprise.SectorCoordinates.GetDistanceTo(klingon.Sector);
|
||||||
var hitStrength = (int)(perEnemyStrength / distance * (2 + _random.GetFloat()));
|
var hitStrength = (int)(perEnemyStrength / distance * (2 + _random.NextFloat()));
|
||||||
|
|
||||||
if (klingon.TakeHit(hitStrength))
|
if (klingon.TakeHit(hitStrength))
|
||||||
{
|
{
|
||||||
_output.WriteLine($"{hitStrength} unit hit on Klingon at sector {klingon.Sector}");
|
_io.WriteLine($"{hitStrength} unit hit on Klingon at sector {klingon.Sector}");
|
||||||
_output.WriteLine(
|
_io.WriteLine(
|
||||||
klingon.Energy <= 0
|
klingon.Energy <= 0
|
||||||
? quadrant.Remove(klingon)
|
? quadrant.Remove(klingon)
|
||||||
: $" (sensors show {klingon.Energy} units remaining)");
|
: $" (sensors show {klingon.Energy} units remaining)");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_output.WriteLine($"Sensors show no damage to enemy at {klingon.Sector}");
|
_io.WriteLine($"Sensors show no damage to enemy at {klingon.Sector}");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class PhotonTubes : Subsystem
|
internal class PhotonTubes : Subsystem
|
||||||
{
|
{
|
||||||
private readonly int _tubeCount;
|
private readonly int _tubeCount;
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly Input _input;
|
|
||||||
|
|
||||||
internal PhotonTubes(int tubeCount, Enterprise enterprise, Output output, Input input)
|
internal PhotonTubes(int tubeCount, Enterprise enterprise, IReadWrite io)
|
||||||
: base("Photon Tubes", Command.TOR, output)
|
: base("Photon Tubes", Command.TOR, io)
|
||||||
{
|
{
|
||||||
TorpedoCount = _tubeCount = tubeCount;
|
TorpedoCount = _tubeCount = tubeCount;
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal int TorpedoCount { get; private set; }
|
internal int TorpedoCount { get; private set; }
|
||||||
@@ -28,13 +27,13 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
if (TorpedoCount > 0) { return true; }
|
if (TorpedoCount > 0) { return true; }
|
||||||
|
|
||||||
_output.WriteLine("All photon torpedoes expended");
|
_io.WriteLine("All photon torpedoes expended");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
if (!_input.TryGetCourse("Photon torpedo course", "Ensign Chekov", out var course))
|
if (!_io.TryReadCourse("Photon torpedo course", "Ensign Chekov", out var course))
|
||||||
{
|
{
|
||||||
return CommandResult.Ok;
|
return CommandResult.Ok;
|
||||||
}
|
}
|
||||||
@@ -42,25 +41,24 @@ namespace SuperStarTrek.Systems
|
|||||||
TorpedoCount -= 1;
|
TorpedoCount -= 1;
|
||||||
|
|
||||||
var isHit = false;
|
var isHit = false;
|
||||||
_output.WriteLine("Torpedo track:");
|
_io.WriteLine("Torpedo track:");
|
||||||
foreach (var sector in course.GetSectorsFrom(_enterprise.SectorCoordinates))
|
foreach (var sector in course.GetSectorsFrom(_enterprise.SectorCoordinates))
|
||||||
{
|
{
|
||||||
_output.WriteLine($" {sector}");
|
_io.WriteLine($" {sector}");
|
||||||
|
|
||||||
if (quadrant.TorpedoCollisionAt(sector, out var message, out var gameOver))
|
if (quadrant.TorpedoCollisionAt(sector, out var message, out var gameOver))
|
||||||
{
|
{
|
||||||
_output.WriteLine(message);
|
_io.WriteLine(message);
|
||||||
isHit = true;
|
isHit = true;
|
||||||
if (gameOver) { return CommandResult.GameOver; }
|
if (gameOver) { return CommandResult.GameOver; }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isHit) { _output.WriteLine("Torpedo missed!"); }
|
if (!isHit) { _io.WriteLine("Torpedo missed!"); }
|
||||||
|
|
||||||
return quadrant.KlingonsFireOnEnterprise();
|
return quadrant.KlingonsFireOnEnterprise();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ReplenishTorpedoes() => TorpedoCount = _tubeCount;
|
internal void ReplenishTorpedoes() => TorpedoCount = _tubeCount;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class ShieldControl : Subsystem
|
internal class ShieldControl : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly Input _input;
|
|
||||||
|
|
||||||
internal ShieldControl(Enterprise enterprise, Output output, Input input)
|
internal ShieldControl(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Shield Control", Command.SHE, output)
|
: base("Shield Control", Command.SHE, io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal float ShieldEnergy { get; set; }
|
internal float ShieldEnergy { get; set; }
|
||||||
@@ -25,17 +24,17 @@ namespace SuperStarTrek.Systems
|
|||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
_output.WriteLine($"Energy available = {_enterprise.TotalEnergy}");
|
_io.WriteLine($"Energy available = {_enterprise.TotalEnergy}");
|
||||||
var requested = _input.GetNumber($"Number of units to shields");
|
var requested = _io.ReadNumber($"Number of units to shields");
|
||||||
|
|
||||||
if (Validate(requested))
|
if (Validate(requested))
|
||||||
{
|
{
|
||||||
ShieldEnergy = requested;
|
ShieldEnergy = requested;
|
||||||
_output.Write(Strings.ShieldsSet, requested);
|
_io.Write(Strings.ShieldsSet, requested);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_output.WriteLine("<SHIELDS UNCHANGED>");
|
_io.WriteLine("<SHIELDS UNCHANGED>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandResult.Ok;
|
return CommandResult.Ok;
|
||||||
@@ -45,7 +44,7 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
if (requested > _enterprise.TotalEnergy)
|
if (requested > _enterprise.TotalEnergy)
|
||||||
{
|
{
|
||||||
_output.WriteLine("Shield Control reports, 'This is not the Federation Treasury.'");
|
_io.WriteLine("Shield Control reports, 'This is not the Federation Treasury.'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,4 +55,3 @@ namespace SuperStarTrek.Systems
|
|||||||
|
|
||||||
internal void DropShields() => ShieldEnergy = 0;
|
internal void DropShields() => ShieldEnergy = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,47 +2,48 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal class ShortRangeSensors : Subsystem
|
internal class ShortRangeSensors : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Galaxy _galaxy;
|
private readonly Galaxy _galaxy;
|
||||||
private readonly Game _game;
|
private readonly Game _game;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
|
|
||||||
internal ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, Output output)
|
internal ShortRangeSensors(Enterprise enterprise, Galaxy galaxy, Game game, IReadWrite io)
|
||||||
: base("Short Range Sensors", Command.SRS, output)
|
: base("Short Range Sensors", Command.SRS, io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_galaxy = galaxy;
|
_galaxy = galaxy;
|
||||||
_game = game;
|
_game = game;
|
||||||
_output = output;
|
_io = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
if (_enterprise.IsDocked)
|
if (_enterprise.IsDocked)
|
||||||
{
|
{
|
||||||
_output.WriteLine(Strings.ShieldsDropped);
|
_io.WriteLine(Strings.ShieldsDropped);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Condition < 0)
|
if (Condition < 0)
|
||||||
{
|
{
|
||||||
_output.WriteLine(Strings.ShortRangeSensorsOut);
|
_io.WriteLine(Strings.ShortRangeSensorsOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
_output.WriteLine("---------------------------------");
|
_io.WriteLine("---------------------------------");
|
||||||
quadrant.GetDisplayLines()
|
quadrant.GetDisplayLines()
|
||||||
.Zip(GetStatusLines(), (sectors, status) => $" {sectors} {status}")
|
.Zip(GetStatusLines(), (sectors, status) => $" {sectors} {status}")
|
||||||
.ToList()
|
.ToList()
|
||||||
.ForEach(l => _output.WriteLine(l));
|
.ForEach(l => _io.WriteLine(l));
|
||||||
_output.WriteLine("---------------------------------");
|
_io.WriteLine("---------------------------------");
|
||||||
|
|
||||||
return CommandResult.Ok;
|
return CommandResult.Ok;
|
||||||
}
|
}
|
||||||
@@ -59,4 +60,3 @@ namespace SuperStarTrek.Systems
|
|||||||
yield return $"Klingons remaining {_galaxy.KlingonCount}";
|
yield return $"Klingons remaining {_galaxy.KlingonCount}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Space;
|
using SuperStarTrek.Space;
|
||||||
|
|
||||||
namespace SuperStarTrek.Systems
|
namespace SuperStarTrek.Systems;
|
||||||
{
|
|
||||||
internal abstract class Subsystem
|
internal abstract class Subsystem
|
||||||
{
|
{
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
|
|
||||||
protected Subsystem(string name, Command command, Output output)
|
protected Subsystem(string name, Command command, IReadWrite io)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Command = command;
|
Command = command;
|
||||||
Condition = 0;
|
Condition = 0;
|
||||||
_output = output;
|
_io = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string Name { get; }
|
internal string Name { get; }
|
||||||
@@ -29,7 +30,7 @@ namespace SuperStarTrek.Systems
|
|||||||
{
|
{
|
||||||
if (IsDamaged)
|
if (IsDamaged)
|
||||||
{
|
{
|
||||||
_output.WriteLine(notOperationalMessage.Replace("{name}", Name));
|
_io.WriteLine(notOperationalMessage.Replace("{name}", Name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,4 +66,3 @@ namespace SuperStarTrek.Systems
|
|||||||
|
|
||||||
internal void TakeDamage(float damage) => Condition -= damage;
|
internal void TakeDamage(float damage) => Condition -= damage;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Games.Common.IO;
|
||||||
using SuperStarTrek.Commands;
|
using SuperStarTrek.Commands;
|
||||||
using SuperStarTrek.Objects;
|
using SuperStarTrek.Objects;
|
||||||
using SuperStarTrek.Resources;
|
using SuperStarTrek.Resources;
|
||||||
@@ -9,20 +10,18 @@ namespace SuperStarTrek.Systems
|
|||||||
internal class WarpEngines : Subsystem
|
internal class WarpEngines : Subsystem
|
||||||
{
|
{
|
||||||
private readonly Enterprise _enterprise;
|
private readonly Enterprise _enterprise;
|
||||||
private readonly Output _output;
|
private readonly IReadWrite _io;
|
||||||
private readonly Input _input;
|
|
||||||
|
|
||||||
internal WarpEngines(Enterprise enterprise, Output output, Input input)
|
internal WarpEngines(Enterprise enterprise, IReadWrite io)
|
||||||
: base("Warp Engines", Command.NAV, output)
|
: base("Warp Engines", Command.NAV, io)
|
||||||
{
|
{
|
||||||
_enterprise = enterprise;
|
_enterprise = enterprise;
|
||||||
_output = output;
|
_io = io;
|
||||||
_input = input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
protected override CommandResult ExecuteCommandCore(Quadrant quadrant)
|
||||||
{
|
{
|
||||||
if (_input.TryGetCourse("Course", " Lt. Sulu", out var course) &&
|
if (_io.TryReadCourse("Course", " Lt. Sulu", out var course) &&
|
||||||
TryGetWarpFactor(out var warpFactor) &&
|
TryGetWarpFactor(out var warpFactor) &&
|
||||||
TryGetDistanceToMove(warpFactor, out var distanceToMove))
|
TryGetDistanceToMove(warpFactor, out var distanceToMove))
|
||||||
{
|
{
|
||||||
@@ -51,12 +50,12 @@ namespace SuperStarTrek.Systems
|
|||||||
private bool TryGetWarpFactor(out float warpFactor)
|
private bool TryGetWarpFactor(out float warpFactor)
|
||||||
{
|
{
|
||||||
var maximumWarp = IsDamaged ? 0.2f : 8;
|
var maximumWarp = IsDamaged ? 0.2f : 8;
|
||||||
if (_input.TryGetNumber("Warp Factor", 0, maximumWarp, out warpFactor))
|
if (_io.TryReadNumberInRange("Warp Factor", 0, maximumWarp, out warpFactor))
|
||||||
{
|
{
|
||||||
return warpFactor > 0;
|
return warpFactor > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_output.WriteLine(
|
_io.WriteLine(
|
||||||
IsDamaged && warpFactor > maximumWarp
|
IsDamaged && warpFactor > maximumWarp
|
||||||
? "Warp engines are damaged. Maximum speed = warp 0.2"
|
? "Warp engines are damaged. Maximum speed = warp 0.2"
|
||||||
: $" Chief Engineer Scott reports, 'The engines won't take warp {warpFactor} !'");
|
: $" Chief Engineer Scott reports, 'The engines won't take warp {warpFactor} !'");
|
||||||
@@ -69,14 +68,14 @@ namespace SuperStarTrek.Systems
|
|||||||
distanceToTravel = (int)Math.Round(warpFactor * 8, MidpointRounding.AwayFromZero);
|
distanceToTravel = (int)Math.Round(warpFactor * 8, MidpointRounding.AwayFromZero);
|
||||||
if (distanceToTravel <= _enterprise.Energy) { return true; }
|
if (distanceToTravel <= _enterprise.Energy) { return true; }
|
||||||
|
|
||||||
_output.WriteLine("Engineering reports, 'Insufficient energy available")
|
_io.WriteLine("Engineering reports, 'Insufficient energy available");
|
||||||
.WriteLine($" for maneuvering at warp {warpFactor} !'");
|
_io.WriteLine($" for maneuvering at warp {warpFactor} !'");
|
||||||
|
|
||||||
if (distanceToTravel <= _enterprise.TotalEnergy && !_enterprise.ShieldControl.IsDamaged)
|
if (distanceToTravel <= _enterprise.TotalEnergy && !_enterprise.ShieldControl.IsDamaged)
|
||||||
{
|
{
|
||||||
_output.Write($"Deflector control room acknowledges {_enterprise.ShieldControl.ShieldEnergy} ")
|
_io.Write($"Deflector control room acknowledges {_enterprise.ShieldControl.ShieldEnergy} ");
|
||||||
.WriteLine("units of energy")
|
_io.WriteLine("units of energy");
|
||||||
.WriteLine(" presently deployed to shields.");
|
_io.WriteLine(" presently deployed to shields.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user