BattleshipUtility.Ship.Place C# (CSharp) Method

Place() public method

Randomly places a ship on a grid
public Place ( int width, int height ) : void
width int width of grid
height int height of grid
return void
        public void Place(int width, int height)
        {
            // Randomly choose a position and orientation
            int row = BattleshipGame.Random.Next(height);
            int column = BattleshipGame.Random.Next(width);
            Orientation = (BattleshipGame.Random.NextDouble() < 0.5d) ? Orientation.Horizontal : Orientation.Vertical;

            // Make sure the ship stays on the board
            if ((Orientation == Orientation.Horizontal) && ((column + Size) >= width))
            {
                column = column - Size + 1;
            }
            else if ((Orientation == Orientation.Vertical) && ((row + Size) >= height))
            {
                row = row - Size + 1;
            }

            Position.Row = row;
            Position.Column = column;
        }

Usage Example

        /// <summary>
        /// Place ships on board
        /// </summary>
        /// <returns>List of ship placements</returns>
        public List<Ship> PlaceShips()
        {
            // We want to be both random and smart
            // Generate a series of positions, score them based on position probability and opponent shooting data
            List<Ship> placedShips = new List<Ship>(AdaptivePlayer.Ships.Count);
            List<Ship> bestShipPlacement = new List<Ship>(AdaptivePlayer.Ships.Count);
            double minimumScore = double.MaxValue;
            bool allowTouching = true;

            // Randomly decide to disallow touching ships
            if (BattleshipGame.Random.NextDouble() < 0.6d)
            {
                allowTouching = false;
            }

            // Randomly choose 1000 different layouts, choose the layout with the lowest score
            for (int sample = 0; sample < _samples; ++sample)
            {
                double currentScore = 0.0d;
                placedShips.Clear();
                foreach (Ship ship in AdaptivePlayer.Ships)
                {
                    bool intersects = false;
                    Ship placedShip = new Ship() { Size = ship.Size, Code = ship.Code };

                    // Keep generating positions until we have a set that has no intersecting ships
                    do
                    {
                        intersects = false;
                        placedShip.Place(AdaptivePlayer.Width, AdaptivePlayer.Height);
                        foreach (Ship checkShip in placedShips)
                        {
                            if (allowTouching)
                            {
                                if (placedShip.Intersects(checkShip))
                                {
                                    intersects = true;
                                    break;
                                }
                            }
                            else
                            {
                                if (placedShip.IntersectsOrAdjacent(checkShip))
                                {
                                    intersects = true;
                                    break;
                                }
                            }
                        }
                    } while (intersects);

                    // Score the positions of each ship
                    foreach(Position p in placedShip.Positions)
                    {
                        // Default to probability distribution, otherwise use previous shot history
                        currentScore += (double)AdaptivePlayer.Data.IncomingShots[p.Row][p.Column] / (double)_totalPositions;
                    }
                    placedShips.Add(placedShip);
                }

                if (currentScore < minimumScore)
                {
                    minimumScore = currentScore;
                    bestShipPlacement.Clear();
                    foreach (Ship ship in placedShips)
                        bestShipPlacement.Add(ship);
                }
            }

            // We want to avoid using this placement again, add some points to the current location
            int totalShipSize = bestShipPlacement.Sum(x => x.Size);
            foreach (Ship ship in bestShipPlacement)
            {
                foreach (Position p in ship.Positions)
                {
                    AdaptivePlayer.Data.IncomingShots[p.Row][p.Column] += (int)((double)ship.Size / (double)totalShipSize * 1000.0d);
                }
            }

            return bestShipPlacement;
        }