I'm looking for an efficient way to save my game coded in python. I've looked at pickle, but I'm not sure it will suit my needs as there is a lot of info that needs to be saved.
The way I understand pickle is it will take whatever I give it and dump it into a file, which sounds great. But not only do I have the player character to save, theres the rooms that the character has already been, the state of the rooms, if the user opened up treasure chests, etc. And if I understand pickle correctly, I would have to input each room manually for that to work.
Is there a better way to do this? Would I be better off creating a database of some kind? Or am I just not using pickle correctly?
Perhaps I'm missing something, but why not put all of the data you mention into a dictionary. It may even be a multi-level dictionary. Something like:
{
"player_info":{"name":"Bart", ..},
"current_state_of_game":{"cur_location":"library", "prior_room":"kitchen", ..}
}
Then pickle that?
Related
I have been looking everywhere for information on pickle, and I thought I had had figured it out, but I am having a bit of a problem getting it to work properly.
So I use python 3.3.1. I have a pygame game with many rooms (around 200), each room is its own child instance of a parent class, many with their own variables to keep track of all sorts of things that happen in their room. As the player goes from room to room, I of course want the changes the player does to each room to be saved when the player saves a game. I have sort of a double question.
So here is more or less what I do:
import pickle
with gzip.GzipFile("Saved Games/"+file_name, 'wb') as output:
pickle.dump(room001, output, pickle.HIGHEST_PROTOCOL)
...
pickle.dump(room200, output, pickle.HIGHEST_PROTOCOL)
pickle.dump(player, output, pickle.HIGHEST_PROTOCOL)
So I guess that saves. But when I load it later, using:
with gzip.GzipFile("Saved Games/"+file_name, 'r') as loadfile:
room001 = pickle.load(loadfile)
...
room200 = pickle.load(loadfile)
player = pickle.load(loadfile)
at first everything seems okay. It seems to load with no problems, but then I notice the game is acting a little strangely. it is as if it is not using the data it loaded from the pickle.
For example, one room might have some bees flying about. I enter the room and see the bees as normal, but when the event function for the room tries to make the bees move about, they don't.
It would look something like this:
def room001_events():
room001.bee_pos_x += room001.bee_speed
if room001.bee_pos_x < 0 or room001.bee_pos_x > 600:
room001.bee_speed *= -1
Prior to the load the bees would happily bounce back and forth, but after it, they wouldnt move at all. So I am wondering what I am doing wrong with the load process. the function is being accessed and when I print out the values, they seem to be changing, but the bees on the screen don't move.
Also, I am wondering if there is some way to iterate over all the rooms in the program without having to list them individually. I have tried using shelve as per this question, but it just crashes on load (it mostly seems to have problems with surfaces from what I can tell because it keeps giving me pygame.error: display Surface quit even though I never called pygame.quit() at all).
Your problem isn't pickle. Your problem is the assumption that restoring the state of a room from a pickle is sufficient to have it operate normally when you load the pickle. I'd be willing to bet you have no tests to validate that assumption.
When you save (pickle) an instance, the values of its instance variables are saved as part of the pickle. When you reload them their __init__() methods will not normally be called, which is presumably how actions are started. So are you sure that there's enough state information in the pickle for things to just resume where they left off?
The easiest way to save all the rooms without having to list them individually is to have a list containing the rooms. Then your code would refer to (say) rooms[100] rather than room100, and you can just pickle the rooms[] list to save them all with a single statement.
I am working heavily with a database, using python, and I am trying to write code that actually makes my life easier.
Most of the time, I need to run a query and get results to process them; most of the time I get the same fields from the same table, so my idea was to collect the various results in an object, to process it later.
I am using SQLAlchemy for the DB interaction. From what I can read, there is no direct way to just say "dump the result of this query to an object", so I can access the various fields like
print object.fieldA
print object.fieldB
and so on. I tried dumping the results to JSON, but even that require parsing and it is not as straightforward as I hoped.
So at this point is there anything else that I can actually try? Or should I write a custom object that mimic the db structure, and parse the result with for loops, to put the data in the right place? I was hoping to find a way to do this automatically, but so far it seems that the only way to get something close to what I am looking for, is to use JSON.
EDIT:
Found some info about serialization and the capabilities that SQLAlchemy has, to read a table and reproduce a sort of 1:1 copy of it in an object, but I am not sure that this will actually work with a query.
Found that the best way is to actually use a custom object.
You can use reflection trough SQLAlchemy to extrapolate the structure, but if you are dealing with a small database with few tables, you can simply create on your own the object that will host the data. This gives you control over the object and what you can put in it.
There are obvious other ways, but since nobody posted anything; I assume that either are too easy to be mentioned, or too hard and specific to each case.
I have been looking into YAML and the Python parsing options with PyYAML. I kind of understand how it works but still have a question regarding the process:
Is it possible to directly update an item inside the YAML file without parsing the whole file, creating a dictionary for everything, operating on that dictionary and then dumping it back?
HOUSE:
- white
APPLE:
- red
BANANA:
- yellow
Let say that I want to make the APPLE "green", is that possible by only operating on the APPLE object, and not working on the whole dictionary?
Thanks.
Ok. I think Roman is right. I was asking this cause I was worried about the overhead of complex YAML objects. But, I guess, If things are becoming complex, then one should switch to a db solution, like MongoDB or a like. Once YAML is kept simple, the serialisation and de-serialisation overhead should bot be a huge issues.
I've got a Python program with about a dozen classes, with several classes possessing instances of other classes, e.g. ObjectA has a list of ObjectB's, and a dictionary of (ObjectC, ObjectD) pairs.
My goal is to put the program's functionality on a website.
I've written and tested JSON encode and decode methods for each class. The problem as I see it now is that I need to choose between starting over and writing the models and logic afresh from a database perspective, or simply storing the python objects (encoded as JSON) in the database, and pulling out the saved states for changes.
Can someone confirm that these are both valid approaches, and that I'm not missing any other simple options?
Man, what I think you can do is convert the classes you already have made into django model classes. Of course, only the ones that need to be saved to a database. The other classes, as the rest of the code, I recommend you to encapsulate them for use as helper functions. So you don't have to change too much your code and it's going to work fine. ;D
Or, another choice, that can be easier to implement is: put everything in a helper, the classes, the functions and everything else.
SO you'll just need to call the functions in your views and define models to save your data into the database.
Your idea of saving the objects as JSON on the database works, but it's ugly. ;)
Anyway, if you are in a hurry to deliver the website, anything is valid. Just remember that things made in this way always give us lots of problems in the future.
It hopes that it could be useful! :D
I want to make a simple game on python, all text based. Sort of an interactive story with puzzles etc. but it is likely to be long. I want to be able to it possible for poeple to sort of, 'Save Progress'. Perhaps assign them selves a name etc? I am new to Python and am wondering if it is possible to set up a bank containing details of game play that can be accessed by entering a username and so will load the correct area of the code to allow the player to pick up where they left of.
Say they decided to quit the game just after... say, finding a clue to a murder. The computer would store the line of code they were on and get them to enter their name. Next time they could select 'Load' from the start up menu and then enter their name. The computer would then search for their name and pull up the peice of code they were at and continue as normal from there.
I am new at this so please try and explain simply. I can make a menu etc. no problems with the if's etc and make the story it's self. It is just the loading I want to add.
I hope this isn't tooooo complicated!? Please help me!
You should check out the pickle module. It allows you to store/retrieve any python object. One way to do this would be to have your game take place in a class, where all of the states/etc were members of that class (or derived classes). When they wanted to save you would just pickle your class!
You are pretty new to python, I would recommend reading the documentation provided here: http://docs.python.org/tutorial/ .
Python tries to be both easy to learn and comprehensive. Most questions answer themselves!
Depends on how you create your game...
Do you follow the tree of decisions that the user took in the game? If so you save the decisions in a file, that you save to a location (for example "saves/{username}/{name_of_save}.sav or just "saves/{username.sav} if every username should have only one save, but this is just a example it all depends on you). You could then allow them to select their save file and then simulate the actions from the file till you reach the point where the last decision took place.
If you would like to easily save the data to the file(s) you could also use a format like JSON, which python has built-in support for - read more at http://docs.python.org/library/json.html . This will allow you to easily create objects that you want to save/read from the file and use for processing.
Hope that helps...
Just a Idea, I have not actually tried anything like this
Take a look at http://www.sqlite.org/ or use plain text files for the beginning:) you could use the username:bitfield to encode you progress. Or use the ConfigParser module for Python and create a scetion for each user:) have fun learning:)