From e27b5ec6e5018a051e9c1a85c91fd83875da8817 Mon Sep 17 00:00:00 2001 From: drewjcooper Date: Thu, 18 May 2023 19:27:56 +1000 Subject: [PATCH] Move shot selection into ComputerShotSelector --- 77_Salvo/csharp/Game.cs | 66 ++--------------- .../csharp/Targetting/ComputerShotSelector.cs | 21 ++---- .../KnownHitsShotSelectionStrategy.cs | 71 +++++++++++++++++++ .../Targetting/ShotSelectionStrategy.cs | 16 +++++ 4 files changed, 101 insertions(+), 73 deletions(-) create mode 100644 77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs create mode 100644 77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs diff --git a/77_Salvo/csharp/Game.cs b/77_Salvo/csharp/Game.cs index 33d750df..95ccef23 100644 --- a/77_Salvo/csharp/Game.cs +++ b/77_Salvo/csharp/Game.cs @@ -17,13 +17,13 @@ internal class Game { _io.Write(Streams.Title); - var hitRecords = new List<(int Turn, Ship Ship)>(); + 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, computerGrid, _io); - var computerShotSelector = new SearchPatternShotSelector(computerGrid, humanGrid, _random); + var computerShotSelector = new ComputerShotSelector(computerGrid, humanGrid, _random); var startResponse = _io.ReadString(Prompts.Start); while (startResponse == Strings.WhereAreYourShips) { @@ -64,12 +64,11 @@ L2850: if (humanGrid.UntriedSquareCount > numberOfShots) { goto L2880; } L2860: _io.Write(Streams.IHaveMoreShotsThanSquares); L2270: _io.Write(Streams.IWon); return; -L2880: if (numberOfShots != 0) { goto L2960; } +L2880: if (numberOfShots == 0) { goto L2960; } L2890: _io.Write(Streams.YouWon); L2900: return; -L2960: if (humanGrid.Ships.Any(s => s.IsDamaged)) { goto L3800; } - temp = computerShotSelector.GetShots().ToArray(); +L2960: temp = computerShotSelector.GetShots().ToArray(); // display shots L3380: if (seeShotsResponse == "YES") { @@ -80,64 +79,13 @@ L3380: if (seeShotsResponse == "YES") } foreach (var shot in temp) { - if (!humanGrid.IsHit(shot, turnNumber, out var ship)) + if (humanGrid.IsHit(shot, turnNumber, out var ship)) { - continue; - } - _io.Write(Strings.IHit(ship.Name)); - if (ship.IsDestroyed) - { - hitRecords = hitRecords.Where(hr => hr.Ship != ship).ToList(); - } - else - { - hitRecords.Add((turnNumber, ship)); + _io.Write(Strings.IHit(ship.Name)); + computerShotSelector.RecordHit(ship, turnNumber); } } goto L1950; -L3800: //REM************************USINGEARRAY - var tempGrid = Position.All.ToDictionary(x => x, _ => 0); -L3860: foreach (var (hitTurn, ship) in hitRecords) - { - foreach (var position in Position.All) - { - if (humanGrid.WasTargetedAt(position, out _)) - { - tempGrid[position]=-10000000; - continue; - } - - foreach (var neighbour in position.Neighbours) - { - if (humanGrid.WasTargetedAt(neighbour, out var turn) && turn == hitTurn) - { - tempGrid[position] += hitTurn + 10 - position.Y * ship.Shots; - } - } - } - } -L4030: for (var i = 0; i < numberOfShots; i++) - { -L4040: temp[i]=i+1; - } - foreach (var position in Position.All) - { -L4090: var Q9=0; -L4100: for (var i = 0; i < numberOfShots; i++) - { -L4110: if (tempGrid[temp[i]] < tempGrid[temp[Q9]]) - { -L4120: Q9 = i; - } - } -L4131: if (position.X <= numberOfShots && position.IsOnDiagonal) { continue; } -L4140: if (tempGrid[position] GetShots() { - throw new NotImplementedException(); + return _knownHitsStrategy.GetShots(NumberOfShots) ?? _searchPatternShotSelector.GetShots(); } - private void DisplayShots(IEnumerable shots, IReadWrite io) - { - if (_displayShots) - { - foreach (var shot in shots) - { - io.WriteLine(shot); - } - } - } + internal void RecordHit(Ship ship, int turn) => _knownHitsStrategy.RecordHit(ship, turn); } diff --git a/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs b/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs new file mode 100644 index 00000000..917b232e --- /dev/null +++ b/77_Salvo/csharp/Targetting/KnownHitsShotSelectionStrategy.cs @@ -0,0 +1,71 @@ +namespace Salvo.Targetting; + +internal class KnownHitsShotSelectionStrategy : ShotSelectionStrategy +{ + private readonly List<(int Turn, Ship Ship)> _damagedShips = new(); + + internal KnownHitsShotSelectionStrategy(Grid target) + : base(target) + { + } + + internal IEnumerable? GetShots(int numberOfShots) + { + if (!_damagedShips.Any()) { return null; } + + var tempGrid = Position.All.ToDictionary(x => x, _ => 0); + var shots = Enumerable.Range(1, numberOfShots).Select(x => new Position(x, x)).ToArray(); + + foreach (var (hitTurn, ship) in _damagedShips) + { + foreach (var position in Position.All) + { + if (WasSelectedPreviously(position)) + { + tempGrid[position]=-10000000; + continue; + } + + foreach (var neighbour in position.Neighbours) + { + if (WasSelectedPreviously(neighbour, out var turn) && turn == hitTurn) + { + tempGrid[position] += hitTurn + 10 - position.Y * ship.Shots; + } + } + } + } + + foreach (var position in Position.All) + { + var Q9=0; + for (var i = 0; i < numberOfShots; i++) + { + if (tempGrid[shots[i]] < tempGrid[shots[Q9]]) + { + Q9 = i; + } + } + if (position.X <= numberOfShots && position.IsOnDiagonal) { continue; } + if (tempGrid[position] x.Ship == ship); + } + else + { + _damagedShips.Add((turn, ship)); + } + } +} diff --git a/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs b/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs new file mode 100644 index 00000000..f98c7b4f --- /dev/null +++ b/77_Salvo/csharp/Targetting/ShotSelectionStrategy.cs @@ -0,0 +1,16 @@ +namespace Salvo.Targetting; + +internal abstract class ShotSelectionStrategy +{ + private readonly Grid _target; + protected ShotSelectionStrategy(Grid target) + { + _target = target; + } + + protected bool WasSelectedPreviously(Position position) + => _target.WasTargetedAt(position, out _); + + protected bool WasSelectedPreviously(Position position, out int turn) + => _target.WasTargetedAt(position, out turn); +}