private void PlaceShips(CellStatus[,] workingSet, ShipPositioningParameters[] shipPositioningParameters)
        {
            var shipsPositionedSoFar = _shipPositioningParametersPerShipLevel.Count;

            Logger.Log("PlaceShips called with {0} ships positioned so far. (Thread {1})", shipsPositionedSoFar, Thread.CurrentThread.ManagedThreadId);

            if (shipsPositionedSoFar == _gameConfiguration.ShipCount)
            {
                return;
            }

            var lengthOfNextShipToPosition = _gameConfiguration.ShipLengths[shipsPositionedSoFar];
            var directionOfPositioning = shipPositioningParameters[shipsPositionedSoFar].ShipDirection;
            var startingCoordinate = shipPositioningParameters[shipsPositionedSoFar].ShipCoordinate;

            var position = FindNextFreeSpace(workingSet, startingCoordinate, directionOfPositioning,
                                                 lengthOfNextShipToPosition);

            while (!position.HasValue)
            {
                position = FindNextFreeSpace(workingSet, BoardCoordinate.GetRandomCoordinateInFirstQuadrant(), directionOfPositioning,
                                             lengthOfNextShipToPosition);
            }

            // actual positioning of the ship
            PlaceShipOnMap(workingSet, lengthOfNextShipToPosition, directionOfPositioning, position.Value);
            PlaceShips(workingSet, shipPositioningParameters);
        }
 public Board GenerateBoard(ShipPositioningParameters[] shipPositioningParameters)
 {
     var workingSet = new CellStatus[_gameConfiguration.BoardSize, _gameConfiguration.BoardSize];
     PlaceShips(workingSet, shipPositioningParameters);
     return ConvertWorkingSetIntoBoard(workingSet);
 }
        private void PlaceShipOnMap(CellStatus[,] workingSet, int lengthOfNextShipToPosition, ShipDirection directionOfPositioning, BoardCoordinate position)
        {
            // first mark everything on and around cells where the ship will be as unavailable
            var startingCoordinateX = Math.Max(position.Column - 1, 0);
            var startingCoordinateY = Math.Max(position.Row - 1, 0);
            var endCoordinateX = directionOfPositioning == ShipDirection.Horizontal ?
                Math.Min(position.Column + lengthOfNextShipToPosition, _gameConfiguration.BoardSize - 1) :
                Math.Min(position.Column + 1, _gameConfiguration.BoardSize - 1);
            var endCoordinateY = directionOfPositioning == ShipDirection.Vertical ?
                Math.Min(position.Row + lengthOfNextShipToPosition, _gameConfiguration.BoardSize - 1) :
                Math.Min(position.Row + 1, _gameConfiguration.BoardSize - 1);

            for (var row = startingCoordinateY; row <= endCoordinateY; row++)
                for (var column = startingCoordinateX; column <= endCoordinateX; column++)
                    workingSet[row, column] = CellStatus.NotAvailableForPlacement;

            //Debug.WriteLine(RepresentWorkingSet(workingSet));

            // next mark where the ship actually is
            for (int i = 0; i < lengthOfNextShipToPosition; i++)
            {
                var row = directionOfPositioning == ShipDirection.Horizontal ? position.Row : Math.Min(position.Row + i, _gameConfiguration.BoardSize - 1);
                var column = directionOfPositioning == ShipDirection.Vertical ? position.Column : Math.Min(position.Column + i, _gameConfiguration.BoardSize - 1);

                workingSet[row, column] = CellStatus.ShipPart;
            }

            // finally, add the positioned ship to the collection of positioned ships
            var shipsPositionedSoFar = _shipPositioningParametersPerShipLevel.Count;
            var currentlyPositionedShipPositioningParameters = new ShipPositioningParameters
            {
                ShipCoordinate = position,
                ShipDirection = directionOfPositioning
            };
            _shipPositioningParametersPerShipLevel.Add(shipsPositionedSoFar, currentlyPositionedShipPositioningParameters);

            //Debug.WriteLine(RepresentWorkingSet(workingSet));
        }