aboutsummaryrefslogtreecommitdiff
path: root/planetwars-rules/src/serializer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'planetwars-rules/src/serializer.rs')
-rw-r--r--planetwars-rules/src/serializer.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/planetwars-rules/src/serializer.rs b/planetwars-rules/src/serializer.rs
new file mode 100644
index 0000000..7eb2e01
--- /dev/null
+++ b/planetwars-rules/src/serializer.rs
@@ -0,0 +1,75 @@
+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,
+ }
+ }
+}