make a shuffle and rand usize8
parent
c1160d9d7e
commit
d6e18aa592
|
|
@ -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]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue