From b7ab700a57fb1155d4824f24fe9cc55111c977fe Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Mon, 20 Dec 2021 11:47:24 +0100 Subject: import planetwars-rules --- planetwars-rules/src/serializer.rs | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 planetwars-rules/src/serializer.rs (limited to 'planetwars-rules/src/serializer.rs') 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, + } + } +} -- cgit v1.2.3