0

I'm making a text based game to better learn python. I made some classes, and I want to code a save state for the game. I could write/read every attribute of each class to a file individually, but obviously that's a hassle. I've used pickle, but I have the save/load in different functions, so pickle works in the function, but when it kicks back to the main, the class reverts back to before the load. So 2 questions: 1. Is there a way to prevent the class from reverting using pickle? Or 2: Is there a way to simplify file.write(class)?

Here's the code I've been testing with. I've simplified the main so it could be easy to change the attributes and check to see if the load worked properly.

class game:
    def __init__(self, position, coins):
        self.position = position
        self.coins = coins

player = game("start", 10)

#save w/ pickle - works
def save():
    save = input("Enter name: ")
    with open(save + ".txt", "wb") as file:
        pickle.dump(player, file)

#save w/o pickle - works, would require a LOT of code
def save():
    save = input("Enter name: ")
    with open(save + ".txt", "w") as file:
        file.write(player.position)
        #file.write(<other attributes>)

#load w/ pickle - player class doesn't transfer out of function
def load():
    try:
        load = input("Enter name: ")
        with open(load + ".txt", "rb") as file:
            player = pickle.load(file)
            print(player.position)
            print(player.coins)
    except FileNotFoundError:
        print("File doesn't exist.")

#load w/o pickle - works, would require a LOT of code
def load():
    try:
        load = input("Enter name: ")
        with open(load + ".txt", "rb") as file:
            player.position = file.read()
            #will need to modified to read each line separately
            print(player.position)
            print(player.coins)
    except FileNotFoundError:
        print("File doesn't exist.")

a = ""
while a.lower() != "exit":
    a = input("Enter input: ")
    if a.lower() == "save":
        save()
    elif a.lower() == "load":
        load()
    elif a.lower() == "p":
        player.position = "pond"
        print(player.position)
    elif a.lower() == "b":
        player.position = "bridge"
        print(player.position)
    elif a.lower() == "s":
        player.position = "start"
        print(player.position)
    elif a.lower() == "print":
        print(player.position)
        print(player.coins)
    elif a.lower() == "-":
        player.coins -= 1
        print(player.coins)

Thanks in advance.

Dave N
  • 1
  • 1
  • 4
  • There is a lot that you need to understand here to write code properly and simply answering the question as is won't fix it. I marked a duplicate that I *hope* will be most useful for you, but it's better if you re-read the language tutorial, or whatever source you're learning from, and make sure you understand how local and global variable scopes work. – Karl Knechtel Jun 07 '20 at 20:44
  • I've been trying to stay away from global variables because I heard they're bad to use. But I'll still read up on them. – Dave N Jun 07 '20 at 20:51
  • 1
    Don't use variables from an outer scope if you don't need to. Your `save` function should get the player with a parameter: `def save(player):`. Your `load` function should return the new `player` instance with `return player`, so that you can call it with `player = load()`. – Matthias Jun 07 '20 at 20:57
  • 1
    BTW, the naming in your code is confusing. Why is `player` an instance of `game`? A _player_ and a _game_ are different things. According to the naming conventions in the [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/#naming-conventions) the class name should start with an uppercase letter. After you fixed that your variable should be called `game` or the class should be called `Player`. – Matthias Jun 07 '20 at 21:02
  • I tried ```return player``` before the (asking the) question, but the same thing. I forgot about passing parameters into functions, so I could give that a try. – Dave N Jun 07 '20 at 21:26
  • As far as the naming convention, I haven't read any books or anything. I've just been learning through tutorials on youtube and various forums. I'll keep that in mind for future reference. Thanks. – Dave N Jun 07 '20 at 21:27
  • I mean, yes, you indeed should not use a global for this task (which `player` currently is). But you also should understand how the scopes work, in addition to understanding how function calls work. – Karl Knechtel Jun 07 '20 at 23:29
  • I found a way without global (using ```player = load()```). Thank you for the help and redirecting me. – Dave N Jun 08 '20 at 00:26

0 Answers0