154 lines
4.6 KiB
Rust
154 lines
4.6 KiB
Rust
use super::super::super::super::model::state::room::Room;
|
|
use super::super::super::super::model::state::event::Event;
|
|
use super::super::lobby::Lobby;
|
|
use super::super::player::Player;
|
|
use super::super::policy::Policy;
|
|
use super::super::role::Role;
|
|
use super::super::gameevent::GameEventType;
|
|
use super::super::gameevent::GameEvent;
|
|
|
|
use log::{info, debug, error};
|
|
use std::collections::HashMap;
|
|
use std::thread;
|
|
use std::time;
|
|
|
|
#[derive(Debug)]
|
|
pub struct GameMaster {
|
|
pub room: Box<dyn Room>,
|
|
pub lobby: Lobby,
|
|
pub candidate_presidents: Vec<String>,
|
|
pub deck: Vec<Policy>,
|
|
pub discard: Vec<Policy>,
|
|
pub policies: HashMap<Policy, usize>,
|
|
pub president: Option<String>,
|
|
pub chancellor: Option<String>,
|
|
pub failed_votes: usize,
|
|
}
|
|
|
|
impl GameMaster {
|
|
pub fn new(room: Box<dyn Room>) -> GameMaster {
|
|
info!("created for room {}", room.room_id());
|
|
GameMaster{
|
|
room: room,
|
|
lobby: Lobby::new(),
|
|
candidate_presidents: vec![],
|
|
deck: vec![],
|
|
discard: vec![],
|
|
policies: HashMap::new(),
|
|
president: None,
|
|
chancellor: None,
|
|
failed_votes: 0,
|
|
}
|
|
}
|
|
|
|
pub fn run(&mut self) -> Result<GameEvent, Role> {
|
|
loop {
|
|
let r = self.run_lobby();
|
|
if r.is_ok() {
|
|
break
|
|
}
|
|
error!("error running lobby: {:?}", r);
|
|
}
|
|
self.run_game_setup()?;
|
|
self.run_game()
|
|
}
|
|
|
|
pub fn players(&self) -> Vec<String> {
|
|
let mut players = vec![];
|
|
for k in self.lobby.players.keys() {
|
|
players.push(k.clone());
|
|
}
|
|
players
|
|
}
|
|
|
|
pub fn player(&mut self, id: String) -> Option<&mut Player> {
|
|
self.lobby.players.get_mut(&id)
|
|
}
|
|
|
|
pub fn scrape_until_gameeventtype(&mut self, get: GameEventType) -> Result<Vec<Event>, String> {
|
|
let mut scraped = vec![];
|
|
loop {
|
|
let events = self.room.sync();
|
|
for e in &events {
|
|
scraped.push(e.clone());
|
|
let ge = GameEvent::new(e.clone());
|
|
debug!("scrape_until {:?}: {:?}: ge: {:?}", get, ge.mode() == get, ge);
|
|
if ge.mode() == get {
|
|
debug!("/scrape_until {:?}: {:?}: ge: {:?}", get, ge.mode() == get, ge);
|
|
self.room.rollback(e.since.clone());
|
|
return Ok(scraped);
|
|
}
|
|
}
|
|
thread::sleep(time::Duration::new(1, 0));
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use super::super::super::super::super::model::state::mockroom::MockRoom;
|
|
use super::super::super::super::super::model::state::mockrooms::MockRooms;
|
|
use super::super::super::super::super::model::state::rooms::Rooms;
|
|
|
|
#[test]
|
|
fn new_mockroom() {
|
|
let _ = GameMaster::new(Box::new(MockRoom::create("__gm__".to_string())));
|
|
}
|
|
|
|
#[test]
|
|
fn new_rooms_mockrooms() {
|
|
fn get() -> impl Rooms {
|
|
let mrs = MockRooms::new();
|
|
mrs
|
|
}
|
|
let mut mrs = get();
|
|
let r = mrs.create("__gm__".to_string());
|
|
let _ = GameMaster::new(r);
|
|
}
|
|
|
|
#[test]
|
|
fn new_mockrooms() {
|
|
let mut mrs = MockRooms::new();
|
|
let r = mrs.create("__gm__".to_string());
|
|
let _ = GameMaster::new(r);
|
|
}
|
|
|
|
#[test]
|
|
fn scrape_until_get() {
|
|
let mut mrs = MockRooms::new();
|
|
let r = mrs.create("__gm__".to_string());
|
|
let room_id = r.room_id().clone();
|
|
let r2 = mrs.join("r2".to_string(), room_id);
|
|
assert!(r2.is_ok());
|
|
let mut r2 = r2.unwrap();
|
|
let mut gm = GameMaster::new(r);
|
|
gm.room.sync();
|
|
r2.send(GameEventType::Null.build().serialize()).unwrap();
|
|
let scraped = gm.scrape_until_gameeventtype(GameEventType::Null);
|
|
assert!(scraped.is_ok());
|
|
let scraped = scraped.unwrap();
|
|
assert!(scraped.len() == 1);
|
|
assert!(scraped.first().is_some());
|
|
let e = scraped.first().unwrap();
|
|
assert!(GameEvent::new(e.clone()).mode() == GameEventType::Null, "{:?}", e);
|
|
assert!(gm.room.sync().len() == 0);
|
|
|
|
r2.send(GameEventType::ElectionSet.build().serialize()).unwrap();
|
|
r2.send(GameEventType::ElectionSet.build().serialize()).unwrap();
|
|
let scraped = gm.scrape_until_gameeventtype(GameEventType::ElectionSet);
|
|
assert!(scraped.is_ok());
|
|
let scraped = scraped.unwrap();
|
|
assert!(scraped.len() == 1);
|
|
assert!(gm.room.sync().len() == 1);
|
|
|
|
r2.send(GameEventType::SpecialPeek.build().serialize()).unwrap();
|
|
r2.send(GameEventType::ElectionPend.build().serialize()).unwrap();
|
|
let scraped = gm.scrape_until_gameeventtype(GameEventType::ElectionPend);
|
|
assert!(scraped.is_ok());
|
|
let scraped = scraped.unwrap();
|
|
assert!(scraped.len() == 2);
|
|
assert!(gm.room.sync().len() == 0);
|
|
}
|
|
}
|