Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

python - Check and update dictionary if key exists doesn't change value

I'm trying to make a terminal-based game. So far, I have a sample class, a default player with default values, and a test file for the checking of updated values. On launch, I want the player default values to be used, but if a save is loaded or new game started, one of the first questions is to set a class, which said class should override the player values FOR THAT FILE/SESSION ONLY. However, after multiple attempts at changing the code, it either throws an error on a random key/pair or doesn't update the value. At one point, it did update the values, but it didn't update properly. Here's my code. from collections import 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: {}
Agility: {}
Critical Chance: {}
Spell Power: {}".format(self.playerStats['strength'], self.playerStats['agility'], self.playerStats['criticalChance'], self.playerStats['spellPower']))
        elif(category == "DEFENSIVE"):
            #print defensive stats
            print("Health: {}/{}
Stamina: {}
Resilience: {}
Armor: {}
Speed: {}".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: {}
Agility: {}
Critical Chance: {}
Spell Power: {}
Health: {}/{}
Stamina: {}
Resilience: {}
Armor: {}
Speed: {}".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 ('----
')
player.returnStats('all')

init.py

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

current output

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To give some example of what we mean, I think this is kind of alright

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...