From 2098bedabef9d1dd9fbf9924793bc25297f410c1 Mon Sep 17 00:00:00 2001 From: Joachim Lusiardi Date: Tue, 26 Dec 2023 11:38:23 +0100 Subject: [PATCH] make monsters more like players --- src/game.rs | 13 +----- src/level.rs | 111 +++++++++++++++++++++++++++++---------------------- src/main.rs | 10 ++--- 3 files changed, 70 insertions(+), 64 deletions(-) diff --git a/src/game.rs b/src/game.rs index 44c665f..b134a1c 100644 --- a/src/game.rs +++ b/src/game.rs @@ -80,19 +80,8 @@ impl Game { /// limitation as walls. fn can_move(&mut self, dx: i16, dy: i16) -> bool { let player_pos = &self.player.get_position(); - let new_x: i16 = player_pos.get_x() as i16 + dx; - let new_y: i16 = player_pos.get_y() as i16 + dy; let level = &mut self.levels[player_pos.get_level()]; - match level.get_element(new_x, new_y) { - (None, _, _) => { return false; } - (Some(t), _, _) => { - match t { - StructureElement::Wall => { return false; } - _ => {} - } - } - }; - true + level.can_player_move(&self.player, dx, dy) } /// returns the position (as tuple) of the next level's start point. fn next_start(&self) -> (usize, usize, usize) { diff --git a/src/level.rs b/src/level.rs index 65e83c5..7c7accc 100644 --- a/src/level.rs +++ b/src/level.rs @@ -6,7 +6,7 @@ use crate::artifacts::Artifact; #[cfg(test)] use crate::monster::{Orc, Rat}; use crate::monster::Monster; -#[cfg(test)] +use crate::player::Player; use crate::position::HasPosition; use crate::position::Position; @@ -37,24 +37,6 @@ pub struct Level { } impl Level { - #[cfg(test)] - pub fn new(level: usize) -> Level { - let mut s = [[StructureElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH]; - for x in 2..LEVEL_WIDTH - 2 { - for y in 2..LEVEL_HEIGHT - 2 { - s[x][y] = StructureElement::Floor; - } - } - Level { - level, - structure: s, - discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH], - monsters: Vec::with_capacity(10), - artifacts: Vec::with_capacity(10), - start: (0, 0), - end: (0, 0), - } - } pub fn get_element(&mut self, x: i16, y: i16) -> (Option, Option<&mut Box<(dyn Monster + 'static)>>, Option<&mut Box<(dyn Artifact + 'static)>>) { if x < 0 || y < 0 { return (None, None, None); @@ -82,33 +64,6 @@ impl Level { } (Some(self.structure[x][y]), res_m, res_a) } - #[cfg(test)] - pub fn add_monster(&mut self, mut monster: impl Monster + 'static) -> Result<(), String> { - if self.level != monster.get_position().get_level() { - return Err("Wrong Level".to_string()); - } - for m in &mut self.monsters { - if m.get_position() == monster.get_position() { - return Err("Position already used".to_string()); - } - } - self.monsters.push(Box::new(monster)); - Ok(()) - } - - #[cfg(test)] - pub fn add_artifact(&mut self, artifact: impl Artifact + 'static) -> Result<(), String> { - if self.level != artifact.get_immutable_position().get_level() { - return Err("Wrong Level".to_string()); - } - for a in &mut self.artifacts { - if a.get_immutable_position() == artifact.get_immutable_position() { - return Err("Position already used".to_string()); - } - } - self.artifacts.push(Box::new(artifact)); - Ok(()) - } /// discover the area with in the level around the given position pub fn discover(&mut self, pos: &Position) { let x = pos.get_x(); @@ -153,7 +108,6 @@ impl Level { } } } - pub fn update(&mut self) { for (index, a) in &mut self.artifacts.iter().enumerate() { if a.was_collected() { @@ -167,6 +121,69 @@ impl Level { break; } } + for index in 0..self.monsters.len() { + if self.can_monster_move(self.monsters[index].as_ref(), 0, 1) { + self.monsters[index].get_position().change(0, 1); + } else if self.can_monster_move(self.monsters[index].as_ref(), 0, -1) { + self.monsters[index].get_position().change(0, -1); + } + } + } + pub fn can_monster_move(&self, agent: &dyn Monster, dx: i16, dy: i16) -> bool { + let agent_pos = agent.get_immutable_position(); + let new_x: usize = (agent_pos.get_x() as i16 + dx) as usize; + let new_y: usize = (agent_pos.get_y() as i16 + dy) as usize; + self.structure[new_x][new_y] != StructureElement::Wall + } + pub fn can_player_move(&self, agent: &Player, dx: i16, dy: i16) -> bool { + let agent_pos = agent.get_immutable_position(); + let new_x: usize = (agent_pos.get_x() as i16 + dx) as usize; + let new_y: usize = (agent_pos.get_y() as i16 + dy) as usize; + self.structure[new_x][new_y] != StructureElement::Wall + } + #[cfg(test)] + pub fn new(level: usize) -> Level { + let mut s = [[StructureElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH]; + for x in 2..LEVEL_WIDTH - 2 { + for y in 2..LEVEL_HEIGHT - 2 { + s[x][y] = StructureElement::Floor; + } + } + Level { + level, + structure: s, + discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH], + monsters: Vec::with_capacity(10), + artifacts: Vec::with_capacity(10), + start: (0, 0), + end: (0, 0), + } + } + #[cfg(test)] + pub fn add_monster(&mut self, mut monster: impl Monster + 'static) -> Result<(), String> { + if self.level != monster.get_position().get_level() { + return Err("Wrong Level".to_string()); + } + for m in &mut self.monsters { + if m.get_position() == monster.get_position() { + return Err("Position already used".to_string()); + } + } + self.monsters.push(Box::new(monster)); + Ok(()) + } + #[cfg(test)] + pub fn add_artifact(&mut self, artifact: impl Artifact + 'static) -> Result<(), String> { + if self.level != artifact.get_immutable_position().get_level() { + return Err("Wrong Level".to_string()); + } + for a in &mut self.artifacts { + if a.get_immutable_position() == artifact.get_immutable_position() { + return Err("Position already used".to_string()); + } + } + self.artifacts.push(Box::new(artifact)); + Ok(()) } } diff --git a/src/main.rs b/src/main.rs index ac8313f..8e74c54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,7 +96,7 @@ fn main() -> Result<()> { stats_area, ); })?; - if event::poll(std::time::Duration::from_millis(16))? { + if event::poll(std::time::Duration::from_millis(100))? { if let event::Event::Key(key) = event::read()? { if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { break; @@ -114,13 +114,13 @@ fn main() -> Result<()> { game.move_player(new_pos.0, new_pos.1); } game.player_collects_artifact(); - game.update_level(); - if game.get_game_state() != GameState::RUNNING { - break; - } } } } + game.update_level(); + if game.get_game_state() != GameState::RUNNING { + break; + } } loop { let _ = terminal.draw(|frame| {