// Public Functions ///////////////////////////////

        /// <summary>
        ///     Add a new battleship to the board,
        ///     such that it's top-left cell is located at the specified coordinate.
        /// </summary>
        /// <param name="battleship"> The battleship to add to the board. </param>
        /// <param name="topLeft"> Where the battleship is to be placed. </param>
        /// <returns> </returns>
        public bool AddBattleship(Battleship battleship, Coord topLeft)
        {
            // Since battleships hold state, duplicate references can't be allowed
            if (Battleships.Any(b => b.Battleship == battleship))
            {
                throw new ArgumentException(
                          "This battleship is already on the board",
                          nameof(battleship));
            }

            // Validate location
            var location = new BattleshipLocation()
            {
                Battleship = battleship, TopLeft = topLeft
            };

            if (!FootprintFitsOnBoard(location))
            {
                return(false);
            }
            if (!FootprintUnoccupied(location))
            {
                return(false);
            }

            // Place battleship
            MarkFootprint(location);
            Battleships.Add(location);

            return(true);
        }
 /// <summary>
 ///     Mark the footprint of the given battleship location as occupied.
 /// </summary>
 /// <param name="location"> The location to mark the footprint of. </param>
 private void MarkFootprint(BattleshipLocation location)
 {
     foreach (var coord in location.IterateFootprint())
     {
         Cells[coord.X, coord.Y] = location;
     }
 }
        // Private Functions //////////////////////////////

        /// <summary>
        ///     Check if the entire footprint fits within the boundaries of the board.
        /// </summary>
        /// <param name="location"> The location to check the footprint of. </param>
        /// <returns> True if it fits, else false. </returns>
        private bool FootprintFitsOnBoard(BattleshipLocation location)
        {
            return(location.TopLeft.X >= 0 &&
                   location.TopLeft.Y >= 0 &&
                   location.TopLeft.X + location.Battleship.Width <= Width &&
                   location.TopLeft.Y + location.Battleship.Height <= Height);
        }
        /// <summary>
        ///     Construct a new board with the specified dimensions.
        /// </summary>
        /// <param name="width"> The width of the board, in cells </param>
        /// <param name="height"> The height of the board, in cells </param>
        public BattleshipBoard(int width = 10, int height = 10)
        {
            if (width < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(width),
                                                      "Must have positive width");
            }
            if (height < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(height),
                                                      "Must have positive height");
            }

            Width       = width;
            Height      = height;
            Cells       = new BattleshipLocation[width, height];
            Battleships = new List <BattleshipLocation>();
        }
 /// <summary>
 ///     Check if the entire footprint of the given location is unoccupied.
 /// </summary>
 /// <param name="location"> The location to check the footprint of. </param>
 /// <returns> True if its footprint is clear, else false. </returns>
 private bool FootprintUnoccupied(BattleshipLocation location)
 {
     return(location.IterateFootprint()
            .All(coord => Cells[coord.X, coord.Y] == null));
 }