make a shuffle and rand usize8

master
bel 2020-05-05 20:22:56 -06:00
parent f27795d303
commit 97a0483807
1 changed files with 72 additions and 21 deletions

View File

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