Search code examples
pythonclassinstancetext-based

How can I create a dynamic instance of a class for a text based grid?


I'm trying to make a 10x10 grid for a map for a basic text-based game in python. I managed to create a MapTile class and a player class that can move about an (x, y) grid. I'm not sure however, how to create the instances of the class to have individual MapTiles. I've read that it would be arbitrary to create maptile1, maptile2... etc. for all 100 MapTiles, but I can't think of another way..

Here's what I've got!

# This class contains the x and y values for a grid
class MapTile:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# basic char class containing position
class Character:
    def __init__(self, name, hp, x, y):
        self.name = name
        self.hp = hp
        self.x = x
        self.y = y

    # movement func
    def Move(self, Direction):
        if Direction.upper() == "UP":
            if self.y > 1:
                self.y -= 1
        elif Direction.upper() == "LEFT":
            if self.x > 1:
                self.x -= 1
        elif Direction.upper() == "RIGHT":
            if self.x < 10:
                self.x += 1
        elif Direction.upper() == "DOWN":
            if self.y < 10:
                self.y += 1

    def __str__(self):
        return "{}\n========\nHP = {}\nX = {}\nY = {}".format(self.name,
                                                              self.hp,
                                                              self.x,
                                                              self.y)

Let me know if I am unclear.


Solution

  • As I said in a comment, I think you should use either a list-of-lists or a dictionary as a container for all the MapTile instances. Here's how to do both of them:

    # This class contains the x and y values for a grid
    class MapTile:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
    XDIM, YDIM = 10, 10
    
    # Create a list-of-lists.
    grid = [[MapTile(x, y) for y in range(YDIM)] for x in range(XDIM)]
    
    # Create a dictionary with tuple keys.
    grid = {(x, y): MapTile(x, y) for x in range(XDIM) for y in range(YDIM)}
    

    Doing something like this makes the x, y position information stored in the MapTile instances somewhat redundant, since it will be implied either by the indices or the keys used to reference each instance in the container. For example:

    grid[1][2] contains MapTile(1, 2)

        in the first case, or

    grid[(1, 2)] contains MapTile(1, 2)

    in the second scenario. For that reason, you may want to leave it out of the MapTile class in your design. Otherwise, you're likely going to need update them when the location of their MapTile instance is changed within whatever type of grid container you've chosen to use.