diff --git a/secert-hitler/src/controller/gamemaster/gamemaster.rs b/secert-hitler/src/controller/gamemaster/gamemaster.rs index dcc92cb..d902893 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster.rs @@ -1,4 +1,5 @@ use super::super::super::model::state::room::Room; +use super::super::super::config; use super::lobby::Lobby; use super::player::Player; use super::gameevent::GameEvent; @@ -6,11 +7,13 @@ use super::gameevent::GameEventType; use std::thread; use std::time; -use log::{info, debug, LevelFilter}; +use log::{info, debug, error, LevelFilter}; +use rand::{self, Rng}; pub struct GameMaster { room: Box, lobby: Lobby, + candidate_presidents: Vec, } impl GameMaster { @@ -19,6 +22,7 @@ impl GameMaster { GameMaster{ room: room, lobby: Lobby::new(), + candidate_presidents: vec![], } } @@ -28,32 +32,31 @@ impl GameMaster { if r.is_ok() { break } + error!("error running lobby: {:?}", r); } self.run_game_setup()?; self.run_game() } fn run_lobby(&mut self) -> Result { - let mut r = self.run_lobby_scrape(); - while r.unwrap_or(0) == 0 { - //while r.is_ok() && r.unwrap() == 0 { + loop { + let r = self.run_lobby_scrape().clone(); + if r.clone().is_err() { + return r; + } + if r.clone().unwrap_or(0) != 0 { + return r; + } thread::sleep(time::Duration::new(1, 0)); - r = self.run_lobby_scrape(); } - return Ok(r.unwrap().clone()); - /* - if r.is_ok() { - return Ok(r.unwrap()); - } - let e = r.err(); - Err(e.unwrap()) - */ } fn run_lobby_scrape(&mut self) -> Result { + debug!("run_lobby_scrape:"); let events = self.room.sync(); for e in &events { let ge = GameEvent::new(e.clone()); + debug!("run_lobby_scrape: ge: {:?}", ge); if ge.mode() == GameEventType::GameStart { self.room.rollback(e.since.clone()); self.lobby.lock(); @@ -61,7 +64,7 @@ impl GameMaster { } self.lobby.eat(e.clone()); } - Ok(0) + return self.lobby.ready(); } fn run_game_setup(&mut self) -> Result { @@ -69,9 +72,11 @@ impl GameMaster { if self.player(player.clone()).is_none() { return Err(format!("missing player {}", player)); } + self.candidate_presidents.push(player.clone()); debug!("player = {}", player); } debug!("/players"); + debug!("should shuffle candidate_presidents to set game order"); Err("not impl".to_string()) } @@ -92,12 +97,27 @@ impl GameMaster { } } +fn shuffle(v: &mut Vec) { + for _ in 0..v.len()*2 { + let a = rand_usize(v.len()); + let b = rand_usize(v.len()); + let t: T = v[a].clone(); + v[a] = v[b].clone(); + v[b] = t.clone(); + } +} + +fn rand_usize(n: usize) -> usize { + rand::thread_rng().gen_range(0, n) +} + #[cfg(test)] mod tests { use super::*; use super::super::super::super::model::state::mockroom::MockRoom; use super::super::super::super::model::state::mockrooms::MockRooms; use super::super::super::super::model::state::rooms::Rooms; + use std::collections::HashMap; fn init() { let _ = env_logger::builder() @@ -106,6 +126,34 @@ mod tests { .try_init(); } + #[test] + fn _rand_usize() { + init(); + let mut unique: HashMap = HashMap::new(); + for _ in 0..100 { + unique.insert(rand_usize(100), true); + } + assert!(unique.len() > 1); + } + + #[test] + fn _shuffle() { + init(); + let mut items: Vec = vec![]; + let n: usize = 50; + for i in 0..n { + items.push(i); + } + assert!(items.len() == n); + shuffle(&mut items); + assert!(items.len() == n); + let mut found = false; + for i in 1..items.len() { + found = found || items[i] < items[i-1]; + } + assert!(found); + } + #[test] fn new_mockroom() { let _ = GameMaster::new(Box::new(MockRoom::create())); @@ -132,15 +180,11 @@ mod tests { #[test] fn run_lobby() { init(); - println!("run_lobby 1"); let mut mrs = MockRooms::new(); let r1 = mrs.create(); - println!("run_lobby 2"); let room_id = r1.room_id(); let mut gm = GameMaster::new(r1); - println!("run_lobby 3"); - for i in 0..4 { - println!("run_lobby attempt stop #{}", i); + for i in 0..config::MIN_PLAYERS-1 { let mut r2 = mrs.join(room_id.clone()).unwrap(); r2.send(format!(r#"{{ "msgtype": "m.text", @@ -161,12 +205,19 @@ mod tests { } #[test] - fn run_game_setup_fail() { + fn run_game_setup() { init(); let mut mrs = MockRooms::new(); let r1 = mrs.create(); + let room_id = r1.room_id(); let mut gm = GameMaster::new(r1); - assert!(gm.run_game_setup().is_ok()); + let r = gm.run_game_setup(); + assert!(!r.is_ok()); + for _ in 0..config::MIN_PLAYERS-1 { + mrs.join(room_id.clone()).unwrap(); + } + let r = gm.run_game_setup(); + assert!(r.is_ok(), "failed to start game after sufficient players joined: {:?}", r); } #[test]