// when we hit something, update state public void ShotHit(Rectangle rect, bool sunk) { var coords = Calculation.CharCoordsToInt(rect.Uid); int x = coords[0], y = coords[1]; this._state[x, y] = sunk ? State.Sunk : State.Hit; // if we know that we just sunk a ship at (x,y), look at adjacent locations to see if we // had to have sunk a given ship (i.e. if there's only one remaining ship that has a size // less than the sunk length, that ship must have sunk.) if (sunk) { var localLeft = x; while (localLeft > 0 && (this._state[localLeft - 1, y] == State.Hit || this._state[localLeft - 1, y] == State.Sunk)) { --localLeft; } var localRight = x; while (localRight < GameSize - 1 && (this._state[localRight + 1, y] == State.Hit || this._state[localRight + 1, y] == State.Sunk)) { ++localRight; } var localAbove = y; while (localAbove > 0 && (this._state[x, localAbove - 1] == State.Hit || this._state[x, localAbove - 1] == State.Sunk)) { --localAbove; } var localBelow = y; while (localBelow < GameSize - 1 && (this._state[x, localBelow + 1] == State.Hit || this._state[x, localBelow + 1] == State.Sunk)) { ++localBelow; } var sunkWidth = localRight - localLeft + 1; var sunkHeight = localBelow - localAbove + 1; if (sunkWidth > 1) { var numShips = 0; foreach (var w in this._remainingShips) { if (w <= sunkWidth) { ++numShips; } } if (numShips == 1) { this._remainingShips.Remove(sunkWidth); } } else if (sunkHeight > 1) { var numShips = 0; foreach (var w in this._remainingShips) { if (w <= sunkHeight) { ++numShips; } } if (numShips == 1) { this._remainingShips.Remove(sunkHeight); } } } }