首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >业余RPG乐趣

业余RPG乐趣
EN

Code Review用户
提问于 2014-11-20 15:51:48
回答 1查看 2.2K关注 0票数 16

我正在寻找这个代码看起来更整洁,如果可能的话,不那么笨重。我对def和字典都很陌生,所以我认为在这里添加一些字典可以缩短代码。

下面是RPG的代码:

代码语言:javascript
复制
# RPG_TEST
#Dennis Gordick
#10/21/2014
"""
Task list:
fix bug where you can sell potions you don't have
allow player to leave battle
make battles more difficult
create different types of monsters
create a limit to the cave
add bosses
improve shop inventory
gain skill points every level to improve yourself
"""

import random
import time
import pickle
import shelve


response = input("New game or Load game? (Choose load or new)")
while response != "load" and response != "new":
    print(response + " is invalid input")
    response = input("New game or Load game? (Choose load or new)")

if response == "load":
    try:
        f = shelve.open("save.dat")
        attributes = f["attributes"]
        f.close()
        Name = attributes["Name"]
        Race = attributes["Race"]
        Class = attributes["Class"]
        Weapon = attributes["Weapon"]
        xp = attributes["xp"]
        player_lvl = attributes["player_lvl"]
        gold = attributes["gold"]
        potions = attributes["potions"]
    except:
        print("Save file is corrupt or doesn't exist")
        response = "new"
if response == "new":
    Name = input("What is your name?")
    Race = input("What is your race? (Your choices are Human, Elf, and Dwarf.)")
    Class = input("What is your class? (Your choices are Warrior, Archer, and Mage.")
    if Class == "Warrior":
        Weapon = "Sword"
        print("A " + Weapon + " is your weapon")
    elif Class == "Archer":
        Weapon = "Bow"
        print("A " + Weapon + " is your weapon")
    else:
        Weapon = "Staff"
        print("A " + Weapon + " is your weapon")

if Class == "Warrior":
    Weapon = "Sword"
    print("A " + Weapon + " is your weapon")
elif Class == "Archer":
    Weapon = "Bow"
    print("A " + Weapon + " is your weapon")
else:
    Weapon = "Staff"
    print("A " + Weapon + " is your weapon")

print("The " + str(Weapon) + " weilding " + str(Class) + " of the " + str(
    Race) + " clan, whent out on an adventure. There name was " + str(Name))

xp = 0
player_lvl = 1
extra_health = int(player_lvl) * 10
health = 90 + int(extra_health)
gold = 0
potions = 0

kill = 0
boss_kill = 0

while health > 0:

    extra_health = int(player_lvl) * 10
    health = 90 + int(extra_health)
    LVL_XP = 90 + int(extra_health)

    if int(xp) >= int(LVL_XP):
        player_lvl += 1
        print("Level Up! " + str(player_lvl))

    player_dmg_min = 0 + int(player_lvl)
    player_dmg_max = 7 + int(player_lvl)

    explore = input(
        "Do you want to explore or go to town or look at some stats/info or even save? (only say explore or town or info or save)")
    turns = 1
    if explore == "explore":
        lvl = input("What level monsters?")
        if lvl.isdigit():
            print("You explore")
            turns = 1
            while turns < 100 and int(health) > 0:

                monster_lvl = int(lvl)
                monster_dmg = int(lvl)
                monster_xp = int(lvl) / int(player_lvl) * 2
                monster_loot = int(monster_lvl)

                encounter = random.randint(1, 100)
                drop_lvl = int(lvl)

                #normal fight
                if int(encounter) >= 70:
                    print("You encounterd a LVL: " + str(monster_lvl) + " Monster!")
                    monster_health = int(monster_lvl) * 2
                    while int(monster_health) > 0 and health > 0:
                        print("Your Health: " + str(health))
                        print("Monsters Health: " + str(monster_health))

                        #Actual combat
                        attack = input("Do you attack or use a potion or run? (attack or potion or run)")

                        if attack == "attack":
                            hit = random.randint(1, 100)
                            if int(hit) <= 75:
                                dmg = random.randint(int(player_dmg_min), int(player_dmg_max))
                                monster_health = int(monster_health) - int(dmg)
                                print("\nYou did " + str(dmg) + " damage")
                            else:
                                print("You missed!")
                        elif attack == "potion":
                            if potions > 0:
                                health = 90 + int(extra_health)
                                print("Potions left... " + str(potions))
                            else:
                                print("You have no potions... You just waisted your turn!")

                        else:
                            print("You sit there and take it")
                        monster_hit_chance = random.randint(1, 100)
                        if int(monster_hit_chance) <= 60:
                            health = int(health) - int(monster_dmg)
                            print("The monster did " + str(monster_dmg) + " damage")
                        else:
                            print("The monster missed!")

                        #loot and xp for normal monster
                        if int(monster_health) <= 0:
                            xp = int(xp) + int(monster_xp)
                            print("\nThe monster died\n")
                            print("XP gained: " + str(monster_xp))
                            print("Your XP: " + str(xp))
                            loot_chance = random.randint(1, 100)

                            if int(loot_chance) < 10:
                                print("No loot :(")
                                print("Your gold " + str(gold))
                            elif int(loot_chance) < 70:
                                print("Your gold sir. It this many..." + str(monster_loot))
                                gold = int(gold) + int(monster_loot)
                                print("Your gold " + str(gold))
                            elif int(loot_chance) < 90:
                                print("Rare loot! 1 potoin!")
                                potions += 1
                                print("\nYour total potions " + str(potions))

                            kill += 1

                        elif int(health) <= 0:
                            print("You died")

                elif int(encounter) < 70:

                    loot = random.randint(1, 100)
                    trap = random.randint(1, 100)

                    if int(loot) >= 60:
                        gold = int(gold) + int(lvl)
                        print("You found " + str(lvl) + " gold")
                        print("You now have a total of " + str(gold) + " gold")
                    elif int(loot) <= 10:

                        if int(trap) >= 50:
                            health = int(health) - 10
                            print("You step on a trap")
                            print("You lost ten health")
                            print("Your total health is " + str(health))

                if int(turns) == 100:

                    #Boss fight

                    boss = random.randint(1, 10)

                    if int(boss) > 5:

                        print("Boss Fight!")
                        boss_health = int(health)
                        boss_xp = int(monster_xp) * 3
                        boss_dmg = int(lvl) * 3
                        boss_loot = int(lvl) * 100
                        run = input("Do you fight or run?")

                        while int(boss_health) > 0 and int(health) > 0 and run == "fight":

                            print("Your Health: " + str(health))
                            print("Boss Health: " + str(boss_health))
                            attack = input("Do you attack or use a potion? (attack or potion)")

                            if attack == "attack":

                                hit = random.randint(1, 100)

                                if int(hit) <= 75:

                                    dmg = random.randint(int(player_dmg_min), int(player_dmg_max))
                                    boss_health = int(boss_health) - int(dmg)
                                    print("\nYou did " + str(dmg) + " damage")

                                else:

                                    print("You missed!")

                            elif attack == "potion":

                                if potions > 0:

                                    health = 90 + int(extra_health)
                                    print("Potions left... " + str(potions))

                                else:

                                    print("You have no potions... You just waisted your turn!")

                            else:

                                print("You sit there and take it")

                            boss_hit_chance = random.randint(1, 100)

                            if int(boss_hit_chance) <= 60:

                                health = int(health) - int(boss_dmg)
                                print("The boss did " + str(boss_dmg) + " damage")

                            else:
                                print("The boss missed!")

                            if int(boss_health) <= 0:

                                xp = int(xp) + int(boss_xp)
                                print("\nThe boss died\n")
                                print("XP gained: " + str(boss_xp))
                                print("Your XP: " + str(xp))
                                loot_chance = random.randint(1, 100)

                                if int(loot_chance) < 10:
                                    print("No loot :(")
                                    print("Your gold " + str(gold))

                            elif int(loot_chance) < 90:

                                print("Your gold sir. It this many..." + str(boss_loot))
                                gold = int(gold) + int(boss_loot)
                                print("Your gold " + str(gold))

                            elif int(health) <= 0:

                                print("You died")

                            else:

                                print("Rare loot! 10 potoin!")
                                potions += 10
                                print("\nYour total potions " + str(potions))

                            boss_kill += 1

                print("End of turn " + str(turns) + "\n")
                turns += 1
                time.sleep(1.0)
        else:
            print("That isnt a lvl... your just not going to explore...")

    elif explore == "info":
        print("Total kills", str(kill))
        print("Total boss kills", str(boss_kill))
    #Going to town (giggity)

    elif explore == "town":
        town = input("Where do you want to go in town? (shop, inspector, blacksmith, tavern)")

        if town == "shop":
            print("Your gold " + str(gold))
            print("The shopkeep says 'We only have potions of health! They are 20 gold each!'")
            shop = input("How many do you want?")
            cost = int(shop) * 20

            if int(gold) >= int(cost):
                potions = int(potions) + int(shop)
                gold = int(gold) - int(cost)
                print("Gold left " + str(gold))
                print("Total potoins " + str(potions))

            else:
                print("'Your to poor! Come back with some gold fool!'\nThe shopkeeper kicks you out.")

        elif town == "inspector":
            print("Comeing soon")

        elif town == "blacksmith":
            print("Comeing soon")

        elif town == "tavern":

            print("Hello traveler, what can I do for you? A drink? Or the lates rumore?")
            bar_keep = input("Whats your choice? (drink, rumore, or leave)")

            if bar_keep == "drink":
                print("Drinks cost one gold.")
                drink = input("Do you want a drink?")

                if drink == "yes" and gold > 0:
                    gold = int(gold) - 1
                    print("Your gold: " + str(gold))
                    print("You get drunk out of your mind.")

                else:
                    print("Goodbye")

    elif explore == "save":
        #do you want extra_health or health saved?
        f = shelve.open("save.dat")
        attributes = {"Name": Name, "Race": Race, "Class": Class, "Weapon": Weapon, "xp": xp, "player_lvl": player_lvl,
                      "gold": gold, "potions": potions}
        f["attributes"] = attributes
        f.sync()
        f.close()
        print("Game saved")

我还有一个名为shelvingEx.py的保存文件程序:

代码语言:javascript
复制
import shelve

#opens file
f = shelve.open("save.dat")
gold = 2
potions = "3"
#sets all variables as a dictionary
f["attributes"] = {"gold": gold, "potions": potions}
#f.sync() adds all any f["whatever"] to the file
f.sync()
#always close after use!!!
f.close()

#reopen file later to read the contents
f = shelve.open("save.dat")
#save the variables still in dictionary form to a new variable
attributes = f["attributes"]
#always close after use!!!
f.close()
#access each variable individually, and save them to a new variable to match the rest of your code.
gold = attributes["gold"]
print(gold)

我能做些什么来缩小代码吗?或者对系统有什么改进吗?

对于实际的游戏和代码,下面是指向文件的链接。

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-11-20 18:06:01

您的代码非常大,但这不是真正的问题。真正的问题是您的代码不是由可重用/可理解/可测试/可维护的组件(函数、类、模块等)组成的。

但让我们一点一点地改变。

风格

Python有一个名为PEP 8的向导样式。如果你没有充分的理由不去追随它,那就跟随它。您将找到各种工具来检查您的代码(pep8pep8online.com/等),甚至可以或多或少地自动修复它(autopep8)。

问题清单主要是关于空白空间的,但是在它变得强大之前知道/修复总是很好的(嗯,我想太晚了)。

输入验证

在测试您的代码时,我注意到的第一件事是它没有检查我的输入。当问我是战士、弓箭手还是法师时,最好检查一下我是否提供了有效值。

很容易定义一个函数来提供这样的功能:

代码语言:javascript
复制
RACES = ['human', 'elf', 'dwarf']
CLASSES = ['warrior', 'archer', 'mage']

def get_input_in_list(prompt, values):
    while True:
        s = input(prompt + '(Your choices are : ' + ', '.join(values) + ')')
        if s in values:
            return s

if response == "new":
    Name = input("What is your name?")
    Race = get_input_in_list("What is your race", RACES)
    Class = get_input_in_list("What is your class ?", CLASSES)

更好的是,这看起来很像你为“新游戏”或“加载游戏”所做的。有人说过“可重用的组件”吗?

代码语言:javascript
复制
response = get_input_in_list("New game or Load game?", ['load', 'new'])

这也可以在其他地方重复使用,但我将让您处理这样做的乐趣。

不要重复你自己

不要重复你自己。

不要重复你自己。

很多事情看上去都不对:

代码语言:javascript
复制
if response == "new":
    Name = input("What is your name?")
    Race = get_input_in_list("What is your race", RACES)
    Class = get_input_in_list("What is your class ?", CLASSES)
    if Class == "Warrior":
        Weapon = "Sword"
        print("A " + Weapon + " is your weapon")
    elif Class == "Archer":
        Weapon = "Bow"
        print("A " + Weapon + " is your weapon")
    else:
        Weapon = "Staff"
        print("A " + Weapon + " is your weapon")


if Class == "Warrior":
    Weapon = "Sword"
    print("A " + Weapon + " is your weapon")
elif Class == "Archer":
    Weapon = "Bow"
    print("A " + Weapon + " is your weapon")
else:
    Weapon = "Staff"
    print("A " + Weapon + " is your weapon")

首先,您可能只需写:

代码语言:javascript
复制
    if Class == "Warrior":
        Weapon = "Sword"
    elif Class == "Archer":
        Weapon = "Bow"
    else:
        Weapon = "Staff"
    print("A " + Weapon + " is your weapon")


if Class == "Warrior":
    Weapon = "Sword"
elif Class == "Archer":
    Weapon = "Bow"
else:
    Weapon = "Staff"
print("A " + Weapon + " is your weapon")

但比,你可能是说:

代码语言:javascript
复制
if Class == "Warrior":
    Weapon = "Sword"
elif Class == "Archer":
    Weapon = "Bow"
else:
    Weapon = "Staff"
print("A " + Weapon + " is your weapon")

因为两次做事是没有意义的。

代码上的

数据

有时候,你必须写很多代码,因为“嘿,我有很多逻辑要写,我必须写代码,这是编程的重点”,但重点是保持简单,并使用正确的工具(并不总是代码)来做正确的事情。

代码中的一个示例是如何从类中获取默认武器。我们就不能定义一个简单的阶级和武器之间的关联吗。当然可以,我们可以用一个简单的字典来完成。更好的是,我们定义了一个常量列表,其中包含不同的类,但是我们可以将其作为字典重用。

代码语言:javascript
复制
CLASSES = {'warrior': 'sword', 'archer': 'bow', 'mage': 'staff'}
...
Weapon = CLASSES[Class]

就是这样。就这么简单。

基本逻辑

没有任何书面意义:

代码语言:javascript
复制
           # normal fight
            if int(encounter) >= 70:
                ...
            elif int(encounter) < 70:

如果第一个条件是假的,我猜第二个条件必须是真。只需使用一个简单的else

删除无用的转换

因为您的代码非常复杂,所以您会迷失自己,并且容易忘记您正在处理的对象是什么。

代码语言:javascript
复制
print(
    "The " +
    str(Weapon) +
    " weilding " +
    str(Class) +
    " of the " +
    str(Race) +
    " clan, whent out on an adventure. There name was " +
    str(Name))

四个字符串被转换成..。弦乐。

代码语言:javascript
复制
extra_health = int(player_lvl) * 10

整数转换为整数(这个整数到处都是)。

您正在执行的几乎每一个转换都是毫无意义的。

用户体验

当我读到:

代码语言:javascript
复制
        print(
            "Hello traveler, what can I do for you? A drink? Or the lates rumore?")
        bar_keep = input("Whats your choice? (drink, rumore, or leave)")

        if bar_keep == "drink":
            print("Drinks cost one gold.")
            drink = input("Do you want a drink?")

            if drink == "yes" and gold > 0:
                gold = int(gold) - 1
                print("Your gold: " + str(gold))
                print("You get drunk out of your mind.")

            else:
                print("Goodbye")

我认为这对任何球员来说都是非常令人困惑的:你被要求做一些可能或不相关的事情。

首先,我可以选择“鲁莫尔”或“离开”,但我觉得他们也会做同样的事情。

然后,在检查我是否有足够的饮料之前,有人问我是否想喝酒。

代码语言:javascript
复制
        bar_keep = get_input_in_list("What's your choice?", ['drink', 'leave']

        if bar_keep == "drink":
            print("Drinks cost one gold. You have " + str(gold))
            if gold > 0:
                if get_input_in_list("Do you want a drink?", ['yes', 'no']) == 'yes':
                    gold = int(gold) - 1
                    print("Your gold: " + str(gold))
                    print("You get drunk out of your mind.")
            print("Goodbye")

还有很多东西可以改进,但最主要的是将代码分割成更小的部分。

票数 28
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/70436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档