2

I'm new to Django and I'm trying to create a Battleship game. I want to create a model for my battleship board, which is going to be 10 rows and 10 columns, with each spot having a coordinate of [x,y]. I'm not sure which model field to use though. So far, this is the code I have for my Board class:

class Board(models.Model):
    ships_left = models.IntegerField()
    available_spots = models.???  #This is to contain [x,y] coordinates of open spots

3 Answers 3

1

One possibility is to create a Coordinate class, and have every possible coordinate pair represented:

class Coordinate(models.Model):
    x = models.IntegerField()
    y = models.IntegerField()
    board = models.ForeignKey(Board)
    hit = models.BooleanField(default=False)
    ship = models.ForeignKey(Ship, null=True)  # assumes you have Ship objects somewhere

You can hit a location as follows (assuming board is a Board object):

x = 2
y = 3
location = board.coordinate_set.filter(x=x, y=y)
if location.ship != None:
    # hit a ship! Do something with location.ship object
# either way, save that it was hit
location.hit = True
location.save()

This would not be efficient for a large grid, but in this case there are only 100 coordinates per board, so it will likely be reasonable and intuitive.

Sign up to request clarification or add additional context in comments.

Comments

1

You might want to consider representing the board as one or more NumPy 2-dimensional arrays. For example, you could use a boolean 2d array to track the coordinates upon which a player has already fired, and an integer array to represent the positions of various ships, by giving each ship type a unique integer value (e.g., 0 for open ocean, 1 for destroyer, 2 for carrier, etc.). This will make it very easy to look up whether an attack was a hit and on what type of ship.

Serialization of the array into the database will require a little bit of work; I'd start by having a look at this article; it will show you what model methods to consider overriding. In the comments, there is a recommendation to just use cPickle with django-picklefield, which is the route I'd try first, for simplicity.

Comments

-1

If it's a one-to-one relationship, I would simply split the coordinate into 2 fields:

class Board(models.Model):
    ships_left = models.IntegerField()
    x = models.IntegerField()
    y = models.IntegerField()

Problem solved. I don't see the need of building another model and link it with a foreign key. Complicates things and incurs one more join, which is real cost.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.