How to make a save/load game for a text based pyth

2020-06-28 15:43发布

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###

标签: python load save
1条回答
再贱就再见
2楼-- · 2020-06-28 16:20

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 doing easy_install jsonpickle.

You could also achieve the same using the standard library json module, but then you'd have to implement your own JSONEncoder to deal with your custom objects. Which isn't hard, but not as easy as just letting jsonpickle 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):

import jsonpickle
import os
import sys


SAVEGAME_FILENAME = 'savegame.json'

game_state = dict()


class Human(object):
    """The human player
    """
    def __init__(self, name, health, gold):
        self.name = name
        self.health = health
        self.gold = gold


class Monster(object):
    """A hostile NPC.
    """
    def __init__(self, name, health):
        self.name = name
        self.health = health


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.
    """
    player = Human('Fred', 100, 10)
    imp = Monster('Imp', 50)

    state = dict()
    state['players'] = [player]
    state['npcs'] = [imp]
    return state


def attack():
    """Toy function to demonstrate attacking an NPC.
    """
    global game_state
    imp = game_state['npcs'][0]
    imp.health -= 3
    print "You attacked the imp for 3 dmg. The imp is now at %s HP." % imp.health


def spend_money(amount):
    """Toy function to demonstrate spending money.
    """
    global game_state
    player = game_state['players'][0]
    player.gold -= amount
    print "You just spent %s gold. You now have %s gold." % (amount, player.gold)


def game_loop():
    """Main game loop.
    This loop will run until the player exits the game.
    """
    global game_state

    while True:
        print "What do you want to do?"
        choice = int(raw_input("[1] Save game [2] Spend money "
                               "[3] Attack that Imp! [4] Load game "
                               "[5] Exit game\n"))
        if choice == 1:
            save_game()
        elif choice == 2:
            spend_money(5)
        elif choice == 3:
            attack()
        elif choice == 4:
            game_state = load_game()
        else:
            print "Goodbye!"
            sys.exit(0)


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

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:

{
    "npcs": [
        {
            "health": 41,
            "name": "Imp",
            "py/object": "__main__.Monster"
        }
    ],
    "players": [
        {
            "gold": 5,
            "health": 100,
            "name": "Fred",
            "py/object": "__main__.Human"
        }
    ]
}
查看更多
登录 后发表回答