From 061a987060a348f586f1ee24f642b591c6b030c7 Mon Sep 17 00:00:00 2001 From: Arthur Roberts Date: Tue, 4 Jul 2023 21:45:21 +0100 Subject: [PATCH] Very basic stab at "difficulty rating" sort of thing --- src/wad.rs | 102 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 20 deletions(-) diff --git a/src/wad.rs b/src/wad.rs index d4ad2f8..cde09aa 100644 --- a/src/wad.rs +++ b/src/wad.rs @@ -92,13 +92,10 @@ pub fn open_wad(path: &PathBuf) -> OpenWad { pub fn get_enemies_and_health_per_level( ow: OpenWad, -) -> ( - HashMap>, - HashMap>, -) { +) -> HashMap, HashMap)> { let mut file = BufReader::new(File::open(ow.path).unwrap()); - let mut enemy_maps: HashMap> = HashMap::new(); - let mut health_maps: HashMap> = HashMap::new(); + let mut level_summary: HashMap, HashMap)> = + HashMap::new(); for level_i in ow.level_indicies { let name = ow.nice_lumps.get(level_i).unwrap().name.clone(); let level_things_wad_lump = ow.nice_lumps.get(level_i + 1).unwrap(); @@ -129,10 +126,9 @@ pub fn get_enemies_and_health_per_level( } } } - enemy_maps.insert(name.clone(), enemy_map); - health_maps.insert(name, health_map); + level_summary.insert(name, (enemy_map, health_map)); } - (enemy_maps, health_maps) + level_summary } #[derive(Eq, Hash, PartialEq, Debug)] @@ -140,6 +136,7 @@ pub enum HealthAndArmour { HealthPotion, Stimpack, Medikit, + Beserk, Soulsphere, SpiritArmour, GreenArmour, @@ -173,6 +170,51 @@ pub enum Enemy { Unknown, } +impl Enemy { + fn difficulty_value(enemy: &Self) -> u16 { + match enemy { + Self::FormerHuman => 2, + Self::WolfensteinSs => 2, + Self::FormerHumanSergeant => 6, + Self::HeavyWeaponDude => 10, + Self::Imp => 4, + Self::Arachnotron => 14, + Self::ArchVile => 30, + Self::BaronOfHell => 16, + Self::BossBrain => 100, + Self::Cacodemon => 14, + Self::CyberDemon => 40, + Self::HellKnight => 10, + Self::LostSoul => 3, + Self::Mancubus => 18, + Self::PainElemental => 27, + Self::Revenant => 23, + Self::Spectre => 8, + Self::SpiderMastermind => 35, + Self::Demon => 7, + Self::Unknown => 0, + } + } +} + +impl HealthAndArmour { + fn health_value(hoa: &Self) -> u16 { + match hoa { + Self::Beserk => 100, + Self::Stimpack => 10, + Self::GreenArmour => 100, + Self::Invulnerability => 100, + Self::Medikit => 25, + Self::Megasphere => 300, + Self::Soulsphere => 100, + Self::SpiritArmour => 1, + Self::HealthPotion => 1, + Self::BlueArmour => 200, + Self::Unknown => 0, + } + } +} + impl std::convert::From for Enemy { fn from(ttype: u16) -> Self { match ttype { @@ -212,6 +254,7 @@ impl std::convert::From for HealthAndArmour { 83 => Self::Soulsphere, 2013 => Self::Megasphere, 2022 => Self::Invulnerability, + 2023 => Self::Beserk, _ => Self::Unknown, } } @@ -237,29 +280,48 @@ mod tests { fn test_num_levels_correct() { let freedoom_iwad = PathBuf::from("freedoom1.wad"); let ow = open_wad(&freedoom_iwad); - let (enemy_summary, _) = get_enemies_and_health_per_level(ow); - assert_eq!(enemy_summary.len(), 9 * 4); + let summary = get_enemies_and_health_per_level(ow); + assert_eq!(summary.len(), 9 * 4); } #[test] fn test_enemies_correct() { let freedoom_iwad = PathBuf::from("freedoom1.wad"); let ow = open_wad(&freedoom_iwad); - let (enemy_summary, _) = get_enemies_and_health_per_level(ow); - let c1m1 = enemy_summary.get("E1M1\0\0\0\0").unwrap(); - assert_eq!(c1m1.get(&Enemy::Imp), Some(&14)); + let summary = get_enemies_and_health_per_level(ow); + let (c1m1e, _) = summary.get("E1M1\0\0\0\0").unwrap(); + assert_eq!(c1m1e.get(&Enemy::Imp), Some(&14)); } #[test] fn test_health_correct() { let freedoom_iwad = PathBuf::from("freedoom1.wad"); let ow = open_wad(&freedoom_iwad); - let (_, health_summary) = get_enemies_and_health_per_level(ow); - let c1m1 = health_summary.get("E1M1\0\0\0\0").unwrap(); - assert_eq!(c1m1.get(&HealthAndArmour::BlueArmour), None); // I wonder if this should be a Some(&0) - assert_eq!(c1m1.get(&HealthAndArmour::HealthPotion), Some(&17)); - let c4m1 = health_summary.get("E4M1\0\0\0\0").unwrap(); - assert_eq!(c4m1.get(&HealthAndArmour::Stimpack), Some(&12)); + let summary = get_enemies_and_health_per_level(ow); + let (_, c1m1h) = summary.get("E1M1\0\0\0\0").unwrap(); + assert_eq!(c1m1h.get(&HealthAndArmour::BlueArmour), None); // I wonder if this should be a Some(&0) + assert_eq!(c1m1h.get(&HealthAndArmour::HealthPotion), Some(&17)); + let (_, c4m1h) = summary.get("E4M1\0\0\0\0").unwrap(); + assert_eq!(c4m1h.get(&HealthAndArmour::Stimpack), Some(&12)); + } + + #[test] + fn test_guess_at_difficulty() { + let freedoom_iwad = PathBuf::from("freedoom1.wad"); + let ow = open_wad(&freedoom_iwad); + let summary = get_enemies_and_health_per_level(ow); + for (level_name, (enemy_sum, health_sum)) in summary { + let mut enemy_total = 0; + for (enemy, num) in enemy_sum { + enemy_total += Enemy::difficulty_value(&enemy) * num; + } + let mut health_total = 0; + for (hoa, num) in health_sum { + health_total += HealthAndArmour::health_value(&hoa) * num; + } + println!("Level: {}, et: {}, ht: {}, ratio: {}", level_name, enemy_total * 10, health_total, (enemy_total * 10) / health_total); + } + panic!(); } #[test]