use crate::state::{GameState, Event}; /** * This is the main game struct. * It takes care of stepping the game forward. * Changes are made to the state struct through the step function. */ pub struct Game { pub state: GameState, } impl Game { pub fn new(state: GameState) -> Game { Game { state: state, } } pub fn step(&mut self) { // get list of all people ids let ids: Vec = self.state.creatures.keys().map(|id| *id).collect(); // step each person for id in ids { let person = self.state.creatures.get(&id); if let Some(p) = person { let mut p = p.clone(); let actions = p.step(&self.state.world); for action in actions { action.apply(&mut self.state); if action.notable() { self.state.events.push(Box::new(Event{ time: self.state.time, effect: action })) } } self.state.creatures.insert(p.entity.id, p); } } // increment time self.state.time.time += 1; } } #[cfg(test)] mod tests { use std::rc::Rc; use crate::{world::{World, Terrain, Town}, person::{Creature, Agenda}, time::Time, entity::Location}; use super::*; #[test] fn test_step() { let state = GameState::new(World::new(100)); let mut game = Game::new(state); game.step(); assert_eq!(game.state.time.time, 1); } #[test] fn test_step_creature() { let mut state = GameState::new(World::new(2)); state.world.map[0][0].terrain = Terrain::Flats; state.world.map[0][1].terrain = Terrain::Flats; state.world.map[1][0].terrain = Terrain::Hills; state.world.map[1][1].terrain = Terrain::Hills; let mut creature = Creature::new( Time { time: 0 }, Rc::new(Town::new()), Location { x: 0, y: 0 } ); creature.set_agenda(Agenda::Traveling(Location { x: 2, y: 2 })); state.add_person(creature); let mut game = Game::new(state); game.step(); assert_eq!(game.state.creatures.len(), 1); assert_eq!(game.state.creatures[&1].entity.loc, Location { x: 1, y: 1 }); } }