如果密钥存在不更改值,则检查并更新字典

时间:2017-11-06 17:55:58

标签: python python-3.x dictionary

我正在尝试制作基于终端的游戏。到目前为止,我有一个示例类,一个默认值的默认播放器,以及一个用于检查更新值的测试文件。在发布时,我希望使用播放器默认值,但是如果加载了保存或新游戏开始,则首先要设置一个类,该类应该覆盖播放器值FOR THAT FILE / SESSION ONLY。但是,在多次尝试更改代码后,它会在随机key/pair上抛出错误或不更新该值。有一次,它确实更新了值,但没有正确更新。这是我的代码。 来自集合导入OrderedDict,Counter

player.py

import assets.classes
import random
#import pickle

#begin player data for new slate

class playerSelf:
    def __init__(self):
        #set starter gold variable
        startGold = random.randint(25,215)*2.5
        self.playerStats = Counter({
            'currentHealth': int(100),
            'maxHealth': int(100),
            'stamina': int(10),
            'resil': int(2),
            'armor': int(20),
            'strength': int(15),
            'agility': int(10),
            'criticalChance': int(25),
            'spellPower': int(15),
            'speed': int(5),
            #set gold as random gold determined from before
            'gold': startGold,
            'name': {'first': 'New', 'last': 'Player'},
            'class': None
        })

    def __str__(self):
        return self.playerStats

    def returnStats(self, category):
        category = category.upper()

        if(category == "OFFENSIVE"):
            #print offensive stats
            print("Strength: {}\nAgility: {}\nCritical Chance: {}\nSpell Power: {}".format(self.playerStats['strength'], self.playerStats['agility'], self.playerStats['criticalChance'], self.playerStats['spellPower']))
        elif(category == "DEFENSIVE"):
            #print defensive stats
            print("Health: {}/{}\nStamina: {}\nResilience: {}\nArmor: {}\nSpeed: {}".format(self.playerStats['currentHealth'], self.playerStats['maxHealth'], self.playerStats['stamina'], self.playerStats['resil'], self.playerStats['armor'], self.playerStats['speed']))
        elif(category == "ALL"):
            #print both offensive and defensive stats
            print("Strength: {}\nAgility: {}\nCritical Chance: {}\nSpell Power: {}\nHealth: {}/{}\nStamina: {}\nResilience: {}\nArmor: {}\nSpeed: {}".format(self.playerStats['strength'], self.playerStats['agility'], self.playerStats['criticalChance'], self.playerStats['spellPower'], self.playerStats['currentHealth'], self.playerStats['maxHealth'], self.playerStats['stamina'], self.playerStats['resil'], self.playerStats['armor'], self.playerStats['speed']))
        else:
            print("Nothing Found.")

    #key function
    def setPath(self, path):
        path = path.upper()
        select = assets.classes.classPath().classDeclare
        chosen = select.get(path, 'That class doesn\'t exist!')
        if chosen is not 'That class doesn\'t exist!':
            for key in select[path]['stats']:
                for key2 in self.playerStats:
                    if key in select[path] and key2 in self.playerStats:
                        self.playerStats[key2] = select[path][key]

classes.py

from collections import OrderedDict, Counter
import assets.player

class classPath:
    def __init__(self):
        #declare player variables
        maxHealthDefault = assets.player.playerSelf().playerStats['maxHealth']
        staminaDefault = assets.player.playerSelf().playerStats['stamina']
        resilDefault = assets.player.playerSelf().playerStats['resil']
        armorDefault = assets.player.playerSelf().playerStats['armor']
        strengthDefault = assets.player.playerSelf().playerStats['strength']
        agilityDefault = assets.player.playerSelf().playerStats['agility']
        criticalChanceDefault = assets.player.playerSelf().playerStats['criticalChance']
        spellPowerDefault = assets.player.playerSelf().playerStats['spellPower']
        speedDefault = assets.player.playerSelf().playerStats['speed']

        self.classDeclare = Counter({
            'DEFAULT': {
                'name': 'dummy',
                'description': 'dummy',
                'gearWeight': None,
                'stats': {
                    'maxHealth': maxHealthDefault,
                    'stamina': staminaDefault,
                    'resil': resilDefault,
                    'armor': armorDefault,
                    'strength': strengthDefault,
                    'agility': agilityDefault,
                    'criticalChance': criticalChanceDefault,
                    'spellPower': spellPowerDefault,
                    'speed': speedDefault
                }
            },
            'WARRIOR': {
                #define name of class for reference
                'name': 'Warrior',
                #define description of class for reference
                'description': 'You were  born a protector. You grew up to bear a one-handed weapon and shield, born to prevent harm to others. A warrior is great with health, armor, and defense, but low damage.',
                #define what the class can equip
                'gearWeight': ['Cloth', 'Leather', 'Mail', 'Plate'],
                #define stat modifiers
                'stats': {
                    #increase, decrease, or leave alone stats from default
                    'maxHealth': maxHealthDefault + 15,
                    'stamina': staminaDefault * 1.25,
                    'resil': resilDefault * 1.25,
                    'armor': armorDefault * 1.35,
                    'strength': strengthDefault * 0.60,
                    'agility': agilityDefault,
                    'criticalChance': criticalChanceDefault * 0.75,
                    'spellPower': spellPowerDefault * 0.40,
                    'speed': speedDefault - 2
                }
            },
            'BERSERKER': {
                'name': 'Berserker',
                'description': 'You are born with the blood, strength, and anger of a viking. Your training since young age has allowed you to dual wield two two-handed weapons, find weak spots in your enemies, and build the mindset saying if they aren\'t an ally, they are an obstacle in your way. A berserker has high damage output, critical hit rating and speed, but lower defenses.',
                'gearWeight': ['Cloth', 'Leather', 'Mail'],
                'stats': {
                    'maxHealth': maxHealthDefault,
                    'stamina': staminaDefault * 0.90,
                    'resil': resilDefault * 0.65,
                    'armor': armorDefault * 0.65,
                    'strength': strengthDefault * 1.35,
                    'agility': agilityDefault,
                    'criticalChance': criticalChanceDefault * 1.40,
                    'spellPower': spellPowerDefault * 0.40,
                    'speed': speedDefault + 1
                }
            }
        })

test.py

from assets import playerSelf
from assets import classPath

player = playerSelf()

player.returnStats('all')

player.setPath('warrior')
print ('----\n')
player.returnStats('all')

init.py

from assets.player import playerSelf
from assets.classes import classPath

当前输出

Strength: 15
Agility: 10
Critical Chance: 25
Spell Power: 15
Health: 100/100
Stamina: 10
Resilience: 2
Armor: 20
Speed: 5
----

Strength: 15
Agility: 10
Critical Chance: 25
Spell Power: 15
Health: 100/100
Stamina: 10
Resilience: 2
Armor: 20
Speed: 5

1 个答案:

答案 0 :(得分:1)

举一个我们的意思的例子,我认为这是好的

import random
import pickle

class BaseCharacter:

    def __init__(self):
        self.gold = random.randint(25, 215) * 2.5
        self.currentHealth = 100
        self.maxHealth = 100
        self.stamina = 10
        self.resil = 2
        self.armor = 20
        self.strength = 15
        self.agility = 10
        self.criticalChance = 25
        self.spellPower = 15
        self.speed = 5
        # set gold as random gold determined from before
        self.first_name = 'New'
        self.last_name = 'Player'
        self.class_ = None

    def update(self, attrs, factors):
        # Maybe a try except would be nice here
        for attr, fac in zip(attrs, factors):
            val = getattr(self, attr)
            setattr(self, attr, val * fac)

    def show_stats(self):
        for attr in self.__dict__:  # Don't do this... but meh
            print(attr, getattr(self, attr))

    def save(self):
        with open(self.first_name+'_'+self.last_name, 'wb') as f:
            pickle.dump(self, f)

    @staticmethod
    def load(filename):
        with open(filename, 'rb') as f:
            return pickle.load(f)


class WarriorCharacter(BaseCharacter):

    def __init__(self, first_name, last_name):
        super().__init__()
        self.class_ = 'Warrior'
        self.first_name = first_name
        self.last_name = last_name
        self.update(['stamina', 'resil', 'armor'], [1.25, 1.25, 1.35])

w = WarriorCharacter('Jon', 'Snow')
w.show_stats()
w.save()
loadedW = WarriorCharacter.load('Jon_Snow')
print(loadedW.class_)