简体   繁体   中英

How can I update a dictionary from within a class method?

I'm trying to code some basic classes and interactions to practice and eventually make this into a working game (similar to OGame). In my code, each player has some ships (I would have preferred them to be classes instead of dicts but couldn't get it to work either) with their own keys. I want the dictionary to update the number of ships and its type by using the build_ships() function, doing it like this felt like the right way to do it, but it is currently not working...

Disclaimer: I'm pretty new at coding in general, but couldn't find any good solutions that would scale nicely or what the best structure for something like this would be.

class Player:
    def __init__(self, name, ships=None):
        self.name = name
        if ships is None:
            self.ships = {}
        else:
            self.ships = ships

    def build_ships(self, ship, quantity):
        self.ships[ship] = quantity


small_cruiser = {
"name":'SMALL CRUISER',
"size":5,
"attack":10,
"defense":7,
"speed":30
}

big_cruiser = {
"name":'BIG CRUISER',
"size":7,
"attack":15,
"defense":9,
"speed":25
}

player_1 = Player('TheLegend27')
player_1.build_ships(small_cruiser, 5)

You can't use a dictionary as a key in another dictionary, because dictionaries are mutable and dictionary keys must be hashable (immutable).

It seems to me like it makes more sense for self.ships to be a list of ships, rather than a dictionary. Then your build_ships method simply need to append ships to that list.

Consider the following code:

class Player:
    def __init__(self, name, ships=None):
        self.name = name
        if ships is None:
            self.ships = []
        else:
            self.ships = ships

    def build_ships(self, ship, quantity):
        for _ in range(quantity):
            s = ship.copy()
            self.ships.append(s)


small_cruiser = {
    "name":'SMALL CRUISER',
    "size":5,
    "attack":10,
    "defense":7,
    "speed":30
}

big_cruiser = {
    "name":'BIG CRUISER',
    "size":7,
    "attack":15,
    "defense":9,
    "speed":25
}

player_1 = Player('TheLegend27')
player_1.build_ships(small_cruiser, 5)

Note that we need to add the line s = ship.copy() in order to create copies of the original dictionary passed in as the argument to build_ships . Otherwise, you'd be appending the same dictionary over and over, and any modifications done to any dictionary in self.ships would reflect on the others.

The keys in the dictionary have to be hashable. So you cannot have a dictionary as a key in a second dictionary. One way would be if you know that the names of the ships are unique, then you can have just Player object just maintain the name and count.

def build_ships(self, ship, quantity):
        self.ships[ship] = quantity

Which will be called by:

player_1.build_ships("SMALL CRUISER", 5)

And then you can have a separate dictionary to maintain the types of ships, something like:

ships = {"SMALL CRUISER":{"size":5,
                          "attack":10,
                          "defense":7,
                          "speed":30},
         "BIG CRUISER":{"size":7,
                        "attack":15,
                        "defense":9,
                        "speed":25},
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM