From 6030ba0b73023f303540d054dffa4ab97d016cf9 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Fri, 24 May 2024 16:35:25 +0200 Subject: [PATCH] Tests - added basic tests for cell, direction, entity, action - fixed bugs --- rogue_lib/src/cell.rs | 15 +- rogue_lib/src/entities.rs | 7 + rogue_lib/tests/tests.rs | 281 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 rogue_lib/tests/tests.rs diff --git a/rogue_lib/src/cell.rs b/rogue_lib/src/cell.rs index 9265676..d8e5e26 100644 --- a/rogue_lib/src/cell.rs +++ b/rogue_lib/src/cell.rs @@ -147,6 +147,11 @@ pub struct TurnBasedDamage { time: u8, damage: i32, } +impl TurnBasedDamage { + pub fn new(time: u8, damage: i32) -> Self { + Self { time, damage } + } +} #[typetag::serde] impl Effect for TurnBasedDamage { fn is_persistent(&self) -> bool { @@ -155,10 +160,12 @@ impl Effect for TurnBasedDamage { fn apply_to(&self, entity: &mut Entity, _floor: &mut Floor) { if self.time > 0 { entity.apply_damage(self.damage); - entity.add_effect(Box::new(Self { - time: self.time - 1, - damage: self.damage, - })); + if self.time > 1 { + entity.add_effect(Box::new(Self { + time: self.time - 1, + damage: self.damage, + })); + } } } } diff --git a/rogue_lib/src/entities.rs b/rogue_lib/src/entities.rs index 8dfbbb9..9ad9a13 100644 --- a/rogue_lib/src/entities.rs +++ b/rogue_lib/src/entities.rs @@ -127,6 +127,13 @@ impl Entity { self.effects.push_back(effect); } + /// Permette di vedere tutti gli effetti che in questo momento sono applicati all'entità.\ + /// Gli effetti qui elencati sono in uno stato di attesa prima di essere effettivamente + /// applicati tremite la funzione update. + pub fn get_effects(& self) -> impl Iterator> { + self.effects.iter() + } + /// Indica se l'entità è considerata ancora in gioco o meno.\ /// Per far si che l'entità non sia più in gioco bisobna far arrivare la vita a 0. /// Nota: una entità con vita negativa è considerata "viva" diff --git a/rogue_lib/tests/tests.rs b/rogue_lib/tests/tests.rs new file mode 100644 index 0000000..ec203fe --- /dev/null +++ b/rogue_lib/tests/tests.rs @@ -0,0 +1,281 @@ +use rand::SeedableRng; +use rand_pcg::Pcg32; +use rogue_lib::{ + cell::{Cell, Effect, InstantDamage, TurnBasedDamage}, + entities::{Action, Direction, Entity, Immovable, Position}, + floor::Floor, +}; + +/*******************************************************/ +/* Funzioni semplici per inizializzazione di strutture */ +/*******************************************************/ +fn get_basic_entity() -> Entity { + Entity::new("name".to_string(), 100, 10, Box::new(Immovable)) +} + +fn get_basic_floor() -> Floor { + let rng = Pcg32::seed_from_u64(0); + let grid = vec![vec![Cell::Empty; 20]; 20]; + Floor::new(0, rng, vec![], grid) +} + +/*******************************************************/ +/* I tests iniziano da qui in poi */ +/*******************************************************/ + +#[test] +fn test_cell_basic() { + let mut entity = get_basic_entity(); + + // random ones + entity.direction = Direction::Up; + entity.position = Position(10, 10); + + Cell::Empty.entity_over(&mut entity); + assert_eq!(entity.position, Position(10, 10)); + assert_eq!(entity.direction, Direction::Up); + + Cell::Entance.entity_over(&mut entity); + assert_eq!(entity.position, Position(10, 10)); + assert_eq!(entity.direction, Direction::Up); + + Cell::Exit.entity_over(&mut entity); + assert_eq!(entity.position, Position(10, 10)); + assert_eq!(entity.direction, Direction::Up); + + Cell::Wall.entity_over(&mut entity); + assert_eq!(entity.position, Position(10, 9)); + assert_eq!(entity.direction, Direction::Down); + + assert_eq!(Cell::Empty.as_char(), ' '); + assert_eq!(Cell::Entance.as_char(), ' '); + assert_eq!(Cell::Exit.as_char(), '¤'); + assert_eq!(Cell::Wall.as_char(), '█'); +} + +#[test] +fn test_cell_trait_effect_instant_damage() { + let cell = InstantDamage(10); + let mut floor = get_basic_floor(); + let mut entity = get_basic_entity(); + + let health = entity.get_health(); + cell.apply_to(&mut entity, &mut floor); + assert_eq!(entity.get_health(), health - 10); + + let cell = InstantDamage(-10); + cell.apply_to(&mut entity, &mut floor); + assert_eq!(entity.get_health(), health); +} + +#[test] +fn test_directions() { + let mut dir = Direction::Up; + + dir.invert(); + assert_eq!(dir, Direction::Down); + dir.invert(); + assert_eq!(dir, Direction::Up); + + dir = Direction::Left; + + dir.invert(); + assert_eq!(dir, Direction::Right); + dir.invert(); + assert_eq!(dir, Direction::Left); + + dir = Direction::None; + assert_eq!(dir, Direction::None); + + let mut pos = Position(10, 10); + assert_eq!(Direction::Up.move_from(&mut pos), &Position(10, 11)); + assert_eq!(Direction::Down.move_from(&mut pos), &Position(10, 10)); + assert_eq!(Direction::Left.move_from(&mut pos), &Position(9, 10)); + assert_eq!(Direction::Right.move_from(&mut pos), &Position(10, 10)); + assert_eq!(Direction::None.move_from(&mut pos), &Position(10, 10)); + + assert_eq!(Direction::Up.as_char(), '▲'); + assert_eq!(Direction::Down.as_char(), '▼'); + assert_eq!(Direction::Left.as_char(), '◄'); + assert_eq!(Direction::Right.as_char(), '►'); + assert_eq!(Direction::None.as_char(), '■'); +} + +#[test] +fn test_entity_basic() { + let entity = get_basic_entity(); + assert!(entity.is_alive()); + assert!(matches!(entity.buffer, Action::DoNothing)); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 100); + assert_eq!(entity.get_name(), &"name".to_string()); + assert_eq!(entity.direction, Direction::None); +} + +#[test] +fn test_entity_basic_damage() { + let mut entity = get_basic_entity(); + + entity.apply_damage(10); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 90); + assert!(entity.is_alive()); + + entity.apply_damage(-10); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 100); + assert!(entity.is_alive()); + + entity.apply_damage(90); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 10); + assert!(entity.is_alive()); + + entity.apply_damage(-100); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 100); + assert!(entity.is_alive()); + + entity.apply_damage(120); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 0); + assert!(!entity.is_alive()); + + entity.apply_damage(10); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 0); + assert!(!entity.is_alive()); + + entity.apply_damage(-500); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 100); + assert!(entity.is_alive()); +} + +#[test] +fn test_entity_basic_effects() { + let mut floor = get_basic_floor(); + let mut entity = get_basic_entity(); + assert!(matches!(entity.get_effects().next(), None)); + + entity.add_effect(Box::new(InstantDamage(10))); + let mut iter = entity.get_effects(); + assert!(matches!(iter.next(), Some(_))); + assert!(matches!(iter.next(), None)); + std::mem::drop(iter); + + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 90); + assert!(matches!(entity.get_effects().next(), None)); + + entity.add_effect(Box::new(InstantDamage(10))); + entity.add_effect(Box::new(TurnBasedDamage::new(2, 10))); + + let mut iter = entity.get_effects(); + assert!(matches!(iter.next(), Some(_))); + assert!(matches!(iter.next(), Some(_))); + assert!(matches!(iter.next(), None)); + std::mem::drop(iter); + + let entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 70); + let mut iter = entity.get_effects(); + assert!(matches!(iter.next(), Some(_))); + assert!(matches!(iter.next(), None)); + std::mem::drop(iter); + + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.get_health_max(), 100); + assert_eq!(entity.get_health(), 60); + assert!(matches!(entity.get_effects().next(), None)); + + entity.add_effect(Box::new(InstantDamage(100))); + let entity = entity.update(&mut floor); + assert!(matches!(entity, None)); +} + +#[test] +fn test_entity_basic_action() { + let mut floor = get_basic_floor(); + let mut entity = get_basic_entity(); + entity.position = Position(10, 10); + entity.buffer = Action::Move(Direction::Up); + + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(10, 11)); + assert_eq!(entity.direction, Direction::Up); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::Up); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(10, 12)); + assert_eq!(entity.direction, Direction::Up); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::Left); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(9, 12)); + assert_eq!(entity.direction, Direction::Left); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::Left); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(8, 12)); + assert_eq!(entity.direction, Direction::Left); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::Down); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(8, 11)); + assert_eq!(entity.direction, Direction::Down); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::Right); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(9, 11)); + assert_eq!(entity.direction, Direction::Right); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::Move(Direction::None); + let mut entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(9, 11)); + assert_eq!(entity.direction, Direction::None); + assert!(matches!(entity.buffer, Action::DoNothing)); + + entity.buffer = Action::DoNothing; + let entity = entity.update(&mut floor).unwrap(); + assert_eq!(entity.position, Position(9, 11)); + assert_eq!(entity.direction, Direction::None); + assert!(matches!(entity.buffer, Action::DoNothing)); +} + +#[test] +fn test_generator_priority() { + let mut vec = vec![(1_u32, &"a"), (3, &"b"), (2, &"c")].into_iter(); + let vec1 = vec!["", "", ""]; + let vec = rogue_lib::generator::vec_filter(&vec1, |_| vec.next()); + let mut sum: std::collections::HashMap<&str, u32> = std::collections::HashMap::new(); + let mut rng = ::seed_from_u64(0); + let tot = 600000; + for _ in 0..tot { + let sample = rogue_lib::generator::vec_get_sample(&vec, &mut rng); + let val = sum.entry(*sample).or_default(); + *val += 1; + } + + // deve essere ~circa a questo valore (per questo il round) + assert_eq!( + (*sum.get("a").unwrap() as f32 / (tot as f32 / 6.0)).round(), + 3.0 + ); + assert_eq!( + (*sum.get("b").unwrap() as f32 / (tot as f32 / 6.0)).round(), + 1.0 + ); + assert_eq!( + (*sum.get("c").unwrap() as f32 / (tot as f32 / 6.0)).round(), + 2.0 + ); +}