private IEnumerable <Tuple <ShipType, CellPosition, bool> > GenerateContinuesForDamagedShip( IList <CellPosition> damagedShipCells, IGameFieldBuilder builder, bool vertical, ShipType ship) { if (builder.ShipsLeft[ship] == 0) { yield break; } var topLeftCell = damagedShipCells.Min(); var delta = vertical ? CellPosition.DeltaDown : CellPosition.DeltaRight; var start = vertical ? new CellPosition(0, topLeftCell.Column) : new CellPosition(topLeftCell.Row, 0); for (; builder.Contains(start); start += delta) { if (!builder.CanBeAddedSafely(ship, start, vertical, x => OpponentFieldKnowledge[x] != false)) { continue; } var newShipCells = Enumerable.Range(0, ship.GetLength()).Select(x => start + delta * x).ToList(); if (damagedShipCells.Any(x => !newShipCells.Contains(x))) { continue; } yield return(Tuple.Create(ship, start, vertical)); } }
private bool TryAddAllShips(IList <ShipType> ships, Predicate <CellPosition> canUseCell) { if (!ships.Any()) { return(true); } var ship = ships.Last(); ships.RemoveAt(ships.Count - 1); var availablePlaces = builder.EnumeratePositions() .SelectMany(position => new[] { new { Position = position, Vertical = true }, new { Position = position, Vertical = false } }) .Where(x => builder.CanBeAddedSafely(ship, x.Position, x.Vertical, canUseCell)) .Shuffle(); foreach (var place in availablePlaces) { builder.TryAddFullShip(ship, place.Position, place.Vertical); if (TryAddAllShips(ships, canUseCell)) { return(true); } builder.TryRemoveFullShip(ship, place.Position, place.Vertical); } ships.Add(ship); return(false); }