繁体   English   中英

我可以从列表中调用函数吗? (python2.7)

[英]Can I call a function from within a list? (python2.7)

我想我所有的问题都对了……但是我不确定。 基本上,我想做的是在文字游戏中获得我的存货和装备的详细信息。

我想要做的是拥有一把武器,放开剑,我希望它能够改变角色本身的某些方面。 让角色的hp增加... 5,在这种情况下,我要的是(不要介意草率的工作!)

global basehp
basehp = 10
global armorhp
armorhp = 0
global skillhp
skillhp = 0
global hpmod
hpmod = (skillhp + armorhp)
global righthand
righthand = 0

因此,以hp为榜样,这就是我程序中实际拥有的东西,现在我想做的就是更改armourhp以匹配其将更改的盔甲,比如说我的剑对我的hp加了5吗? 我现在正在使用的设备无法正常工作,起初我以为只是装备它,然后给Armourhp加5,然后我开始考虑取消装备...效果会是一样的...我将向您展示我的意思是

def hpsword:
    armorhp = (armorhp + 5)

def prompt():
    x = raw_input("Type command>>")
    if x == 'equip':
        print "equip what?"
        print inventory
        y = raw_input(">>>>")
        if y == 'sword':
            if 'hpsword' in inventory:
                global righthand
                righthand = 1
                inventory.remove ('hpsword')
                equipmentlist.append ('hpsword')

现在从这里开始,您会注意到我遗漏了一些东西,例如我的清单,我正要去那儿,但这是我真正可以解释我的意思的更多地方,我想使用这样的每个项目,但是我可以不知道如何...我很困惑,我知道,我有很多想法,但是我想做类似...的事情。

def this sword():
    this sword does this thing!

然后当它被装备时添加它的效果,例如+5生命值,然后将其删除并使用它,而不必使用一堆语句执行100行代码,哦,添加此效果,但是当您不想再使用它,将其右手重置为0,然后如果将其更改为数字2,然后再添加10,则从该数字中删除大量的数字。

我也在努力避免装备剑,获得5点生命值,不装备,还是5点? 好,装备,10耶!

如果我完全没有道理,我会感到震惊...但是,如果有人能弄清我的意思,并给我一些提示,那将是很棒的!

编辑:

读完评论中剩下的内容,(谢谢那个伊芙!)我想我开始有点...非常少了。

然后,我要问一个新问题,我是否要为主要角色开一门课,例如,

class character(object):

然后添加init

def __init__(self)

那我会定义库存吗

def __init__(self)

def inventory

还是我会这样做,

def __init__(self, inventory)

抱歉,如果我问了太多问题,只是想弄清楚,我注意到这里的人很好,至少可以看一下我自己想要的程序员提出的问题:D

另一个编辑!

再次感谢吨伊夫! 这是有道理的,尽管通读它仍然使我对如何将其添加到我的代码中以及对于某些其他项目需要更改的内容感到有些困惑。

为了解释一下,当我说不同的项目时,您给了我

class Sword(object):
    def visit_health_bonus(self, character):
        return 5

如果我想要一把做其他事情的剑,我会创建一个具有不同名称的新类,但是基本上是一样的吗?

class Sword2(object):
    def visit_strength_bonus(self, character):
        return 2

那会给我一把剑,使我的力量加2对吗?

现在我的另一个问题是,当我尝试使用它时,我真正需要什么才能使其正常工作,我看到很多我认为没有其他东西就无法运行的东西

class Sword(object):
    def visit_health_bonus(self, character): 
        return 5

# Then, every turn, recalculate health:
health = player.base_health
for equipment in player.equipment:   //would i need another class here? (player)
    # Pretend this lists everything the player has equipped; you might
    # have to check each hand manually
    health += equipment.visit_health_bonus(player)  //also going to think a class (equipment)

我假设您熟悉对象。 如果没有,您应该在继续之前认真阅读它们(LPTHW确实很棒),因为它们对于Python来说非常重要。 如果是这样,您应该真正使用Player对象而不是六个全局对象。

真正简单的方法是让剑成为在装备和未装备时会填满东西的物体:

class Sword(object):
    health_bonus = 5

    def on_equip(self, character):
        character.health += self.health_bonus

    def on_unequip(self, character):
        character.health -= self.health_bonus

然后调用on_equip当玩家装备的剑, on_unequip当玩家unequips它。 其他武器可能具有类似的事件挂钩,可能用于不同的统计数据。

一切都很好,但是这件事使我感到on_unequip每当玩家丢失一件物品时,您都必须记住调用on_unequip ,并且可能发生的方式不止一种。 您还必须分别跟踪玩家的“基础”健康状况,如果它发生变化,则更新“计算的”健康状况需要取消装备并重新装备武器,这没有什么意义。

因此,让我们尝试其他事情。 Marcin所说的“访问者模式”是指(大致)遍历一个较大整体的所有部分,并对它们调用相同的方法。 在这种情况下,您想询问所有播放器设备是否赋予其额外的生命值。

class Sword(object):
    def visit_health_bonus(self, character):
        return 5

# Then, every turn, recalculate health:
health = player.base_health
for equipment in player.equipment:
    # Pretend this lists everything the player has equipped; you might
    # have to check each hand manually
    health += equipment.visit_health_bonus(player)

现在,您可以计算每次需要的总生命值,因此不必担心在玩家升级时进行更新。 您也不必担心未配备某些设备时会做额外的记账工作:一旦它从设备列表中消失,它就会停止贡献。

这仍然有点不灵活,因为它不容易支撑,例如在与龙搏斗时使你的攻击力加倍的剑。 解决此问题的最一般方法涉及到许多纠结和多余的对象,并弄清楚首先需要发生什么效果,而我尚未使它满意。 希望以上方法是一个足够好的起点。 :)

解决此问题的最灵活方法是使“装备有武器的攻击”本身成为对象,并使装备,玩家,目标等都通过增加属性来对攻击做出反应。 但是,那么您有优先权的问题确实需要解决,所以我们不要这样做。

听起来您似乎错过了一些很棒的面向对象编程实用程序,类似于Marcin所说的,您可能会制作一系列这样的类:

class Weapon:
    def __init__(self, name, armor_hp_bonus = 0, skill_hp_bonus = 0):
       self.skill_hp_bonus = skill_hp_bonus
       self.armor_hp_bonus = armor_hp_bonus
       self.__name__ = name

class Hero:
    def __init__(self):
        self.basehp = 10
        self.armorhp = 0
        self.skillhp = 0
        self.righthand = None
        self.inventory = []

    def choose_weapon(self):
        while True:
            for idx, item in enumerate(self.inventory):
                print '{i}: {weapon}'.format(i=idx, weapon=item.__name__)
                choice = raw_input("Pick your weapon: ")
                try:
                    self.equip(self.inventory.pop(int(choice)))
                    return
                except IndexError:
                    print "Invalid choice"
                    continue

    def equip(self, weapon):
        if self.righthand:
            print "Weapon already equipped to right hand!"
            return
        else:
            self.righthand = weapon
            self.armorhp += weapon.armor_hp_bonus
            self.skillhp += weapon.skill_hp_bonus

    def unequip(self):
        if not self.righthand:
            print "No weapon to unequip!"
            return
        self.skillhp -= self.righthand.skill_hp_bonus
        self.armorhp -= self.righthand.armor_hp_bonus
        self.inventory.append(self.righthand)
        self.righthand = None

    def acquire_weapon(self, weapon):
        self.inventory.append(weapon)

    def calc_effective_hp(self):
        return self.basehp + self.skillhp + self.armorhp

类使您可以将所有难以跟踪的变量都放在一个位置。 这样,一个武器的技能加值将永远不会与另一武器的技能加值相混淆,因为存储该信息的变量包含在对象中。 您可以正确设置类,而代码的其余部分则更短,更简洁,因为您可以调用方法并放心所有操作均正确完成:

sword_of_1000_truths = Weapon('sword_of_1000_truths', skill_hp_bonus = 1337)
gandalf = Hero()

gandalf.acquire_weapon(sword_of_1000_truths)
gandalf.choose_weapon()

>> 0 sword_of_1000_truths
>> Pick your weapon: 0


print gandalf.calc_effective_hp()
>> 1347

gandalf.unequip()

print gandalf.calc_effective_hp()
>> 10

equipunequip equip的方法可确保正确增加和减少Hero的hp,同时跟踪游戏的逻辑,即您不能一手拥有两把武器,而如果没有,则不能取消装备。没有配备等。这有助于消除您提到的丑陋的100行代码。

祝好运! 希望这可以帮助

有两件事:

  1. 您有5个全局变量。 这些应该移到一个类中,并且您的函数将成为该类上的方法。

  2. 像这样工作的通常方法是使剑支持一个特定的接口,该接口定义了它进行的修改以及角色类可以读取的内容。 或者,使用访客模式,并让角色将自己传递给装备/不装备上的剑法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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