mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-02-05 03:17:03 -08:00
Simplify shot selection and evaluation
This commit is contained in:
@@ -3,11 +3,11 @@ using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Salvo;
|
||||
|
||||
internal class Grid
|
||||
internal class Fleet
|
||||
{
|
||||
private readonly List<Ship> _ships;
|
||||
|
||||
internal Grid(IReadWrite io)
|
||||
internal Fleet(IReadWrite io)
|
||||
{
|
||||
io.WriteLine(Prompts.Coordinates);
|
||||
_ships = new()
|
||||
@@ -19,7 +19,7 @@ internal class Grid
|
||||
};
|
||||
}
|
||||
|
||||
internal Grid(IRandom random)
|
||||
internal Fleet(IRandom random)
|
||||
{
|
||||
_ships = new();
|
||||
while (true)
|
||||
@@ -53,13 +53,14 @@ internal class Grid
|
||||
|
||||
internal IEnumerable<Ship> Ships => _ships.AsEnumerable();
|
||||
|
||||
internal bool IsHit(Position position, [NotNullWhen(true)] out Ship? ship)
|
||||
internal void ReceiveShots(IEnumerable<Position> shots, Action<Ship> reportHit)
|
||||
{
|
||||
ship = _ships.FirstOrDefault(s => s.IsHit(position));
|
||||
if (ship == null) { return false; }
|
||||
|
||||
if (ship.IsDestroyed) { _ships.Remove(ship); }
|
||||
|
||||
return true;
|
||||
foreach (var position in shots)
|
||||
{
|
||||
var ship = _ships.FirstOrDefault(s => s.IsHit(position));
|
||||
if (ship == null) { continue; }
|
||||
if (ship.IsDestroyed) { _ships.Remove(ship); }
|
||||
reportHit(ship);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,21 +20,20 @@ internal class Game
|
||||
var damagedShips = new List<(int Turn, Ship Ship)>();
|
||||
var temp = new Position[13];
|
||||
|
||||
var computerGrid = new Grid(_random);
|
||||
var humanGrid = new Grid(_io);
|
||||
var humanShotSelector = new HumanShotSelector(humanGrid, _io);
|
||||
var computerShotSelector = new ComputerShotSelector(computerGrid, _random);
|
||||
var computerFleet = new Fleet(_random);
|
||||
var humanFleet = new Fleet(_io);
|
||||
var startResponse = _io.ReadString(Prompts.Start);
|
||||
while (startResponse == Strings.WhereAreYourShips)
|
||||
{
|
||||
foreach (var ship in computerGrid.Ships)
|
||||
foreach (var ship in computerFleet.Ships)
|
||||
{
|
||||
_io.WriteLine(ship);
|
||||
}
|
||||
startResponse = _io.ReadString(Prompts.Start);
|
||||
}
|
||||
L1890: var turnNumber=0;
|
||||
L1900: var seeShotsResponse = _io.ReadString(Prompts.SeeShots);
|
||||
var humanShotSelector = new HumanShotSelector(humanFleet, _io);
|
||||
var computerShotSelector = new ComputerShotSelector(computerFleet, _random, _io);
|
||||
L1920: _io.WriteLine();
|
||||
L1930: if (startResponse != "YES") { goto L2620; }
|
||||
L1950: if (startResponse != "YES") { goto L1990; }
|
||||
@@ -48,13 +47,7 @@ L2230: if (humanShotSelector.CanTargetAllRemainingSquares)
|
||||
_io.WriteLine(Streams.YouHaveMoreShotsThanSquares);
|
||||
L2250: goto L2890;
|
||||
}
|
||||
foreach (var shot1 in humanShotSelector.GetShots(turnNumber))
|
||||
{
|
||||
if (computerGrid.IsHit(shot1, out var ship))
|
||||
{
|
||||
_io.Write(Strings.YouHit(ship.Name));
|
||||
}
|
||||
}
|
||||
computerFleet.ReceiveShots(humanShotSelector.GetShots(turnNumber), ship => _io.Write(Strings.YouHit(ship.Name)));
|
||||
L2620: if (startResponse == "YES") { goto L2670; }
|
||||
L2640: turnNumber++;
|
||||
L2660: _io.Write(Strings.Turn(turnNumber));
|
||||
@@ -68,23 +61,13 @@ L2880: if (numberOfShots > 0) { goto L2960; }
|
||||
L2890: _io.Write(Streams.YouWon);
|
||||
L2900: return;
|
||||
|
||||
L2960: temp = computerShotSelector.GetShots(turnNumber).ToArray();
|
||||
// display shots
|
||||
L3380: if (seeShotsResponse == "YES")
|
||||
{
|
||||
foreach (var shot in temp)
|
||||
{
|
||||
_io.WriteLine(shot);
|
||||
}
|
||||
}
|
||||
foreach (var shot in temp)
|
||||
{
|
||||
if (humanGrid.IsHit(shot, out var ship))
|
||||
L2960: humanFleet.ReceiveShots(
|
||||
computerShotSelector.GetShots(turnNumber),
|
||||
ship =>
|
||||
{
|
||||
_io.Write(Strings.IHit(ship.Name));
|
||||
computerShotSelector.RecordHit(ship, turnNumber);
|
||||
}
|
||||
}
|
||||
});
|
||||
goto L1950;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,27 @@ internal class ComputerShotSelector : ShotSelector
|
||||
{
|
||||
private readonly KnownHitsShotSelectionStrategy _knownHitsStrategy;
|
||||
private readonly SearchPatternShotSelectionStrategy _searchPatternStrategy;
|
||||
private readonly IReadWrite _io;
|
||||
private readonly bool _showShots;
|
||||
|
||||
internal ComputerShotSelector(Grid source, IRandom random)
|
||||
internal ComputerShotSelector(Fleet source, IRandom random, IReadWrite io)
|
||||
: base(source)
|
||||
{
|
||||
_knownHitsStrategy = new KnownHitsShotSelectionStrategy(this);
|
||||
_searchPatternStrategy = new SearchPatternShotSelectionStrategy(this, random);
|
||||
_io = io;
|
||||
_showShots = io.ReadString(Prompts.SeeShots).Equals("yes", StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Position> GetShots() => GetSelectionStrategy().GetShots(NumberOfShots);
|
||||
protected override IEnumerable<Position> GetShots()
|
||||
{
|
||||
var shots = GetSelectionStrategy().GetShots(NumberOfShots).ToArray();
|
||||
if (_showShots)
|
||||
{
|
||||
_io.WriteLine(string.Join(Environment.NewLine, shots));
|
||||
}
|
||||
return shots;
|
||||
}
|
||||
|
||||
internal void RecordHit(Ship ship, int turn) => _knownHitsStrategy.RecordHit(ship, turn);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ internal class HumanShotSelector : ShotSelector
|
||||
{
|
||||
private readonly IReadWrite _io;
|
||||
|
||||
internal HumanShotSelector(Grid source, IReadWrite io)
|
||||
internal HumanShotSelector(Fleet source, IReadWrite io)
|
||||
: base(source)
|
||||
{
|
||||
_io = io;
|
||||
|
||||
@@ -2,10 +2,10 @@ namespace Salvo.Targetting;
|
||||
|
||||
internal abstract class ShotSelector
|
||||
{
|
||||
private readonly Grid _source;
|
||||
private readonly Fleet _source;
|
||||
private readonly Dictionary<Position, int> _previousShots = new();
|
||||
|
||||
internal ShotSelector(Grid source)
|
||||
internal ShotSelector(Fleet source)
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user