diff options
author | Ilion Beyst <ilion.beyst@gmail.com> | 2021-12-20 11:47:24 +0100 |
---|---|---|
committer | Ilion Beyst <ilion.beyst@gmail.com> | 2021-12-20 11:47:24 +0100 |
commit | b7ab700a57fb1155d4824f24fe9cc55111c977fe (patch) | |
tree | 100db4ad472124d51ed954446be82063901b0baf /planetwars-rules/src/serializer.rs | |
parent | 931bf0fbed9670c356fdeae0f2e4559ff3e59ebb (diff) | |
download | planetwars.dev-b7ab700a57fb1155d4824f24fe9cc55111c977fe.tar.xz planetwars.dev-b7ab700a57fb1155d4824f24fe9cc55111c977fe.zip |
import planetwars-rules
Diffstat (limited to 'planetwars-rules/src/serializer.rs')
-rw-r--r-- | planetwars-rules/src/serializer.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/planetwars-rules/src/serializer.rs b/planetwars-rules/src/serializer.rs new file mode 100644 index 0000000..380433e --- /dev/null +++ b/planetwars-rules/src/serializer.rs @@ -0,0 +1,76 @@ +use super::protocol as proto; +use super::rules::{Expedition, Planet, PwState}; + +/// Serialize given gamestate +pub fn serialize(state: &PwState) -> proto::State { + serialize_rotated(state, 0) +} + +/// Serialize given gamestate with player numbers rotated by given offset. +pub fn serialize_rotated(state: &PwState, offset: usize) -> proto::State { + let serializer = Serializer::new(state, offset); + serializer.serialize_state() +} + +struct Serializer<'a> { + state: &'a PwState, + player_num_offset: usize, +} + +impl<'a> Serializer<'a> { + fn new(state: &'a PwState, offset: usize) -> Self { + Serializer { + state: state, + player_num_offset: offset, + } + } + + fn serialize_state(&self) -> proto::State { + proto::State { + planets: self + .state + .planets + .iter() + .map(|planet| self.serialize_planet(planet)) + .collect(), + expeditions: self + .state + .expeditions + .iter() + .map(|exp| self.serialize_expedition(exp)) + .collect(), + } + } + + /// Gets the player number for given player id. + /// Player numbers are 1-based (as opposed to player ids), They will also be + /// rotated based on the number offset for this serializer. + fn player_num(&self, player_id: usize) -> usize { + let num_players = self.state.players.len(); + let rotated_id = + (player_id + num_players - self.player_num_offset) % num_players; + // protocol player ids start at 1 + return rotated_id + 1; + } + + fn serialize_planet(&self, planet: &Planet) -> proto::Planet { + proto::Planet { + name: planet.name.clone(), + x: planet.x, + y: planet.y, + owner: planet.owner().map(|id| self.player_num(id)), + ship_count: planet.ship_count(), + } + } + + fn serialize_expedition(&self, exp: &Expedition) -> proto::Expedition { + proto::Expedition { + id: exp.id, + owner: self.player_num(exp.fleet.owner.unwrap()), + ship_count: exp.fleet.ship_count, + origin: self.state.planets[exp.origin as usize].name.clone(), + destination: self.state.planets[exp.target as usize].name.clone(), + turns_remaining: exp.turns_remaining, + } + } +} |