/// <summary> /// Adjust position possibilies based on the fact that a ship was sunk /// </summary> /// <param name="size">size of ship</param> void Sink(Ship ship) { // Remove this ship type from ship position consideration for (var i = 0; i < AdaptivePlayer.Width; ++i) { for (var j = 0; j < AdaptivePlayer.Width; ++j) { if (_score[i, j].Score > 0) _score[i, j].Sink(ship.Size); } } _sunkSpots += ship.Size; // We sunk a ship, go back to search mode if we don't have any pending hit boats if (_sunkSpots == _hits.Count) { _sunkSpots = 0; List<Position> adjacent = new List<Position>(); // We can now adjust scores for these hits foreach (Position p in _hits) { AdjustScore(p); if (!_assumeAdjacent) { AdjustNotAdjacentScore(p); adjacent.AddRange(AdjacentPositions(p)); } } if (!_assumeAdjacent) { adjacent = adjacent.Except(_hits).Distinct().ToList(); foreach (Position p in adjacent) { AdjustNotAdjacentScore(p); } } _hits.Clear(); _targettingMode = TargettingMode.Search; } else { // We found two ships that are adjacent _assumeAdjacent = true; // Let's see if we can remove some hits from further consideration List<Ship> possibleLayouts = new List<Ship>(); if ((_destroySearchOrientation & Orientation.Horizontal) == Orientation.Horizontal) { Ship layout = ship.Clone() as Ship; layout.Orientation = Orientation.Horizontal; // Let's see if we can find the end points of the ship var possibilities = _hits.Where(p => p.Row == _lastShot.Row && Math.Abs(p.Column - _lastShot.Column) < ship.Size); if (possibilities.Count() == ship.Size) { layout.Position = possibilities.Min(); if (!layout.Positions.Except(_hits).Any()) { // If all positions in the layout are contained in hits possibleLayouts.Add(layout); } } } if ((_destroySearchOrientation & Orientation.Vertical) == Orientation.Vertical) { Ship layout = ship.Clone() as Ship; layout.Orientation = Orientation.Vertical; // Let's see if we can find the end points of the ship var possibilities = _hits.Where(p => p.Column == _lastShot.Column && Math.Abs(p.Row - _lastShot.Row) < ship.Size); if (possibilities.Count() == ship.Size) { layout.Position = possibilities.Min(); if (!layout.Positions.Except(_hits).Any()) { // If all positions in the layout are contained in hits possibleLayouts.Add(layout); } } } if (possibleLayouts.Count == 1) { // Remove these positions from consideration _hits = _hits.Except(possibleLayouts[0].Positions).ToList(); _sunkSpots -= ship.Size; foreach (Position p in possibleLayouts[0].Positions) AdjustScore(p); } } // Reset our destroy orientation pattern _destroySearchOrientation = Orientation.Horizontal | Orientation.Vertical; }