From 1d3fd94ae6a80ab75c5082d7974533660677ef77 Mon Sep 17 00:00:00 2001 From: drewjcooper Date: Mon, 22 May 2023 08:42:22 +1000 Subject: [PATCH] Simplify shot selection and evaluation --- 77_Salvo/csharp/{Grid.cs => Fleet.cs} | 21 ++++++----- 77_Salvo/csharp/Game.cs | 37 +++++-------------- .../csharp/Targetting/ComputerShotSelector.cs | 16 +++++++- .../csharp/Targetting/HumanShotSelector.cs | 2 +- 77_Salvo/csharp/Targetting/ShotSelector.cs | 4 +- 5 files changed, 38 insertions(+), 42 deletions(-) rename 77_Salvo/csharp/{Grid.cs => Fleet.cs} (75%) diff --git a/77_Salvo/csharp/Grid.cs b/77_Salvo/csharp/Fleet.cs similarity index 75% rename from 77_Salvo/csharp/Grid.cs rename to 77_Salvo/csharp/Fleet.cs index f91ae43a..5f267225 100644 --- a/77_Salvo/csharp/Grid.cs +++ b/77_Salvo/csharp/Fleet.cs @@ -3,11 +3,11 @@ using System.Diagnostics.CodeAnalysis; namespace Salvo; -internal class Grid +internal class Fleet { private readonly List _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 Ships => _ships.AsEnumerable(); - internal bool IsHit(Position position, [NotNullWhen(true)] out Ship? ship) + internal void ReceiveShots(IEnumerable shots, Action 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); + } } } diff --git a/77_Salvo/csharp/Game.cs b/77_Salvo/csharp/Game.cs index 6c0add12..5004cacb 100644 --- a/77_Salvo/csharp/Game.cs +++ b/77_Salvo/csharp/Game.cs @@ -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; } } diff --git a/77_Salvo/csharp/Targetting/ComputerShotSelector.cs b/77_Salvo/csharp/Targetting/ComputerShotSelector.cs index 5a5214dd..721f50c5 100644 --- a/77_Salvo/csharp/Targetting/ComputerShotSelector.cs +++ b/77_Salvo/csharp/Targetting/ComputerShotSelector.cs @@ -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 GetShots() => GetSelectionStrategy().GetShots(NumberOfShots); + protected override IEnumerable 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); diff --git a/77_Salvo/csharp/Targetting/HumanShotSelector.cs b/77_Salvo/csharp/Targetting/HumanShotSelector.cs index f3e5fba2..ea49bf12 100644 --- a/77_Salvo/csharp/Targetting/HumanShotSelector.cs +++ b/77_Salvo/csharp/Targetting/HumanShotSelector.cs @@ -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; diff --git a/77_Salvo/csharp/Targetting/ShotSelector.cs b/77_Salvo/csharp/Targetting/ShotSelector.cs index 95a5c4bd..695dbc42 100644 --- a/77_Salvo/csharp/Targetting/ShotSelector.cs +++ b/77_Salvo/csharp/Targetting/ShotSelector.cs @@ -2,10 +2,10 @@ namespace Salvo.Targetting; internal abstract class ShotSelector { - private readonly Grid _source; + private readonly Fleet _source; private readonly Dictionary _previousShots = new(); - internal ShotSelector(Grid source) + internal ShotSelector(Fleet source) { _source = source; }