b-inary / postflop-solver

[Development suspended] An efficient open-source postflop solver library written in Rust
GNU Affero General Public License v3.0
246 stars 97 forks source link

Best way to serialize PostFlopGame? #4

Closed ryanto closed 2 years ago

ryanto commented 2 years ago

Hi!

This is a very cool library! I've been messing around with it for the last week and it's so cool to run a bunch of solves on my machine :)

I'd like to save a PostFlopGame so I can load it again later and use the functions that let me traverse the tree with different actions, turns, and rivers. I tried using serde to do so, but got stuck with reading/writing the private fields.

I'm new to rust so any advice you have would be helpful.

Thanks again for this awesome library!

b-inary commented 2 years ago

Thanks for your comments!

I do understand that having the capability to save calculated results is very useful, but once we implement this feature, we will have to keep aware of the compatibility issue. Currently, the internal structure of PostFlopGame and PostFlopNode structs is not yet stabilized (for example, I just changed the internal structure of PostFlopGame yesterday for optimization).

Probably the best way to serialize PostFlopGame is to implement Encode and Decode traits of the bincode crate. Just deriving Encode or Decode won't work since PostFlopGame and PostFlopNode structs contain raw pointers, so we need to implement them manually.

If you don't mind the compatibility issue (i.e., compatibility will be lost when the internal structure is changed), it is possible to implement Encode and Decode traits from now. What do you think?

ryanto commented 2 years ago

Ah good point about the changing shape of the structs!

I don't mind the compatibility issue, I'm guessing most of my saves will be short lived so I can always re-run if things change. By the way, I'd love to help with this, but I don't know how to implement the encoding of raw pointers.

Also, I don't want to create extra work for you. I'm more than happy iterating over the players, actions, and strategies and saving those. That should give me enough to re-create the results of the game tree. If you'd rather I do that I'm more than happy to.

Thanks again!

b-inary commented 2 years ago

I experimentally implemented Encode and Decode traits of bincode.

Now you can save and load the PostFlopGame struct like the following:

let config = bincode::config::legacy();

// save let mut game = ...; let mut write_buf = BufWriter::new(File::create("filename.bin").unwrap()); bincode::encode_into_std_write(&game, &mut write_buf, config).unwrap(); write_buf.flush().unwrap();

// load let mut read_buf = BufReader::new(File::open("filename.bin").unwrap()); let mut game: PostFlopGame = bincode::decode_from_std_read(&mut read_buf, config).unwrap();



Serialized data contains version information. I will upgrade the version when the internal structure is changed, in which case compatibility will be lost (I won't provide an implementation for data migration).

If you find any bugs or other problems, please feel free to report them!
ryanto commented 2 years ago

Awesome! It worked perfectly 👍