0

私は2つの文字を一緒にピットする非常に単純なpythonスクリプトを作成しようとしていますが、スクリプトの実行中に、スクリプトが2つの文字の統計を定義するために使用する最初の2つの関数を実行しますが、3番目の関数に到達すると、ハングします。

コードは次のとおりです。

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

はい、このコードは完全に編集されていません。私のコメントがあまり良くないことに気づきました。

4

5 に答える 5

1

コードにいくつかの問題があり、コードがハングします。pdbなどのPythonデバッガーに慣れることをお勧めします。これにより、実行時に値を確認し、プログラムの実行を1行ずつ実行できます。

インデントの問題はさておき、私が見つけた問題領域は次のとおりです。

  1. whileループではwhile hp1 > 0 and hp2 > 0、条件として使用します。ここでは使用しないでください。そうしないと、両方のor文字のhpが0未満になるまでループが続くため、に変更する必要があります。and
  2. rawacc(両方の文字について)計算するときに、を使用しました。if char1rawacc > 95これは、実際にはに最大値を適用しchar1rawaccます。あなたはのために同じことをしましたchar2rawacc。これらをif char1rawacc < 95とに切り替えますif char2rawacc < 95
  3. スタイルノートとして、これをスクリプトとして実行する場合は、関数呼び出しを関数定義自体の外に配置する必要があります。これを行うための良い方法は、スクリプトの最後に次のようなブロックを配置することです。
    __name__ == "__main__"の場合:
        #以下は、ファイルがスクリプトとして実行されている場合にのみ実行されます
        char1()
        char2()
        stapsbatt( "キャラクター1"、 "キャラクター2"、400、30)

うまくいけば、これで無限ループから抜け出すことができます!これらの変更を加えて、コンピューターでゲームを動作させました。

さて、Oz123が述べているように、あなたは本当にグローバル変数を悪用しています。代わりに、オブジェクトの作成と受け渡しを検討する必要があります(9000の回答を参照)。たとえば、キャラクターのクラスを定義し、このクラスの2つのインスタンス(char1とchar2)を作成して、バトル関数に渡すことができます。これにより、多くの冗長なコードからも節約できます。これには大幅なリストラが必要になりますが、それだけの価値はあります。それで問題が発生した場合は、新しい質問を開いてください。

于 2012-09-28T15:14:35.483 に答える
1

おそらく探している問題:

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

内部で何をしてもその状態が変わらないため、このループは決して終了しません。おそらく、あなたはif.

残り:OMG。このコードを見ると痛いです。もう少し良くしましょう。

globalよほどの理由がない限り使用しないでください。今のところ、これは規律の問題だと考えてください。プログラマーとして進歩するにつれて、スコープの分離が重要である理由がわかります。

関数を使用して、同様のことを1 回記述します。繰り返し部分を削除し、それらを名前に置き換え、新しい「単語」に置き換えて、言語を解決している問題に近づけることが重要です。

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')

データ構造を使用します。この場合、キャラクターのステータスを 1 つのエンティティに結合します。

# 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"
于 2012-09-28T15:09:53.867 に答える
1

まず、コメントはコードと同じインデント レベルにする必要があります。

于 2012-09-28T14:36:10.117 に答える
1

2 つの不滅の文字 ("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
于 2012-09-28T15:22:55.210 に答える
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)))を試しても、問題は依然として発生します。奇妙なことに、プログラムの外部で関数を呼び出すことに問題はありません。

コードを少しクリーンアップして、改善されるかどうかを確認してください。通常、グローバルは最初に宣言する必要があります。また、次の行で「または」の代わりに「and」と言うことを意味していると思いますwhile hp1 > 0 or hp2 > 0:。この場合にORを使用することは、char1またはchar2が有効であるかどうかを意味します。あなたは戦いが終わるまで行きたいだけです(もちろん、あなたが死んだ馬を倒すのが好きでない限り)。

于 2012-09-28T15:21:00.153 に答える