【问题标题】:Python 3.2 script hang on third functionPython 3.2 脚本挂在第三个函数上
【发布时间】:2012-09-28 14:33:17
【问题描述】:

我正在尝试制作一个非常简单的 python 脚本,将两个字符放在一起,但是在运行脚本时,它执行脚本用来定义两个字符统计信息的前两个函数,但是当它到达第三个函数时,它只是挂起。

代码如下:

#STAPS: Strength Toughness Agility Perception weapon Skill
#A comparative simulator
import random
#Functions used to define character parameters
#Character 1's parameter function

def char1():
    global s1
    global t1
    global a1
    global p1
    global dam1
    global dt1
    global dr1
    global ac1
    global ws1
    s1 = int(input("Char1's Strength? "))
    t1 = int(input("Char1's Toughness? "))
    a1 = int(input("Char1's Agility? "))
    p1 = int(input("Char1's Perception? "))
    dam1 = int(input("Char1's Damage? "))
    dt1 = int(input("Char1's Damage Threshold? "))
    dr1 = int(input("Char1's Damage Resistance? "))
    ac1 = int(input("Char1's Armor Class? "))
    ws1 = int(input("Char1's Weapon Skill? "))

#Character 2's paramter function
def char2():
    global s2
    global t2
    global a2
    global p2
    global dam2
    global dt2
    global dr2
    global ac2
    global ws2
    s2 = int(input("Char2's Strength? "))
    t2 = int(input("Char2's Toughness? "))
    a2 = int(input("Char2's Agility? "))
    p2 = int(input("Char2's Perception? "))
    dam2 = int(input("Char2's Damage? "))
    dt2 = int(input("Char2's Damage Threshold? "))
    dr2 = int(input("Char2's Damage Resistance? "))
    ac2 = int(input("Char2's Armor Class? "))
    ws2 = int(input("Char2's Weapon Skill? "))

#Main battle function. Ordo Xenos calls this "complex and easy to misuse"
#Jury-rigged way of getting names, why did I include them anyways?

def stapsbatt(c1n,c2n,hp1,hp2):
    while hp1 > 0 or hp2 > 0:
    #determines original raw acc
        char1rawacc = ws1 - ac2
    #if statement settles it to minimum 95% acc
    if char1rawacc > 95:
        char1rawacc = 95
    #random int used to determine whether it's a hit or not
    char1hitnum = random.randint(0, 100)
    if char1rawacc > char1hitnum:
        moddam1 = dam1 - dt2
        if moddam1 < 0:
            moddam1 = 0
        rawdam1 = moddam1 * (100 - dr2)
        hp2 = hp2 - rawdam1
    #Now we move on to doing char2's batt calcs
    char2rawacc = ws2 - ac1
    if char2rawacc > 95:
        char2rawacc = 95
    char2hitnum = random.randint(0, 100)
    if char2rawacc > char2hitnum:
        moddam2 = dam2 - dt1
        if moddam2 < 0:
            moddam2 = 0
        rawdam2 = moddam2 * (100 - dr1)
        hp1 = hp1 - rawdam2
    if hp1 == 0:
        print(c2n, "has won!")
    else:
        print(c1n, "has won!")
    char1()
    char2()
    stapsbatt("Character 1", "Character 2",400,30)
    input("Press enter to exit. ")

是的,这段代码完全未经编辑,我意识到我的 cmets 不是很好。

【问题讨论】:

  • @Klikun,不要过度滥用全局变量。有更好的方法可以从不同的范围访问变量。
  • 你说“是的,这段代码完全未经编辑”,那为什么不编辑呢?添加一些打印语句来确定代码挂起的位置,然后发布(事实上它与全局相关等)。 [短,独立,正确(可编译),示例(]sscce.org):)
  • @Oz123 对不起!我最近了解了函数,并且一直想将这种模拟从笔和纸转移到脚本,所以我一有机会就跳了起来。虽然仍在学习,但我刚刚了解了范围和非常基本的类。
  • @hayden 我已经知道挂起的位置,我知道它是在第三个函数的开头,我只是不知道是什么原因造成的。我所说的未经编辑的意思是我希望这是我尴尬的 cmets 的借口。
  • “一开始”相当模糊,打印语句可以让你在精确的行上磨练(实际上 CRTL+C 会停止该过程并告诉你最后运行的行):)

标签: python python-3.2


【解决方案1】:

首先,您的 cmets 必须与代码处于相同的缩进级别。

【讨论】:

  • 这是什么原因造成的?无论如何我都会改变它,即使它不是。编辑:好的,这不是造成它的原因。
  • 另外,在撰写此消息时,您似乎也没有在函数体内有任何缩进。
【解决方案2】:

您可能正在寻找的问题:

while hp1 > 0 or hp2 > 0:
    #determines original raw acc
    char1rawacc = ws1 - ac2

这个循环永远不会结束,因为无论你在里面做什么都不会改变它的条件。可能你想要一个if

剩下的:天哪。看到这段代码很痛苦。让我们做得更好一点。

不要使用global,除非你有充分的理由这样做。现在,将其视为纪律问题;随着您作为程序员的进步,您会明白为什么范围分离很重要。

用函数描述相似的事物一次。重点是:删除重复的部分,用名称替换它们,用新的“单词”让你的语言更接近你正在解决的问题。

def get_character_description(name):
    print "Describe character %s" % name
    # input values here...
    return description

char1 = get_character_description('Liu Kang')
char2 = get_character_description('Sub Zero')

使用数据结构。在这种情况下,将角色的统计数据组合成一个实体。

# Use a dict to describe character stats
def get_character_description(name):
    description = {}
    description['name'] = name
    print "Describe character %s" % name
    description['strength'] = int(input("%s's strength?"))
    # input other values here...
    return description

char1 = get_character_description('Pikachu')
if char1['strength'] > 100: ...

在了解类时考虑创建一个自定义类来描述字符:

class Character(object):
    def __init__(self, name):
        self.name = name

    def input(self):
        print "Let's define stats of %s" % self.name
        self.strength = int(input("Strength?"))
        # and so on

char1 = Character('J.C. Denton')
if char1.strength > 100: ...

之后,您的代码可能如下所示:

char1 = get_character_description('Liu Kang')
char2 = get_character_description('Sub Zero')
if char1.wins_over(char2):
   print char1.name, "has won"
else:
   print char2.name, "has won"

【讨论】:

  • 是的,对代码很抱歉,我意识到它非常草率。在休息了大约 8 个月后,我才重新开始编写 Python,而当我停止写作时,我还是个新手。我仍然只知道高级编程的基础知识,所以我对类仍然一无所知。一旦我能理解它们,我肯定会提交这些更改。感谢您的建设性回应。
【解决方案3】:

您的代码存在一些问题导致它挂起。我建议熟悉一个 python 调试器,例如pdb。这将允许您在运行时查看值,逐行执行程序。

除了缩进问题,以下是我发现的问题区域:

  1. 在您的 while 循环中,您使用 while hp1 &gt; 0 and hp2 &gt; 0 作为您的条件。您不想在此处使用or,否则它将一直循环直到两个 字符的hp and。
  2. 在计算rawacc(对于两个字符)时,您使用了if char1rawacc &gt; 95,它实际上对char1rawacc 强制执行最大值。你对char2rawacc 做了同样的事情。将它们切换为 if char1rawacc &lt; 95if char2rawacc &lt; 95
  3. 作为一种风格说明,如果您将其作为脚本执行,您应该将函数调用放在函数定义本身之外,这样做的一个好方法是在脚本末尾放置这样的块:
如果 __name__ == "__main__": # 以下内容仅在文件作为脚本运行时才会执行 char1() char2() stapsbatt("字符 1", "字符 2", 400, 30)

希望这能让你摆脱无限循环!通过这些更改,我让游戏在我的电脑上运行。

现在,正如 Oz123 所提到的,您确实在滥用全局变量。相反,您应该研究创建和传递对象(请参阅 9000 的答案)。例如,您可以为您的角色定义一个类,并创建该类的两个实例(char1 和 char2),并传递给您的战斗函数。这也将使您免于大量冗余代码。这将需要一些重大的重组,但这是值得的。如果您遇到问题,请随时提出一个新问题。

【讨论】:

  • 酷,感谢您的回复。我对 Python 和一般编程还是很陌生,所以我总是有更多的东西要学。这些修复就像一个魅力,而那个“或”运算符对我来说是一个愚蠢的错误。
【解决方案4】:

两个不朽的角色(用“or->and”修复)=>无限循环

moddam1 = dam1 - dt2
if moddam1 < 0:
    moddam1 = 0                  # dam1 <= dt2: moddam1 = 0
rawdam1 = moddam1 * (100 - dr2)  # rawdam1 == 0
hp2 = hp2 - rawdam1              # hp2 == const: immortality

【讨论】:

    【解决方案5】:

    如果它让您感觉更好,那么这似乎不是您的程序的问题。 (没关系,是的,这是 while 语句)

    Traceback (most recent call last):
      File "C:\Python32\staps.py", line 89, in <module>
        stapsbatt("Character 1", "Character 2",400,30)
      File "C:\Python32\staps.py", line 76, in stapsbatt
        char2hitnum = random.randint(0,100)
      File "C:\Python32\lib\random.py", line 215, in randint
        return self.randrange(a, b+1)
      File "C:\Python32\lib\random.py", line 191, in randrange
        return istart + self._randbelow(width)
      File "C:\Python32\lib\random.py", line 221, in _randbelow
        getrandbits = self.getrandbits
    KeyboardInterrupt
    

    它挂在随机模块内,尽管尝试了其他几个功能(random.randrage(0,100)random.choice(range(0,100))),但问题仍然存在。奇怪的是,在程序之外调用函数没有问题。

    尝试稍微清理一下您的代码,看看它是否有所改进。一般来说,你的全局变量应该在开始时声明。另外,我认为您的意思是在这一行中说“和”而不是“或”:while hp1 &gt; 0 or hp2 &gt; 0:。在这种情况下使用 OR 意味着 char1 或 char2 是否存在。你只想坚持到战斗结束(当然,除非你喜欢打死马)。

    【讨论】:

      猜你喜欢
      • 2020-05-06
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 2023-02-08
      • 1970-01-01
      相关资源
      最近更新 更多