【问题标题】:Looping through instances and changing value of specific instance parameter goes wrong循环遍历实例并更改特定实例参数的值出错
【发布时间】:2018-02-16 00:37:51
【问题描述】:

我目前正在学习 Python3 的在线初学者课程之一,其中一个人制作 RPG 游戏以展示其功能。

所以一般来说游戏在 main.py 中运行并使用 3 个类,每个类都在单独的文件中。类是 Person、Spell 和 Item

基本上,它在整个游戏中循环运行,在游戏内部,它循环遍历队伍中的每个玩家(3 个玩家,一个敌人)。

Person 类看起来像这样:

class Person:
    def __init__(self, name, hp, mp, atk, df, magic, items):
        self.maxhp = hp
        self.hp = hp
        self.maxmp = mp
        self.mp = mp
        self.atkl = atk - 15
        self.atkh = atk + 15
        self.df = df
        self.magic = magic
        self.items = items
        self.actions = ["Attack", "Magic", "Items"]
        self.name = name

现在直奔问题:

当我以这种方式使用一个变量传递带有项目的字典/数组时:

player_items = [{"item": potion, "quantity": 4}, 
                {"item": superPotion, "quantity": 5},
                {"item": elixer, "quantity": 5},
                {"item": grenade, "quantity": 2}]

player1 = Person("Nasteroth", 460, 130, 65, 34, player_spells, player_items)
player2 = Person("Vidala   ", 380, 200, 55, 34, player_spells, player_items)
player3 = Person("Xerogas  ", 540, 100, 80, 34, player_spells, player_items)

然后,在player1回合中,当它应该只为player1减少1的使用物品数量时,它会减少我们正在循环的所有玩家的数量?

这里是循环的一部分:

players = [player1, player2, player3]

for player in players:

    item_choice = int(input(BColors.OKGREEN + "Choose item to use: " + BColors.ENDC)) - 1

    item = player.items[item_choice]

    if item["item"].type == "potion":
        player.heal(item["item"].prop)
        print(BColors.OKGREEN, "\n", item["item"].name, "heals for", str(item["item"].prop), "HP", BColors.ENDC)
        item["quantity"] -= 1

但是当我以手动方式传递项目时:

player1 = Person("Nasteroth", 460, 130, 65, 34, player_spells, [{"item": potion, "quantity": 4}, {"item": superPotion, "quantity": 5},
                {"item": elixer, "quantity": 5},
                {"item": grenade, "quantity": 2}])
player2 = Person("Vidala   ", 380, 200, 55, 34, player_spells, [{"item": potion, "quantity": 4}, {"item": superPotion, "quantity": 5},
                {"item": elixer, "quantity": 5},
                {"item": grenade, "quantity": 2}])
player3 = Person("Xerogas  ", 540, 100, 80, 34, player_spells, [{"item": potion, "quantity": 4}, {"item": superPotion, "quantity": 5},
                {"item": elixer, "quantity": 5},
                {"item": grenade, "quantity": 2}])

代码运行良好,它分别减少了每个玩家使用的物品数量。

Python3 中是否有一些我还不知道的全局参数之类的东西?

编辑:

粘贴更多代码会使它变成一堵文字墙,因此可以在此处找到完整代码: https://pastebin.com/4V6NFu1z

【问题讨论】:

  • 所有玩家都有相同的单个背包物品player_items。显示您的Person 课程。
  • 把它放到问题中,而不是放到代码不可读的cmets中。
  • 这是您的完整代码吗?你确定它在工作吗?有很多问题使它无效。
  • 在我的问题底部添加了包含完整代码的链接,所有文件都包含在所有类中。一般来说,代码是好的,它启动并执行它应该做的除了项目之外的事情。整个程序仍在进行中,因此尚未添加一些功能。

标签: python loops


【解决方案1】:

我简化了您的代码(将一些数据转换为 player_items 中的字符串),以使其正常工作。无论如何,它说明了这个想法。发射:

class Person:
    def __init__(self, name, hp, mp, atk, df, magic, items):
        self.maxhp = hp
        self.hp = hp
        self.maxmp = mp
        self.mp = mp
        self.atkl = atk - 15
        self.atkh = atk + 15
        self.df = df
        self.magic = magic
        self.items = items
        self.actions = ["Attack", "Magic", "Items"]
        self.name = name


player_spells = None

player_items = [{"item": "potion", "quantity": 4}, 
                {"item": "superPotion", "quantity": 5},
                {"item": "elixer", "quantity": 5},
                {"item": "grenade", "quantity": 2}]

player1 = Person("Nasteroth", 460, 130, 65, 34, player_spells, player_items)
player2 = Person("Vidala   ", 380, 200, 55, 34, player_spells, player_items)
# 1
print(id(player1.items))
print(id(player2.items))
# 2
print((player1.items))
print((player2.items))

player1.items[0] = {}
# 3
print((player1.items))
print((player2.items))

它将显示 1) 两个玩家拥有相同的物品,但 2) 这些对象的 ID 相同:两个玩家持有相同的引用,因此在内存中操作相同的数据,如打印 3) 所示:改变一个玩家的数据,改变另一个玩家的物品。

如果你在上面的代码中引入一个小改动(注意.copy())然后说:

player2 = Person("Vidala   ", 380, 200, 55, 34, player_spells, player_items.copy())

然后,两个玩家将有两个不同的items 列表,并且操纵一个,不会更新另一个。此外,对象的ids 也会有所不同。

【讨论】:

  • 很高兴听到这个消息。那你能接受我的回答吗?
猜你喜欢
  • 2016-05-15
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-08
相关资源
最近更新 更多