In the first part of this series we discussed how to play a game of Battleship and what kinds of components and strategies we would need to use. With those in place, we can begin modeling the game. Let's build some objects!

Coordinates

The first and most basic object we are going to model is the Coordinates object, which represents a location on a board that can be fired at.

You might be wondering why those properties Row and Column are not a part of a different model, e.g. the Panel model that we're about to define. This is because whenever a shot is fired, the person firing the shot does so by calling out coordinates, and so this class will not only represent coordinates on the game and firing boards, but also coordinates that are under attack.

(NOTE: In the game, rows are given letter designations, e.g. "A", "B", etc. Here, we'll be using integers, as it makes several calculations easier).

OccupationType

For any given panel, there a few possibilities as to what can be on that panel:

If a ship is on the panel, then the panel is occupied. Two ships cannot occupy the same panel.

If a shot was fired at that panel, then either a hit or a miss was recorded on that panel.

If there's nothing on that panel, the panel is said to be empty.

To represent all of these statuses, I created an enumeration called OccupationType:

We should make special note of the IsRandomAvailable property. Remember from the previous part of this series that when we are firing random shots, we don't need to target every panel, but rather every other panel, like so:

IsRandomAvailable helps us implement that strategy. It designates every panel where both row and column coordinates are odd, or both coordinates are even, as being available for a "random" shot selection.

Finally, note the IsOccupied property. We'll be using that property in a later part to determine where to place the ships.

Our first objective is achieved: we've created the classes necessary to play a game of Battleship. Now, let's work though how to set up a game.

Setting Up the Game

To start, let's think about what a Player would need to do, once s/he has all their pieces, to set up a game of Battleship. S/he needs to:

Place his/her ships on the GameBoard.

That's it!

So, okay, there's not a whole lot of setup involved in a game of Battleship. However, there is some, so in this section we're going to implement the code which places a Player's ships, as well as output what their boards look like.

Ship Placement

There are a lot of articles out there that purport to help you win a game of Battleship each time you play (and many of them correspond with the release of that god-awful movie), but for this practice we're not going to bother with more advanced strategies since our goal is not to win games, but to understand the game itself better by modeling it.

In short: our ship placement will be effectively random.

But it cannot be truly random, since two ships cannot occupy the same panel. Therefore we must implement a placement algorithm which places each ship on the board but ensures that each ship does not occupy the same Panel as any other ship.

Attempt to place the ship on the proposed panels. If any of those panels are already occupied, or are outside the boundaries of the game board, start over from 1.

Given that the total number of panels (100) is much greater than the space we need to occupy (2 + 3 + 3 + 4 + 5 = 16), this is actually relatively efficient, but not perfect.

Let's start coding up that algorithm, using the Player class we defined in Part 2. We'll create a new method PlaceShips in the Player class and define it like so, and use a random number generator that I stole from StackOverflow: