public Cell Fire(Coordinate coordinate) { switch (Field[coordinate].State) { case CellState.ShipDeck: Field[coordinate] = new Cell { State = CellState.Exploded, Coordinate = coordinate, ShipId = Field[coordinate].ShipId }; var targetShip = _ships.First(s => s.Id == Field[coordinate].ShipId.Value); targetShip.Shot(); //invoke ship destroyed event if (targetShip.State == ShipState.Destroyed) { var surroundedCells = new List<Cell>(); //mark nearby cells as surrounded GetSurroundedCoordinatesOfTheShip(targetShip).ForEach(c => { var cell = Field[c]; if (cell.State == CellState.Shot) cell.State = CellState.ShotAndSurrounded; else if (cell.State == CellState.Empty) cell.State = CellState.Surrounded; Field[c] = cell; surroundedCells.Add(cell); }); //invoke ShipDestroyed?.Invoke(this, new ShipDestroyedEventArgs { Ship = targetShip, SurroundedCells = surroundedCells }); } break; case CellState.Empty: Field[coordinate] = new Cell { State = CellState.Shot, Coordinate = coordinate }; break; case CellState.Exploded: throw new InvalidShotException("Cannot shot again an exploded cell."); case CellState.Shot: throw new InvalidShotException("This cell were already shot."); default: throw new ArgumentOutOfRangeException(); } //call event Fired?.Invoke(this, new FiredEventArgs { Coordinate = coordinate, Result = Field[coordinate].State }); return Field[coordinate]; }
public bool PlaceShip(Ship ship) { var decks = (int)ship.Type; var possibleCoordinates = new Coordinate[decks]; var startingPoint = Coordinate.Copy(ship.StartingPoint); for (var i = 0; i < decks; i++) { //try to validate if (Field.ValidateCoordinate(startingPoint)) { //proximity check if (Field.ProximityCheck(startingPoint)) return false; possibleCoordinates[i] = Coordinate.Copy(startingPoint); if (ship.Orientation == ShipOrientation.Vertical) startingPoint.MoveDown(); else startingPoint.MoveRight(); } else return false; } //if everything went fine, persist possibleCoordinates on map possibleCoordinates.ForEach(c => Field[c] = new Cell { State = CellState.ShipDeck, Coordinate = c, ShipId = ship.Id }); //add ship to collection _ships.Add(ship); return true; }