Python Forum
Coding RPG Game - Need Fresh Eyes.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Coding RPG Game - Need Fresh Eyes.
#1
This is a project I have been working on for a couple of months. The project has drastically improved my understanding of Python3 and I have been pretty good about attacking most if not all of the problems so far by myself. However, once the project files start to get a little bigger (this being my largest project thus far) it gets much easier to miss simple mistakes. I think this needs a fresh pair of eyes. Don't worry too much about tweaking it into a more efficient version, I'll get there. I don't mind any critiques picking out obvious no-no's or offering any advice or suggestions unrelated to the main error issue..

With that out of the way, here is the problem I am experiencing that I need looked over. I will post the 2 main files first and then the rest of the project for others to observe and learn from as well. I noticed there aren't as many advanced RPG code examples provided online so I want to put together this project as a open-source text-based PyMUD. One obvious mistake is unnecessary imports but maybe I did right.

Error:
Traceback (most recent call last): File "D:\Documents\Game Programming\Python Project Files\Self-Py Projects\SmallGame\play.py", line 8, in <module> Interface.main_menu() File "D:\Documents\Game Programming\Python Project Files\Self-Py Projects\SmallGame\uimenu.py", line 26, in main_menu player.location['Name'], AttributeError: 'NoneType' object has no attribute 'location'
play.py
from uimenu import *
from account import *
import output

if __name__ == '__main__':
    Account.create(Account)
    Player.create()
    Interface.main_menu()
uimenu.py
from output import *
from player import *
import maps

class Interface:

    def main_menu():
        actions = ['gm', 'revive']
        alphas = False
        asci = False
        commands = ['target', 'heal', 'n', 'north', 's', 'south', 'e', 'east', 'w', 'west']
        esc = ['quit',
               'exit',
               'q',
               'esc']
        numeric = False
        reset = ['cls',
                 'main',
                 'menu',
                 'reset',
                 'restart']
        run = [True, False]
        spaces = False
        Output.iFrame(Output,
                      '#',
                      player.location['Name'],
                      '_',
                      player.location['Description'],
                      player.location['Content'])
        print('\nActions:',actions,'\nCommands:',commands,'\nMenu:',reset,'\nQuit:',esc)

        while run[0] is True:

            uin = input(f'\n{player.tag}{player.name}[{player.level}] | Health: {player.health}/{player.mhp} | Experience: {player.exp}/{player.exp2lvl}\n\n>>> ').lower()

            try:
                
                if '.' in uin[:1]:

                    if uin[1:] not in actions:

                        for char in uin[1:]:

                            if char.isspace():
                                spaces = True

                            elif char.isalpha():
                                alphas = True

                            elif char.isdigit():
                                numeric = True

                            elif char.isascii():
                                asci = True

                        if spaces is True:
                            print('\n|Notice|- The (.)command must not contain any spaces! Please try again.')
                            spaces = False
                            continue

                        elif alphas is True and spaces is False and numeric is False and asci is False:
                            print('\n|Notice|- The (.)command was entered incorrectly or does not exist! Please try again.')
                            alphas = False
                            continue

                        elif asci is True and len(uin) > 1:
                            print('\n|Notice|- Except for (.) Special characters are not valid or accepted in (.)commands! Please try again.')
                            asci = False
                            spaces = False
                            alphas = False
                            numeric = False
                            continue
                        
                        elif numeric is True:
                            print('\n|Notice|- The (.)command must not contain any numerical digits! Please try again.')
                            numeric = False
                            continue

                        elif uin[1:] == '' or alphas is False and numeric is False and asci is False and spaces is False:
                            print('\n|Notice|- No command was entered after the (.)! Please try again.')
                            continue

                    else:
                        try:
                            #Handles all (.)Actions
                            if uin[1:] == actions[0]:
                                #GM-ON
                                if player.tag == '':
                                    player.tag = '[GM]-'
                                    print('\n|Notice|- You have upgraded your rank to Game Master.')
                                    
                                else:
                                    if player.tag == '[GM]-':
                                        player.tag = ''
                                        print('\n|Notice|- You have disabled your rank of Game Master.')
                                        
                            elif uin[1:] == actions[1]: 

                                if player.tag == '':
                                    print('\n|Notice|- You must be a Game Master in order to use the revive command!')
                                    if player.health - 100 >= 1:
                                        player.health -= 100

                                    else:
                                        player.health -= player.health
                                        player.death()
                                        

                                elif player.tag == '[GM]-':
                                    if player.health < 1:
                                        print(f'\n|Notice|- You have been revived by Game Master {player.name}!')
                                        player.health = 0
                                        player.health += player.mhp
                                    else:
                                        print('\n|Notice|- You can not be revived if you are alive!')
                                
                        finally:
                            #print('\n|Notice|- You have successfully executed a .command!\n')
                            pass
                elif uin == '':
                    print('\n|Notice|- There was no command entered! Please try again.')
                    continue

                elif ' ' in uin:
                    print('\n|Notice|- The command must not contain any spaces! Please try again.')
                    continue
                    
                
                elif uin not in esc and uin not in reset:

                    if uin not in commands:

                        for char in uin:

                            if char.isspace():
                                spaces = True

                            elif char.isalpha():
                                alphas = True

                            elif char.isdigit():
                                numeric = True

                            elif char.isascii():
                                asci = True

                        if alphas is True and spaces is False and numeric is False and asci is False:
                            print('\n|Notice|- The command was entered incorrectly or does not exist! Please try again.')
                            alphas = False
                            continue

                        elif numeric is True:
                            print('\n|Notice|- The command must not contain any numerical digits! Please try again.')
                            numeric = False
                            continue

                        elif asci is True:
                            print('\n|Notice|- The command contains special characters that are not valid or accepted! Please try again.')
                            asci = False
                            numeric = False
                            alphas = False
                            spaces = False
                            continue

                    else:
                        
                        if player.health == 0:
                            print('\n|Notice|- You must first revive before you can enter a command! Only Action Commands work right now.')

                        else:
                            
                            try:
                            
                                #Handles all Commands
                                if uin == commands[0]:
                                    player.get_target()

                                elif uin == commands[1]:
                                    player.heal()

                                elif uin == commands[2] or uin == commands[3]:
                                    if player.location['North'] == '':
                                        print('\n|Notice|- You can no longer travel further North. Please pick one of the paths described in your current map\'s description.')

                                    else:
                                        print(f'\n{player.name} travels North!')
                                        player.location = maps.Map.zonemap[player.location['North']]

                                elif uin == commands[4] or uin == commands[5]:
                                    if player.location['South'] == '':
                                        print('\n|Notice|- You can no longer travel further South. Please pick one of the paths described in your current map\'s description.')

                                    else:
                                        print(f'\n{player.name} travels South!')
                                        player.location = maps.Map.zonemap[player.location['South']]

                                elif uin == commands[6] or uin == commands[7]:
                                    if player.location['East'] == '':
                                        print('\n|Notice|- You can no longer travel further East. Please pick one of the paths described in your current map\'s description.')

                                    else:
                                        print(f'\n{player.name} travels East!')
                                        player.location = maps.Map.zonemap[player.location['East']]

                                elif uin == commands[8] or uin == commands[9]:
                                    if player.location['West'] == '':
                                        print('\n|Notice|- You can no longer travel further West. Please pick one of the paths described in your current map\'s description.')

                                    else:
                                        print(f'\n{player.name} travels West!')
                                        player.location = maps.Map.zonemap[player.location['West']]

                            finally:
                                Interface.main_menu()
                                break

                else:

                    if uin in esc:
                        print('\n|Notice|- Terminating Program Sequence. Good-bye!')
                        run.reverse()
                        Interface.UI_quit()
                        break

                    elif uin in reset:
                        print('\n|Notice|- Restarting Program Sequence. See you soon!')
                        run.reverse()
                        Interface.main_menu()
                        break
            #except:
                #print('|Notice|- An error has prevented a section of this code from being executed.\n')
            finally:
                pass

    def UI_quit():
        gap = ' '*20
        print(' _____  _                    _\n'+
              '|_   _|| |                  | |\n'+
              '  | |  | |__    __ _  _ __  | | __ ___\n'+
              '  | |  | \'_ \  / _` || \'_ \ | |/ // __|\n'+
              '  | |  | | | || (_| || | | ||   < \__ \\\n'+
              '  \_/  |_| |_| \__,_||_| |_||_|\_\|___/\n'+gap+
              ' _____\n'+gap+
              '|  ___|\n'+gap+
              '| |_  ___   _ __\n'+gap+
              '|  _|/ _ \ | \'__|\n'+gap+
              '| | | (_) || |\n'+gap+
              '\_|  \___/ |_|\n'+
              ' _____  _                _\n'+
              '| ___ \| |              (_)\n'+
              '| |_/ /| |  __ _  _   _  _  _ __    __ _\n'+
              '|  __/ | | / _` || | | || || \'_ \  / _` |\n'+
              '| |    | || (_| || |_| || || | | || (_| |\n'+
              '\_|    |_| \__,_| \__, ||_||_| |_| \__, |\n'+
              '                   __/ |            __/ |\n'+
              '                  |___/            |___/\n')
player.py
import random, time, os, maps, uimenu
from enemy import *
from output import *
player = None

class Player:
    max_level = 20
    exp_mod = 1
    
    def __init__(self,
                 name,
                 mhp,
                 health,
                 level,
                 exp,
                 exp2lvl,
                 target,
                 tag,
                 location):
        
        self.name = name
        self.health = health
        self.mhp = health
        self.level = level
        self.exp = exp
        self.exp2lvl = exp2lvl
        self.target = target
        self.tag = tag
        self.location = location
        
    def __str__(self):
        
        if self.health < 0:
            self.health = 0
        return(f'\n[Player Details]\nCharacter: {self.tag}{self.name}\nLevel: {self.level}\nHealth: {self.health}/{self.mhp}\nExperience: {self.exp}/{self.exp2lvl}')

    def create():
        Output.iFrame(Output, '#', 'PyRona RPG v1.10', '_', 'Character Creation Menu', 'We will now create your in-game PyRona RPG character.', 50)
        name = input('\nCreate Character: ')
        health = random.randrange(500, 1500, 5)
        mhp = health
        level = 1
        exp = 0
        exp2lvl = 500 * level * (1+level)
        target = [None]
        tag = ''
        location = maps.Map.zonemap['a1']
        player = Player(name, mhp, health, level, exp, exp2lvl, target, tag, location)
        print('\n[Character Details]')
        time.sleep(random.uniform(0.25, 0.75))
        print(f'Name: {player.name}')
        time.sleep(random.uniform(0.25, 0.75))
        print('Location:',player.location['Name'])
        time.sleep(random.uniform(0.25, 0.75))
        print(f'Level: {player.level}')
        time.sleep(random.uniform(0.25, 0.75))
        print(f'Health: {player.health}/{player.mhp}')
        time.sleep(random.uniform(0.25, 0.75))
        print(f'Experience: {player.exp}/{player.exp2lvl}')
        time.sleep(random.uniform(0.25, 0.75))
        while True:
            input('\n|Notice|- Press the enter key to continue.')
            break

    def levelup(self):
        
        self.target = [None]
        if self.exp >= self.exp2lvl:
            self.health = self.mhp
            self.level += 1
            self.exp2lvl = 500 * self.level * (1+self.level)
            self.health += (random.randrange(25, 125, 25)) * self.level
            self.mhp = self.health
            print(f'Congratulations {self.name}! You have just advanced to level {self.level}!')
            if self.level < Player.max_level:
                if self.exp >= self.exp2lvl:
                    self.levelup()
                else:
                    print(self)
            else:
                print('|Notice|- You may no longer gain experience from battles. You have reached the maximum level!')
                self.exp = self.exp2lvl

    def get_target(self):
        try:
            if self.health == 0:
                print('\n|Notice|- You are dead and may not obtain a target!')
                self.death()
            else:
                if None in self.target:
                    self.target.clear()
                    #Continue building map spawns by checking if index [0]-[3] in list A, B, C, or D are equal by comparison to the players self.location['Name']
                    
                    vmaps = ['A1', 'A2', 'A3', 'A4', 'B1', 'B2', 'B3', 'B4', 'C1', 'C2', 'C3', 'C4', 'D1', 'D2', 'D3', 'D4']
                    
                    
                    if 'A' in self.location['Name']:
                        #65, 30, 5, 0
                        map_spawn = random.choices(creatures, [65, 30, 5, 0])
                        enemy = random.choice(map_spawn)
                        self.target = enemy()

                    elif 'B' in self.location['Name']:
                        #25, 42, 32, 1
                        map_spawn = random.choices(creatures, [25, 42, 32, 1])
                        enemy = random.choice(map_spawn)
                        self.target = enemy()
                        
                    elif 'C' in self.location['Name']:
                        #5, 60, 30, 5
                        map_spawn = random.choices(creatures, [5, 60, 30, 5])
                        enemy = random.choice(map_spawn)
                        self.target = enemy()

                    elif 'D' in self.location['Name']:
                        #0, 25, 45, 30
                        map_spawn = random.choices(creatures, [0, 25, 45, 30])
                        enemy = random.choice(map_spawn)
                        self.target = enemy()
                        
                    print(self.target)
                    self.attack()

        except:
            print(f'\n|Notice|- You are already attacking a {self.target.name}\n')
            
    def attack(self):
        attacker = ['Enemy', 'Player']
            
        while self.health > 0 and self.target.health > 0:

            if attacker[0] == 'Player':

                if self.tag == '[GM]-':
                    self.dmg = round(random.randrange(50, 150, 1)*self.target.level/20*self.level)

                else:
                    self.dmg = round(random.randrange(1, 5, 1)*self.target.level/2)
                    
                print(f'\nPlayer attacks target for {self.dmg} points of damage!')
                self.target.health -= self.dmg
                attacker.reverse()
                print(self.target)
                time.sleep(1)

            elif attacker[0] == 'Enemy':
                a = int(self.target.dmg[:2])
                b = int(self.target.dmg[5:7])
                self.target.damage = random.randrange(a, b, 1)
                print(f'{self.target.name} attacks player for {self.target.damage} points of damage!')
                self.health -= self.target.damage
                attacker.reverse()
                print(self)
                time.sleep(1)

        else:

            if self.health <= 0:
                print(f'{self.name} was just slain by a {self.target.name}... Better luck next time!')
                self.death()

            elif self.target.health <= 0:
                if self.tag == '[GM]-':
                    Player.exp_mod = random.randrange(5, 20, 1)
                    exp_gain = (random.randrange(10, 35, 1) * self.target.level)*Player.exp_mod/2
                else:
                    Player.exp_mod = 1
                    exp_gain = (random.randrange(10, 35, 1) * self.target.level)/2+50
                if self.level < Player.max_level:
                    print(f'You have just slain a level {self.target.level} \'{self.target.name}\'.\nThis creature\'s type was: {self.target.ctype}\nYou have gained {exp_gain} experience!\nXP Modifier: {Player.exp_mod}')
                    self.exp += exp_gain
                    if self.exp >= self.exp2lvl:
                            self.levelup()
                self.target = [None]

    def print_inventory(self):
        pass

    def heal(self):

        if self.health < 1:
            print('\n|Notice|- You must first be revived by a Game Master before you can heal!')
        else:
            if self.health >= self.mhp:
                self.health = self.mhp
                print('\n|Notice|- You are already at max health and can no longer receive heals!')
            else:
                heals = random.randrange(75, 250, 1)
                if self.health + heals <= self.mhp:

                    if heals > 175:
                        print(f'\nYou have been healed with a major healing touch for {heals} health points!')
                    else:
                        print(f'\nYou have been healed with a healing touch for {heals} health points!')

                    self.health += heals
                else:
                    print(f'\nYou have been healed to max health from a healing touch spell.')
                    self.health = self.mhp


    def death(self):
        self.target = [None]
        if self.health < 1:
            #self.health = 0
            print('You are dead... Now you must figure out a way to revive!')

        else:
            return('\n[Death]: You are not dead. Who do you think you are? Get outta here!')
enemy.py
import random, time

class Enemy:

    def __init__(self, name, ctype, level, health, dmg):
        self.name = name
        self.ctype = ctype
        self.level = level
        self.health = health
        self.max_health = health
        self.dmg = dmg

    def __str__(self):
        if self.health < 0:
            self.health = 0
        return(f'\n[Enemy Details]\nName: {self.name}\nType: {self.ctype}\nLevel: {self.level}\nHealth: {self.health}/{self.max_health}\nDamage: {self.dmg}\n')

    def display(self):
        print(self.__str__())

class Zombie(Enemy):
    def __init__(self):
        super().__init__(name='Zombie', ctype='Undead', level=5, health=75, dmg = '05 - 15')

class Ghost(Enemy):

    def __init__(self):
        super().__init__(name='Ghost', ctype='Apparition', level=10, health=150, dmg = '15 - 30')

class Wolf(Enemy):
    def __init__(self):
        super().__init__(name='Wolf', ctype='Creature', level=15, health=300, dmg = '30 - 60')

class Troll(Enemy):

    def __init__(self):
        super().__init__(name='Troll', ctype='Humanoid', level=20, health=500, dmg = '60 - 99')

creatures = [Zombie, Ghost, Wolf, Troll]
items.py
from output import *

class Item():
    'The base class for all items'

    def __init__(self, name, description, value):
        self.name = name
        self.description = description
        self.value = value

    def __str__(self):
        return ('Name: {}\nDescription: {}\nValue: {}\n'.format(self.name, self.description, self.value))


class Weapon(Item):
    'This is a subclass of Item: A class for all Weapons'

    def __init__(self, name, description, value, damage):
        self.damage = damage
        super().__init__(name, description, value)

    def __str__(self):
        return("Name: {}\nDescription: {}\nValue: {}\nDamage: {}\n".format(self.name, self.description, self.value, self.damage))

class Rock(Weapon):
    'class for Weapon: Rock'
    def __init__(self):
        super().__init__(name = 'Rock',
                                  description = 'A fist-sized rock, suitable for bludgeoning.',
                                  value = 0,
                                  damage = 2.5)

class Dagger(Weapon):
    def __init__(self):
        super().__init__(name = "Dagger",
                                  description = "A dull dagger with some rust. It's better than nothing..",
                                  value = 20,
                                  damage = 4.0)

class Gold(Item):
    'This is the \'GoldCoin\' class'
    def __init__(self, amt):
        self.amt = amt
        super().__init__(name = 'Gold',
                                  description = 'A loot of \'Gold Coins\'. This is certainly a valuable stash.',
                                  value = amt)
output.py
import random, sys, textwrap, time

class Output:
    
    def iFrame(self,
               border='#',
               header='',
               lbreak='_',
               desc='',
               content=(''),
               width=50):

        iFrame = {
            'Border': f'{border}'*50,
            'Header': f'{border}'+header.center(48)+f'{border}',
            'Content': content.center(50),
            'Desc': f'{border}'+desc.center(48)+f'{border}',
            'Break': f'{border}'+lbreak*48+f'{border}'
        }
        print('\r')
        print(iFrame['Border']),
        print(iFrame['Header']),
        print(iFrame['Break']),
        print(iFrame['Desc']),
        print(iFrame['Border']+'\n'),
        Output.content(Output, content, width)

    def content(self, content, width):
        '''Formatting content with textwrap.'''
        wrapper = textwrap.TextWrapper(width)
        default_content = wrapper.wrap(text = content)
        for element in default_content:
            print(element)
            
    def text_delay(text, delay):
        for characters in text:
            sys.stdout.write(characters)
            sys.stdout.flush()
            time.sleep(delay)
account.py
from output import *
import errno, json, os, random, time
cache = None
account = None

class Account:

    i = 0
    data = {'ID': None,
            'Username': None,
            'Password': None,
            'Date': None}
    
    def __init__(self,
                 uid,
                 username,
                 password,
                 date):

        self.uid = uid
        self.username = username
        self.password = password
        self.date = date

    def __str__(self):
        return('\n##################################################\n#                PyRona RPG v1.10                #\n#________________________________________________#\n#               Account Login Menu               #\n##################################################')

    def create(self):
        global cache
        global account
        Output.iFrame(Output, '#', 'PyRona RPG v1.10', '_', 'Account Creation Menu', 'Creating a new account is easy. Enter the following information into the prompt to register your account.')
        account = Account(Account.i+1, input('\nCreate Username: '), input('Create Password: '), time.ctime()[11:24])
        cache = [account.uid,
                 account.username,
                 account.password]
        print('\nImporting Account {} to Databse @ {}'.format(account.username, time.ctime()[11:24]))        
        Account.data.update({'ID': account.uid,
                             'Username': account.username,
                             'Password': '*'*len(account.password),
                             'Date': time.ctime()[11:24]})
        self.write_file()
        print('Table Updated Successfully @ {}'.format(time.ctime()[11:24]))
        print(account)
        account.login(input('\nUsername: '),
                      input('Password: '))
            

    def login(self, username, password):
        global cache
        print('\n--[Logging Into Account: {}'.format(self.username))
        time.sleep(2)
        if username == cache[1] and password == cache[2]:
            print(f'Welcome, {self.username}. You have successfully logged in!')

        else:
            print('\nInvalid Login, please try again!\n')
            self.login(input('Username: '),
                       input('Password: '))

    def write_file():
        filename = f'\Documents\Game Programming\Python Project Files\Self-Py Projects\SmallGame\Data\{account.username}.txt'
        if not os.path.exists(os.path.dirname(filename)):
            try:
                os.makedirs(os.path.dirname(filename))
            except OSError as exc:
                raise
        with open(filename, 'w') as file:
            file.write('\r'+json.dumps(Account.data))
maps.py
#MAP REFERENCE
'''
*Starting on B2
____________
|A1|A2|A3|A4|
|B1|B2|B3|B4|
|C1|C2|C3|C4|
|D1|D2|D3|D4|
-------------
'''
class Map:

    zonename = 'Name'
    description = 'Description'
    content = 'Content'
    solved = False
    north = 'North'
    south = 'South'
    west = 'West'
    east = 'East'

    solved_places = {'a1': False, 'a2': False, 'a3': False, 'a4': False,
                     'b1': False, 'b2': False, 'b3': False, 'b4': False,
                     'c1': False, 'c2': False, 'c3': False, 'c4': False,
                     'd1': False, 'd2': False, 'd3': False, 'd4': False
                    }

    zonemap = {

        'a1': {
            
            zonename: 'A1',
            description: 'Here is the description of A1',
            content: 'MAP A1: You can travel in the directions South or East!',
            solved: False,
            north: '',
            south: 'b1',
            west: '',
            east: 'a2'
        },

        'a2': {
            zonename: 'A2',
            description:'Here is the description of A2',
            content: 'MAP A2: You can travel in the directions South, East, or West!',
            solved: False,
            north: '',
            south: 'b2',
            west: 'a1',
            east: 'a3'
            },

        'a3': {
            zonename: 'A3',
            description: 'Here is the description of A3',
            content: 'MAP A3: You can travel in the directions South, East, or West!',
            solved: False,
            north: '',
            south: 'b3',
            west: 'a2',
            east: 'a4'
        },

        'a4': {
            zonename: 'A4',
            description: 'Here is the description of A4',
            content: 'Map A4: You can travel in the directions South or West!',
            solved: False,
            north: '',
            south: 'b4',
            west: 'a3',
            east: ''
        },

        'b1': {
            zonename: 'B1',
            description: 'Here is the description of B1',
            content: 'Map B1: You can travel in the directions North, South, or East!',
            solved: False,
            north: 'a1',
            south: 'c1',
            west: '',
            east: 'b2'
        },

        'b2': {
            zonename: 'B2',
            description: 'Here is the description of B2',
            content: 'Map B2: You can travel in the directions North, South, East, and West!',
            solved: False,
            north: 'a2',
            south: 'c2',
            west: 'b1',
            east: 'b3'
        },

        'b3': {
            zonename: 'B3',
            description: 'Here is the description of B3',
            content: 'Map B3: You can travel in the directions North, South, East, and West!',
            solved: False,
            north: 'a3',
            south: 'c3',
            west: 'b2',
            east: 'b4'
        },

        'b4': {
            zonename: 'B4',
            description: 'Here is the description of B4',
            content: 'Map B4: You can travel in the directions North, South, or West!',
            solved: False,
            north: 'a4',
            south: 'c4',
            west: 'b3',
            east: ''
        },

        'c1': {
            zonename: 'C1',
            description: 'Here is the description of C1',
            content: 'Map C1: You can travel in the directions North, South, or East!',
            solved: False,
            north: 'b1',
            south: 'd1',
            west: '',
            east: 'c2'
        },

        'c2': {
            zonename: 'C2',
            description: 'Here is the description of C2',
            content: 'Map C2: You can travel in the directions North, South, East, or West!',
            solved: False,
            north: 'b2',
            south: 'd2',
            west: 'c1',
            east: 'c3'
        },

        'c3': {
            zonename: 'C3',
            description: 'Here is the description of C3',
            content: 'Map C3: You can travel in the directions North, South, East, and West!',
            solved: False,
            north: 'b3',
            south: 'd3',
            west: 'c2',
            east: 'c4'
        },

        'c4': {
            zonename: 'C4',
            description: 'Here is the description of C4',
            content: 'Map C4: You can travel in the directions North, South, or West!',
            solved: False,
            north: 'b4',
            south: 'd4',
            west: 'c3',
            east: ''
        },

        'd1': {
            zonename: 'D1',
            description: 'Here is the description of D1',
            content: 'Map D1: You can travel in the directions North or East!',
            solved: False,
            north: 'c1',
            south: '',
            west: '',
            east: 'd2'
        },

        'd2': {
            zonename: 'D2',
            description: 'Here is the description of D2',
            content: 'Map D2: You can travel in the directions North, East, or West!',
            solved: False,
            north: 'c2',
            south: '',
            west: 'd1',
            east: 'd3'
        },

        'd3': {
            zonename: 'D3',
            description: 'Here is the description of D3',
            content: 'Map D3: You can travel in the directions North, East, or West!',
            solved: False,
            north: 'c3',
            south: '',
            west: 'd2',
            east: 'd4'
        },

        'd4': {
            zonename: 'D4',
            description: 'Here is the description of D4',
            content: 'Map D4: You can travel in the directions North, East, or West!',
            solved: False,
            north: 'c4',
            south: '',
            west: 'c3',
            east: ''
        }
    }
Reply
#2
The assignment
player = Player(name, mhp, health, level, exp, exp2lvl, target, tag, location)
happens inside of the method Player.Create () and therefor is not the same "player" variable that is being referenced in Interface.main_menu ().
You can use a global variable or have Player.Create () return a reference to the created instance of the class Player.
Reply
#3
Not just not the same player, but not the same variable.

Global variables are bad. Global variables defined in other modules are worse. Global variables from other modules that are imported using a wildcard get you your own special level of hell.
buran likes this post
Reply
#4
As mentioned by others, the issue here is relying on global variables. Your Player.create() creates a local player object, that isn't assigned to the global player variable. I have a feeling you'll have a similar issue with the Account.

The pattern you're using (kind of) is called the Singleton. You have a Player class, but you don't really expect to create more than one instance of that class. You can read more about this in The Book: https://gameprogrammingpatterns.com/singleton.html

As a side note, that entire book is very well written. The code examples are all c++, but all the code is (for the most part) very simple and designed to illustrate the point, and can be understood even if you don't know c++.

Normally, these sorts of classes are Builders, that have a GetInstance method. For your player, here's how I'd do it:
>>> class Player:
...     __players = []
...     def __init__(self, name):
...         self.name = name
...         Player.__players.append(self)
...     @classmethod
...     def get(cls, player_id=0):
...         if len(cls.__players) > player_id:
...             return cls.__players[player_id]
...         raise Exception(f"Player {player_id} does not exist.")
...
>>> me = Player('george')
>>> me
<__main__.Player object at 0x0000026450096CD0>
>>> me.name
'george'
>>> # elsewhere in our codebase...
>>> player = Player.get()
>>> player.name
'george'
This way, the class itself controls the instance, and you just ask it for that instance.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to begin coding for game making [Install pygame on mac] mattkrebs 2 4,950 Apr-02-2017, 10:57 AM
Last Post: machrider

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020