1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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,
}
}
}
|