secret-hitler/.old/secert-hitler/src/controller/gamemaster/gamemaster/gamemaster.rs

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);
}
}