2012-09-28 12 views
0

我想製作一個非常簡單的Python腳本,它將兩個字符放在一起,但在運行腳本時,它會執行腳本用來定義兩個字符統計信息的前兩個函數,但當它到達第三個函數時,它就會掛起。Python 3.2腳本掛在第三個函數

下面的代碼:

#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. ") 

是的,這個代碼是完全未經編輯的,我知道我的意見是不是很好。

+1

@Klikun,不要濫用全局變量太多。有更好的方法來訪問來自不同作用域的變量。 – Oz123

+1

你說「是的,這段代碼完全未經編輯」,那爲什麼不編輯它?添加一些print語句來確定代碼在哪裏掛起,然後發佈(實際上它是全局相關的等等)。 [簡短,獨立,正確(可編譯),示例(] http://sscce.org/):) –

+0

@ Oz123對不起!我最近了解了功能,並且一直有意將這種模擬從筆和紙轉移到腳本,所以我跳出了我的第一次機會。儘管如此,我剛剛瞭解了範圍和非常基礎的課程。 – Kilkun

回答

1

首先,您的註釋必須與代碼具有相同的縮進級別。

+0

這是什麼可能導致它?無論如何,我會改變它,即使它不是。編輯:好的,這不是什麼原因造成的。 – Kilkun

+0

也是,在編寫此消息時,您似乎沒有任何內部函數體內的縮進。 – zeffii

+0

我做了,但他們沒有繼續粘貼的代碼。 – Kilkun

1

你可能要查找的問題:

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

這個循環永遠不會結束,因爲無論你做什麼裏面從來沒有改變其狀態。可能你想要一個if

其餘:OMG。看到這段代碼很痛。讓我們更好一點。除非你有充分的理由這麼做,否則不要使用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" 
+0

是的,對於代碼抱歉,我意識到這是非常草率。我剛剛在大約8個月的休息時間後重新編寫了Python,而當我停止寫作時,我仍然是一名新手。我仍然只知道高級編程的基礎知識,所以對類仍然一無所知。只要我能理解,我一定會做出這些改變。感謝您的建設性迴應。 – Kilkun

1

有幾個問題與您的代碼,導致它掛起。我建議熟悉python調試器,如pdb。這將允許您在運行時查看值,逐行執行程序執行。

壓痕問題不談,這裏是有問題的地方,我發現:

  1. 在while循環,你用while hp1 > 0 and hp2 > 0爲作爲條件。你不想在這裏使用or,或者它將保持循環,直到字符有< 0馬力,所以你應該改變它爲and
  2. 在計算rawacc(對於兩個字符)時,您使用的是if char1rawacc > 95,它實際上在char1rawacc上強制執行最大值。你做了同樣的事情char2rawacc。切換到if char1rawacc < 95if char2rawacc < 95
  3. 作爲樣式說明,如果您將其作爲腳本執行,則應該將函數調用放在函數定義本身之外,這樣做的一個好方法是在腳本的末尾放置一個如下所示的塊:
 
    if __name__ == "__main__": 
     # the following only gets executed if the file is run as a script 
     char1() 
     char2() 
     stapsbatt("Character 1", "Character 2", 400, 30) 

希望這可以讓你擺脫你的無限循環!這些改變讓我的電腦能夠在我的電腦上工作。

現在,正如Oz123所提到的,你真的在​​濫用全局變量。相反,你應該研究創建和傳遞對象(參見9000的答案)。例如,您可以爲您的角色定義一個類,並創建該類的兩個實例(char1和char2),並將其傳遞給您的戰鬥功能。這也可以爲您節省大量冗餘代碼。這將需要一些重大的重組,但這將是值得的。如果遇到問題,請隨時打開一個新問題。

+0

很酷,謝謝你的回覆。我對Python仍然很陌生,一般來說編程,所以我總是有更多東西要學習。這些修復工作像一個魅力,而「或」運營商是我的一個愚蠢的錯誤。 – Kilkun

0

如果它讓你感覺好一點,它似乎不是你的程序的問題。 (沒關係的確是這樣,它的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 > 0 or hp2 > 0:。在這種情況下使用OR意味着如果char1或char2存在。你只想去戰鬥結束(除非你喜歡摔死一匹死馬)。

1

兩個不朽的字符( 「或 - >和」 修復)=>無限循環

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