Re: saves, seeds, and sessions



On Sat, 2005-12-31 at 14:16 -0500, Vincent Povirk wrote:
> I've been thinking about how aisleriot could accomodate game saves
> (for playing the same game again in different places and/or resuming
> across sessions), and Alan's recent comment about seeds has gotten me
> back on this subject, so here's what I think (sorry if I'm repeating
> myself, I'm not sure what parts of this I might have said earlier):
> 
> We can overcome any compatibility problems related to seeds by not
> using them at all. Instead, we would just store the initial set of
> cards (produced by shuffle-deck). Correct me if I'm wrong, but
> shuffle-deck is the only time any current game needs to randomize
> anything, and it's always called only once, in new-game (or a helper
> function called by new-game).
You are almost correct. Gay Gordons uses random to choose slots while
dealing the cards in a solvable manner - after calling shuffle-deck.
However the state *after* new-game is called is not affected by random.
(The only other use of random is in clock where it is used to select the
useless hint.)

> Of course, the list of cards would need to be validated (probably
> stored in such a way that it is easy to validate--maybe a list of
> indices used to scramble the original deck?), and in order to preserve
> compatibility, the order in which cards are dealt could never be
> changed. Options could probably be stored there too (but if it's just
> a replacement for seeds, it wouldn't be necessary).
> 
> The ability to enter seeds could be implemented as an option specific
> to Freecell, for compatibility with the windows Freecell numbers (and
> wasn't there some other program with a larger range of seeds that are
> sort of standard?).
There are at least two sets of numbers for the Microsoft games. One had
a 15-bit seed and a later version had a 20-bit (I think) seed. So it
probably isn't worth supporting. See the Wikipedia page for details. 


> Now, saving and loading undo history is where this gets crazy. That
> would really only be needed for preserving games across sessions,
> which isn't necessary at all (but would be nice--so maybe it's just
> not worth it).
I would like the program to simply pick up where it left off. Regardless
of circumstance. Persistence of State is Good (TM).

> The simplest solution would be to just write out the undo history,
> redo history, and current state as raw scheme. I'm pretty sure we have
> helper functions and built in scheme functions that would make this
> easy. The resulting files would not be safe at all (or compatible if
> the layout or anything about the game changes--we'd need a way to
> detect that), and should probably be hidden from the user.
Yes, scheme does support this. The primitive write is the one you want.
The worry about layout changes applies to *any* save-game scheme, not
just undo and redo. The moment the internal state of the saved game and
the state of the new game disagree you have a problem. Using symbolic
names in the save-game file is one way around this - it gets around
minor changes easily - and is probably the best way. In the event of a
major change we have to throw the saved game away. I think making the
saved game a scheme file will be the simplest and most flexible thing
regardless of the details.

One option may be to have aisleriot check the version against a
"last-run" version and if the major version changes throw away the saved
game regardless. This route would also need a commitment to no
significant interface changes in the scheme file between minor versions.

Another option is to just try restoring the saved game. If there is an
exception during restore, reset the game and continue. If there isn't an
exception we just assume everything is alright and continue. This is a
little dangerous of course.

> Another possibility would be to store the initial state, a list of
> user actions, and an undo count. This would, of course, be much harder
> to implement. It could be made more safe (and could be validated since
> it would have to follow a very specific format and all the moves would
> have to be valid), but would be even less compatible. It'd also be the
> most convenient form for debugging.
I actually think this would be easier to implement, it does suffer from
most of the same problems, but you could record moves as "the queen of
hearts is moved onto the king of spades" rather than "nth card on slot 3
moves to slot 4". That solves the problem of checking validity and of
slots moving around on you. I don't know what to do when multiple decks
are flying around.

I'd start with a simple solution and see how it works. You'll probably
need several iterations anyway and it is far better to add the
complexity you know you want rather than writing complexity you
eventually throw away. (I re-learnt this one the hard way recently with
the high-score code.)

 - Callum





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]