文字冒险,全局和局部变量问题

时间:2018-09-17 20:04:19

标签: python python-2.7 global-variables local-variables

from random import randint
from time import sleep

pminatk = 0
pmaxatk = 4
playerhp = 15

def atk(minatk, maxatk):
    return randint(minatk, maxatk)

def playerAtk(monsterhp):
    dmg = atk(pminatk, pmaxatk)
    monsterhp -= dmg
    print ("Du gjorde %i skade. Monsteret har nå %i liv igjen" % (dmg, monsterhp))
    sleep(1)
    return monsterhp

def monsterAtk(mminatk, mmaxatk):
    global playerhp
    dmg = atk(mminatk, mmaxatk)
    playerhp -= dmg
    print ("Monsteret gjorde %i skade. Du har nå %i liv igjen" % (dmg, playerhp))
    sleep(1)

def fight(monsterhp, mminatk, mmaxatk):
    global playerhp
    while monsterhp > 0 and playerhp > 0:
        playerAtk(monsterhp)
        if monsterhp > 0:
            monsterAtk(mminatk, mmaxatk)
    if playerhp > 0:
        print ("Gratulerer! Du beseiret monsteret!")
    else:
        print ("Du døde!")

fight(5, 1, 2)
fight(6, 0, 2)

这应该是基于文本的冒险中的简单战斗系统。现在我的问题是,在执行playerAtk之后,monsterhp总是回到其原始值。如果我选择将monsterhp作为全局变量,则在fight()完成后它将保持为0,同时使所有其他怪物的hp也等于零。现在,我可以有多个变量来为不同的怪物分配不同的hp值,但是有什么办法可以使用对fight()函数使用参数的方法呢?

1 个答案:

答案 0 :(得分:0)

当您调用while时,您的直接问题就在您的playerAtk()循环中,您从中返回monsterhp,但实际上并未在该循环中使用它,这就是为什么看到怪物的健康点恢复到原始值。第28行需要阅读:

monsterhp = playerAtk(monsterhp)

代替:

playerAtk(monsterhp)

但是正如注释中所建议的,值得研究定义自定义类。我根据您的代码整理了以下示例来激发您的胃口:

from random import randint
from time import sleep

PLAYERNAME = "Player1"
PLAYERHP = 15
PMINATK = 0
PMAXATK = 4


class CharacterDied(Exception):
    def __init__(self, msg):
        self.msg = msg


class Character:
    def __init__(self, name, initial_hp, minatk, maxatk):
        self.name = name
        self.hp = initial_hp
        self.minatk = minatk
        self.maxatk = maxatk

    def take_damage(self, damage_hp):
        self.hp -= damage_hp
        msg = "{} takes {:d}HP damage and has {:d} left."
        print(msg.format(self.name, damage_hp, self.hp))
        if self.hp < 0:
            msg = "{} died."
            raise CharacterDied(msg.format(self.name))

    def attack(self, other):
        dmg = randint(self.minatk, self.maxatk)
        sleep(1)
        other.take_damage(dmg)


def fight(char1, char2):
    try:
        while True:
            char1.attack(char2)
            char2.attack(char1)
    except CharacterDied as death_exception:
        print(death_exception.msg)


if __name__ == "__main__":
    player = Character(PLAYERNAME, PLAYERHP, PMINATK, PMAXATK)
    fight(player, Character("Monster1", 5, 1, 2))
    if player.hp > 0:
        fight(player, Character("Monster2", 6, 0, 2))

有很多方法可以做到这一点。为简单起见,我只编写了一个用于玩家和怪物的通用Character类,但是即使我们开始使用子类自定义它们,例如,战斗现在变得更加通用,我们也可以使用怪物攻击了玩家,因为它只是两个战斗角色的功能。

对于您最初的问题,尽管这里追求的好处是属性是通过实例对象保留和持久化的,通常比尝试处理和跟踪全局变量要容易得多。