/// <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;
}