Python 基于文本的RPG:如何对用户输入应用冷却

Python 基于文本的RPG:如何对用户输入应用冷却,python,python-2.7,Python,Python 2.7,假设我有一个名为治疗的咒语。如何防止用户在每次受到损坏时滥发heal。我曾考虑将此应用于单个作战功能;然而,我不知道如何实施这方面的全球规则?此代码可能会将其清除: available_spells = ['fireball', 'heal'] equipped = {'Weapon': "Staff", 'Armor': "Robes", 'Spells': ['fireball', 'heal']} print "Your available s

假设我有一个名为治疗的咒语。如何防止用户在每次受到损坏时滥发heal。我曾考虑将此应用于单个作战功能;然而,我不知道如何实施这方面的全球规则?此代码可能会将其清除:

available_spells = ['fireball', 'heal']
equipped = {'Weapon': "Staff",
           'Armor': "Robes",
           'Spells': ['fireball', 'heal']}

print "Your available spell(s) is(are) '%s'. " % equipped["Spells"]
inp = raw_input("Type the name of a spell you want to use.: ").lower()
lst = [x for x in available_spells if x.startswith(inp)]
    if len(lst) == 0:
        print "No such spell"
        print ' '
    elif len(lst) == 1:
        spell = lst[0]
        print "You picked", spell
        #COMBAT FUNCTIONS HERE
    else:
        print "Which spell of", equipped["Spells"], "do you mean?"
如果我要创建一个类来定义咒语要执行的特定操作,我如何在我的代码中实现它?例如,如果我有一类咒语,有定义伤害规则、冷却时间等的函数,我如何在我已有的代码中引用该函数?i、 玩家输入“治疗”,我希望它引用上面的一个类,该类定义了这些值,以检查玩家是否最近使用了该咒语,以及在使用该咒语时做了什么


我在这个问题上够清楚吗?我应该如何写一个法术冷却机制?如何在上述代码中实现这一机制?

您可以将所有可用法术存储为字典,而不是将其存储为列表,这样您还可以存储所需的冷却时间:

available_spells = {
    # spell name: cooldown duration in seconds
    'fireball': 3.0,
    'heal': 5.0,
}
每个玩家可以有另一个记录他们上一次施法时间的记录。当游戏开始时,它将是空的:

cast_spells = {}
当玩家试图施法时,检查法术名称是否在
cast\u咒语中。如果不是,则表示他们尚未在本游戏中施法,因此允许他们施法:

if spell_name not in cast_spells:
    cast_spells[spell_name] = datetime.now()
否则,如果咒语名称在施法咒语中,请检查所需的冷却时间是否已过:

elif cast_spells[spell_name] + datetime.timedelta(seconds=spells[spell_name]) < datetime.now():
    cast_spells[spell_name] = datetime.now()

我可能会使用
、一个异常处理程序和一个简单的计时器来完成。这样你就可以重复冷却模式,共享冷却(如下图所示),甚至全局冷却,等等

以下是课程:

import time

class CooldownException(Exception):
    pass

class Cooldown(object):
    def __init__(self, seconds):
        self.seconds = seconds
        self.expire = None
    def __enter__(self): 
        if not self.expire or time.time() > self.expire:
            self.expire = time.time() + self.seconds
        else:
            raise CooldownException('Cooldown not expired!')
    def __exit__(self, type, value, traceback):
        pass

heal_cooldown = Cooldown(5)

def heal():
    try:
        with heal_cooldown:
            print 'You heal yourself!'
    except CooldownException as e:
        print e

def apply_bandage():
    try:
        with heal_cooldown:
            print 'You bandage yourself!'
    except CooldownException as e:
        print e

def drink_potion():
    try:
        with heal_cooldown:
            print 'You quaff a potion!'
    except CooldownException as e:
        print e
下面是它们的使用方法:

>>> heal()
You heal yourself!
>>> time.sleep(3)
>>> drink_potion()
Cooldown not expired!
>>> time.sleep(3)
>>> apply_bandage()
You bandage yourself!
如果我要创建一个类来定义咒语要执行的特定操作,我如何在我的代码中实现它

正如您所猜测的,您的问题非常适合于课堂

我在这个问题上够清楚吗

你的程序,但是有课程 这里是您的程序修改为使用两个自定义类,
FireballSpell
HealSpell
。每个都有一个
.name
,它是一个字符串,还有一个
.cast()
,它是一种自定义行为。它与您的原始代码几乎相同,因此您应该很容易理解:

available_spells = [FireballSpell(), HealSpell()]
equipped = {'Weapon': "Staff",
           'Armor': "Robes",
           'Spells': [FireballSpell(), HealSpell()]}

while True:

    print "Your available spell(s) is(are) '%s'. " % [spell.name for spell in equipped["Spells"]]
    inp = raw_input("Type the name of a spell you want to use.: ").lower()
    lst = [spell for spell in available_spells if spell.name.startswith(inp)]
    if len(lst) == 0:
        print "No such spell"
        print ' '
    elif len(lst) == 1:
        spell = lst[0]
        print "You picked", spell.name
        spell.cast()
    else:
        print "Which spell of", [spell.name for spell in equipped["Spells"]], "do you mean?"

    print ""
运行它并尝试一下!这是完整的脚本。我很确定这正是你想要的

特殊咒语 每个特定类都有名称、冷却时间和特定行为。父级
拼写
类(见下)处理其余部分

class FireballSpell(Spell):

    def __init__(self):
        self.name = "fireball"
        self.cooldown_seconds = 5

    def spell_specific_behaviour(self):
        # do whatever you like with fireball
        # this is only called if the spell has cooled down
        print "casting fireball"


class HealSpell(Spell):

    def __init__(self):
        self.name = "heal"
        self.cooldown_seconds = 10

    def spell_specific_behaviour(self):
        # same applies here as from FireballSpell
        print "casting heal"
拼写
类 这是一个通用的
法术
类-所有法术的父级。它知道名字、冷却时间和特定法术的行为(上面的子类)。它也有通用的冷却机制,由法术共享:

class Spell:

    # spell data - filled in by specific spells
    name = "default"
    cooldown_seconds = 0
    last_cast_time = 0

    def cast(self):
        # only cast the spell if it has cooled down
        if self.is_cooled_down():
            # call the behaviour set by the specific spell
            self.spell_specific_behaviour();
            # set the last cast time to the current time
            self.last_cast_time = time.time()
        else:
            print self.name + " has not cooled down yet!"

    def spell_specific_behaviour(self):
        # implement in specific spell subclasses
        return

    def is_cooled_down(self):
        current_time_seconds = time.time()
        cooldown_expire_time_seconds = self.last_cast_time + self.cooldown_seconds

        return current_time_seconds > cooldown_expire_time_seconds
同样,整个过程都在一个工作脚本中完成。玩得开心


META:装饰器、异常和带有
块的
?哇,伙计们。OP正在学习课程。让我们在这里保持简单


这里是另一个使用装饰器的示例

from functools import wraps

class Cooldown(object):
    def __init__(self, seconds, cooldown_message):
        self.seconds = seconds
        self.expire = None
        self.cooldown_message = cooldown_message
    def decorator(self, fail_message_callback):
        def _wrap_decorator(foo):
            def _decorator(*args, **kwargs):
                if not self.expire or time.time() > self.expire:
                    self.expire = time.time() + self.seconds
                    result = foo(*args, **kwargs)
                    return result
                else:
                    if fail_message_callback:
                        fail_message_callback(self.cooldown_message)
                    return None
            return wraps(foo)(_decorator)
        return _wrap_decorator

heal_cooldown = Cooldown(5, 'Cooldown not expired!')

def display(message):
    print message

@heal_cooldown.decorator(display)
def heal():
    display('You heal yourself!')

@heal_cooldown.decorator(display)
def apply_bandage():
    display('You bandage yourself!')

@heal_cooldown.decorator(display)
def drink_potion():
    display('You quaff a potion!')


heal()
time.sleep(3)
drink_potion()
time.sleep(3)
apply_bandage()

您可能应该在其他文件中包含这些类,并将它们导入到此文件中。这将允许您引用这些类中的函数。您还需要(在代码中或通过解析器)定义一个拼写库/数据库。您可以使用时间的概念,以及根据时间点采取的行动列表来帮助确定冷却时间。我认为这个问题可能有点过于开放,无法在这里得到很好的答案。这是正确的想法。然而,
cast_拼写
是一本“跟踪上次施放每个拼写的时间”的词典,因此名称
cast_拼写
不准确或不具体。它应该被命名为类似于
法术\u上一次\u施法\u时间
。一个尚未冷却的法术是正常行为,不是例外,所以这里不应该使用例外。
from functools import wraps

class Cooldown(object):
    def __init__(self, seconds, cooldown_message):
        self.seconds = seconds
        self.expire = None
        self.cooldown_message = cooldown_message
    def decorator(self, fail_message_callback):
        def _wrap_decorator(foo):
            def _decorator(*args, **kwargs):
                if not self.expire or time.time() > self.expire:
                    self.expire = time.time() + self.seconds
                    result = foo(*args, **kwargs)
                    return result
                else:
                    if fail_message_callback:
                        fail_message_callback(self.cooldown_message)
                    return None
            return wraps(foo)(_decorator)
        return _wrap_decorator

heal_cooldown = Cooldown(5, 'Cooldown not expired!')

def display(message):
    print message

@heal_cooldown.decorator(display)
def heal():
    display('You heal yourself!')

@heal_cooldown.decorator(display)
def apply_bandage():
    display('You bandage yourself!')

@heal_cooldown.decorator(display)
def drink_potion():
    display('You quaff a potion!')


heal()
time.sleep(3)
drink_potion()
time.sleep(3)
apply_bandage()