using System.Collections.Generic;
public record struct Cell(int x, int y);
public record struct HitResult(HitType hitType, string shipName);
public record Ship(List<Cell> cells, string shipName);
public record ShipLog(List<Cell> hits);
public interface IBattleship
void Init(List<Ship> ships);
HitResult[] DoHit(Cell cell);
public class Battleship: IBattleship
private List<Ship> _ships = new List<Ship>();
private Dictionary<string, HitType> _shipHits = new Dictionary<string, HitType>();
void IBattleship.Init(List<Ship> ships)
_shipHits = _ships.ToDictionary(s => s.shipName, s => HitType.Missed);
HitResult TryHit(Ship ship, Cell cell)
var shipName = ship.shipName;
var index = ship.cells.IndexOf(cell);
_shipHits[shipName] = HitType.Missed;
return new HitResult(HitType.Missed, shipName);
ship.cells.RemoveAt(index);
if (ship.cells.Count == 0)
return new HitResult(HitType.Sink, shipName);
return _shipHits[shipName] == HitType.Hit
? new HitResult(HitType.HitAgain, shipName)
: new HitResult(HitType.Hit, shipName);
HitResult[] IBattleship.DoHit(Cell cell)
return _ships.Select(s => TryHit(s, cell)).ToArray();
public static void Main()
IBattleship battleship = new Battleship();
battleship.Init(new List<Ship>
new Ship([new Cell(0,0), new Cell(1,0)], "ship1"),
new Ship([new Cell(0,1), new Cell(1,1)], "ship2")
var result = battleship.DoHit(new Cell(0, 0));
AssertTrue(() => result.Length == 2, "Must be two ships");
AssertTrue(() => result.First(r => r.shipName == "ship1").hitType == HitType.Hit, "ship1 Must has Hit");
AssertTrue(() => result.First(r => r.shipName == "ship2").hitType == HitType.Missed, "ship1 Must has Hit");
result = battleship.DoHit(new Cell(1, 0));
AssertTrue(() => result.First(r => r.shipName == "ship1").hitType == HitType.Sink, "ship1 Must has Sink");
result = battleship.DoHit(new Cell(1, 0));
AssertTrue(() => result.First(r => r.shipName == "ship1").hitType == HitType.Missed, "ship1 Must has Missed");
Console.WriteLine("No Errors");
static void AssertTrue(Func<bool> action, string message)
Console.WriteLine($"Checking for {message}");
throw new Exception(message);