EDIT: I am using python 3.2! rest of post below...
I am finishing my text based RPG in python, and I need some help. I need to make a save/load game system. I read that I can use pickle a few other methods but thats not entirely what I want. Basically, I want to be able to save my variables into a text file. If the file exists, load the variables, and skip over the introduction where it asks the player for a name. I will give the pickle method and others try and see how they work. If someone would be kind enough to show me how I would do this with .txt files, I would be very grateful! I will continue digging and post my solution once I have found it.
EDIT: I have removed the irrelevant parts of my original post. The following code is the WORKING game.py file. I no longer use a separate class module. Topic solved, now I can work on a storyline! :D
#A text based RPG
#Import required modules
import jsonpickle
import os
import sys
import time
from random import randint
#main game
#Variables
go = True
IsShopLocked = False
IsDaggerEquipped = False
IsSwordEquipped = False
IsLeatherHideEquipped = False
SAVEGAME_FILENAME = 'savegame.json'
game_state = dict()
### Classes ###
class Human(object):
#Represents the human player in the game
def __init__(self, name, health, strength, gold):
self.name = name
self.health = health
self.strength = strength
self.gold = gold
class AI(object):
#Represents the enemy player in the game
def __init__(self, name, health, strength):
self.name = name
self.health = health
self.strength = strength
class Item(object):
#represents any item in the game
def __init__(self, name, hvalue, strvalue):
self.name = name
self.hvalue = hvalue
self.strvalue = strvalue
###end classess###
###functions for loading, saving, and initializing the game###
def load_game():
"""Load game state from a predefined savegame location and return the
game state contained in that savegame.
"""
with open(SAVEGAME_FILENAME, 'r') as savegame:
state = jsonpickle.decode(savegame.read())
return state
def save_game():
"""Save the current game state to a savegame in a predefined location.
"""
global game_state
with open(SAVEGAME_FILENAME, 'w') as savegame:
savegame.write(jsonpickle.encode(game_state))
def initialize_game():
"""If no savegame exists, initialize the game state with some
default values.
"""
global game_state
player = Human('Fred', 100, 10, 1000)
enemy = AI('Imp', 50, 20)
state = dict()
state['players'] = [player]
state['npcs'] = [enemy]
return state
###End functions for loading, saving, and initalizing the game###
###Main game functions###
#Function for the shop
def Shop():
global game_state
player = game_state['players'][0]
dagger = Item('Dagger', 0, 5)
sword = Item('Sword', 0, 10)
leather_hide = Item('Leather Hide', 5, 0)
if IsShopLocked == True:
print("The shop is locked!\nPlease go back and continue your adventure!")
else:
print()
print("Welcome to the Larkville shop! What would you like to buy?\n1. Weapons\n2. armor\n3. Go back")
selection = int(input("Enter a value: "))
if selection == 1:
if player.gold >= 50:
print("Weapons shop")
print("1. Bronze Dagger: $20\n2. Bronze Sword: $50")
wpnselection = int(input("Enter a value: "))
if wpnselection == 1:
global IsDaggerEquipped
global IsSwordEquipped
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
dagger = Item('Dagger', 0, 5)
IsDaggerEquipped = True
player.strength += dagger.strvalue
player.gold -= 20
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 2:
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
sword = Item('Sword', 0, 10)
IsSwordEquipped = True
player.strength += sword.strvalue
player.gold -= 50
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 3:
Game_Loop()
elif selection == 2:
if player.gold >= 20:
print ("Armor Shop")
print ("1. Leather hide\n2. Go back")
armselection = int(input("enter a value: "))
if armselection == 1:
global IsLeatherHideEquipped
if IsLeatherHideEquipped == True:
print("You are already wearing armor!")
Game_Loop()
else:
leather_hide = Item('Leather Hide', 5, 0)
IsLeatherHideEquipped = True
player.health += leather_hide.hvalue
player.gold -= 20
print("Health increased to: {}".format(player.health))
Game_Loop()
elif armselection == 2:
Game_Loop()
elif selection == 3:
Game_Loop()
#Function for combat
def Combat():
global game_state
player = game_state['players'][0]
enemy = game_state['npcs'][0]
global go
while go == True:
dmg = randint (0, player.strength)
edmg = randint (0, enemy.strength)
enemy.health -= dmg
if player.health <= 0:
os.system('cls')
print()
print("You have been slain by the enemy {}...".format(enemy.name))
go = False
leave = input("press enter to exit")
elif enemy.health <= 0:
os.system('cls')
print()
print("You have slain the enemy {}!".format(enemy.name))
go = False
leave = input("press any key to exit")
else:
os.system('cls')
with open("test.txt", "r") as in_file:
text = in_file.read()
print(text)
player.health -= edmg
print()
print("You attack the enemy {} for {} damage!".format(enemy.name, dmg))
print("The enemy has {} health left!".format(enemy.health))
print()
print("The enemy {} attacked you for {} damage!".format(enemy.name, edmg))
print("You have {} health left!".format(player.health))
time.sleep(3)
#The main game loop
def Game_Loop():
global game_state
while True:
print()
print("You are currently in your home town of Larkville!")
print("What would you like to do?")
print("1. Shop\n2. Begin/continue your adventure\n3. View player statistics\n4. save game")
print()
try:
selection = int(input("Enter a value: "))
except ValueError:
print()
print("You can only use the numbers 1, 2, or 3.")
print()
Game_Loop()
if selection == 1:
Shop()
elif selection == 2:
Combat()
elif selection == 3:
player = game_state['players'][0]
print()
print("Your players stats:\nHealth: {}\nStrength: {}\nGold: {}".format(player.health, player.strength, player.gold))
if IsDaggerEquipped == True:
print("You have a dagger equipped")
elif IsSwordEquipped == True:
print ("You have a sword equipped")
elif IsLeatherHideEquipped == True:
print("You are wearing a leather hide")
elif selection == 4:
game_state = save_game()
else:
print()
print("Oops! Not a valid input")
print()
###End main game functions###
###The "main" function, not to be confused with anything to do with main above it###
def main():
"""Main function. Check if a savegame exists, and if so, load it. Otherwise
initialize the game state with defaults. Finally, start the game.
"""
global game_state
if not os.path.isfile(SAVEGAME_FILENAME):
game_state = initialize_game()
else:
game_state = load_game()
Game_Loop()
if __name__ == '__main__':
main()
###end main function###
You can use
jsonpickle
to serialize your object graph to JSON.jsonpickle
is not part of the standard library, so you'll have to install it first, for example by doingeasy_install jsonpickle
.You could also achieve the same using the standard library
json
module, but then you'd have to implement your ownJSONEncoder
to deal with your custom objects. Which isn't hard, but not as easy as just lettingjsonpickle
do it for you.I used simplified examples of your player classes to demonstrate how you could implement load and save functionality for the objects that constitute your game state (completely ignoring any story line):
Note the global
game_state
variable. You need something like that to keep track of all the objects that define your game state and keep them together for easy serialization / deserialization. (It doesn't necessarily have to be global, but it's definitely easier, and a game state like this is one of the few cases where it actually makes sense to use globals).Saving the game using this code will result in a
savegame.json
that looks like this: