diff --git a/secert-hitler/src/controller/gamemaster/gameevent.rs b/secert-hitler/src/controller/gamemaster/gameevent.rs index ee4313d..41ed748 100644 --- a/secert-hitler/src/controller/gamemaster/gameevent.rs +++ b/secert-hitler/src/controller/gamemaster/gameevent.rs @@ -137,7 +137,6 @@ impl GameEvent { targets: self.targets(), params: self.params(), }), - sender: "__gm__", msgtype: "m.text".to_string(), }).dump() } @@ -256,31 +255,31 @@ mod tests { d: json::object!{}, sender: "a".to_string(), }; - assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"Null\",\"sources\":[],\"targets\":[],\"params\":[]}","sender":"__gm__","msgtype":"m.text"}"#, "{}", ge.serialize()); + assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"Null\",\"sources\":[],\"targets\":[],\"params\":[]}","msgtype":"m.text"}"#, "{}", ge.serialize()); let ge = GameEvent{ d: json::object!{GameEventType: "GameStart"}, sender: "a".to_string(), }; - assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[],\"targets\":[],\"params\":[]}","sender":"__gm__","msgtype":"m.text"}"#, "{}", ge.serialize()); + assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[],\"targets\":[],\"params\":[]}","msgtype":"m.text"}"#, "{}", ge.serialize()); let ge = GameEvent{ d: json::object!{GameEventType: "GameStart", params: ["hi"]}, sender: "a".to_string(), }; - assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[],\"targets\":[],\"params\":[\"hi\"]}","sender":"__gm__","msgtype":"m.text"}"#, "{}", ge.serialize()); + assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[],\"targets\":[],\"params\":[\"hi\"]}","msgtype":"m.text"}"#, "{}", ge.serialize()); let ge = GameEvent{ d: json::object!{GameEventType: "GameStart", sources: ["hi"], targets: ["hi2"]}, sender: "a".to_string(), }; - assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[\"hi\"],\"targets\":[\"hi2\"],\"params\":[]}","sender":"__gm__","msgtype":"m.text"}"#, "{}", ge.serialize()); + assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"GameStart\",\"sources\":[\"hi\"],\"targets\":[\"hi2\"],\"params\":[]}","msgtype":"m.text"}"#, "{}", ge.serialize()); let ge = GameEvent{ d: json::object!{GameEventType: "Null", sources: ["hi"], targets: ["hi2"]}, sender: "a".to_string(), }; - assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"Null\",\"sources\":[\"hi\"],\"targets\":[\"hi2\"],\"params\":[]}","sender":"__gm__","msgtype":"m.text"}"#, "{}", ge.serialize()); + assert!(ge.serialize() == r#"{"body":"{\"GameEventType\":\"Null\",\"sources\":[\"hi\"],\"targets\":[\"hi2\"],\"params\":[]}","msgtype":"m.text"}"#, "{}", ge.serialize()); debug!("sample gameevent serialize: {}", ge.serialize()); } } diff --git a/secert-hitler/src/controller/gamemaster/gamemaster/game.rs b/secert-hitler/src/controller/gamemaster/gamemaster/game.rs index 17b258c..2d119d7 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster/game.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster/game.rs @@ -4,11 +4,46 @@ use super::super::gameevent::GameEventType; use super::super::policy::Policy; use super::super::role::Role; -use log::debug; +use log::{debug, error}; use json; use std::collections::HashMap; impl GameMaster { + pub fn run_game(&mut self) -> Result { + loop { + let ge = self.game_is_over()?; + self.room.send(ge.serialize()); + let ge = self.game_election()?; + self.room.send(ge.serialize()); + let ge = self.game_is_over()?; + self.room.send(ge.serialize()); + let p = match self.game_election_vote().unwrap_or(GameEventType::GameStop.build()).mode() { + GameEventType::VoteFailed => self.game_policy_select_random(), + GameEventType::GameStop => self.game_is_over(), + _ => self.game_policy_select(), + }?; + self.room.send(p.serialize()); + if p.mode() != GameEventType::PolicySet { + error!("unexpected game event type after election vote followup: {:?}", p); + return Err(Role::Null); + } + let params = p.params(); + let param = params.first(); + if param.is_none() { + error!("unexpected missing param on {:?}: {:?}", p, param); + return Err(Role::Null); + } + let param = param.unwrap(); + let policy = Policy::from_string(param.to_string()); + let ge = self.game_policy_veto(policy.clone())?; + self.room.send(ge.serialize()); + let ge = self.game_ends_with(policy.clone())?; + self.room.send(ge.serialize()); + let ge = self.game_policy_enact(policy.clone())?; + self.room.send(ge.serialize()); + } + } + pub fn game_is_over(&mut self) -> Result { if self.policies[&Policy::Facist] >= 3 { let chancellor = self.chancellor.clone(); @@ -34,9 +69,7 @@ impl GameMaster { self.president = Some(president_candidate.clone()); ge.d["targets"] = json::array![president_candidate.clone()]; ge.d["params"] = json::array!["president"]; - if self.room.send(ge.serialize()).is_err() { - return Err(Role::Null); - } + self.room.send(ge.serialize()).unwrap(); let events = self.scrape_until_gameeventtype(GameEventType::ElectionSet); if events.is_err() { return Err(Role::Null); @@ -95,20 +128,30 @@ impl GameMaster { } self.room.send(ge.serialize()); - if gm_vote { - return Ok(GameEventType::Null.build()); // todo how to emit continue? - } else { + if ! gm_vote { self.president = None; self.chancellor = None; return Ok(GameEventType::VoteFailed.build()); } + + if self.game_is_over().is_err() { + return Ok(GameEventType::GameStop.build()); + } + Ok(GameEventType::Null.build()) } pub fn game_policy_select_random(&mut self) -> Result { - Err(Role::Null) + let policy = self.deck.pop().unwrap().clone(); + let mut ge = GameEventType::PolicySet.build(); + ge.d["params"] = json::array![format!("{:?}", policy)]; + self.room.send(ge.serialize()).unwrap(); } pub fn game_policy_select(&mut self) -> Result { + let draw = vec![]; + for _ in 0..3 { + draw.push(self.deck.pop().unwrap().clone()); + } Err(Role::Null) } @@ -342,4 +385,12 @@ mod tests { assert!(ge.params()[1] == "true"); assert!(ge.params()[2] == "true"); } + + #[test] + fn game_policy_select() { + } + + #[test] + fn game_policy_select_random() { + } } diff --git a/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs b/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs index 3935c62..242280d 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs @@ -18,6 +18,7 @@ pub struct GameMaster { pub lobby: Lobby, pub candidate_presidents: Vec, pub deck: Vec, + pub discard: Vec, pub policies: HashMap, pub president: Option, pub chancellor: Option, @@ -31,6 +32,7 @@ impl GameMaster { lobby: Lobby::new(), candidate_presidents: vec![], deck: vec![], + discard: vec![], policies: HashMap::new(), president: None, chancellor: None, @@ -49,41 +51,6 @@ impl GameMaster { self.run_game() } - pub fn run_game(&mut self) -> Result { - loop { - let ge = self.game_is_over()?; - self.room.send(ge.serialize()); - let ge = self.game_election()?; - self.room.send(ge.serialize()); - let ge = self.game_is_over()?; - self.room.send(ge.serialize()); - let p = match self.game_election_vote().unwrap_or(GameEventType::GameStop.build()).mode() { - GameEventType::VoteFailed => self.game_policy_select_random(), - GameEventType::GameStop => self.game_is_over(), - _ => self.game_policy_select(), - }?; - self.room.send(p.serialize()); - if p.mode() != GameEventType::PolicySet { - error!("unexpected game event type after election vote followup: {:?}", p); - return Err(Role::Null); - } - let params = p.params(); - let param = params.first(); - if param.is_none() { - error!("unexpected missing param on {:?}: {:?}", p, param); - return Err(Role::Null); - } - let param = param.unwrap(); - let policy = Policy::from_string(param.to_string()); - let ge = self.game_policy_veto(policy.clone())?; - self.room.send(ge.serialize()); - let ge = self.game_ends_with(policy.clone())?; - self.room.send(ge.serialize()); - let ge = self.game_policy_enact(policy.clone())?; - self.room.send(ge.serialize()); - } - } - pub fn players(&self) -> Vec { let mut players = vec![]; for k in self.lobby.players.keys() { diff --git a/secert-hitler/src/model/state/mockroom.rs b/secert-hitler/src/model/state/mockroom.rs index 9bd02b4..1946f9a 100644 --- a/secert-hitler/src/model/state/mockroom.rs +++ b/secert-hitler/src/model/state/mockroom.rs @@ -75,7 +75,7 @@ impl Room for MockRoom { } fn send(&mut self, message: String) -> Result { - self.send_as(rands(), message) + self.send_as(self.sender.clone(), message) } fn room_id(&self) -> String {