Very basic stab at "difficulty rating" sort of thing
This commit is contained in:
102
src/wad.rs
102
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<String, HashMap<Enemy, u16>>,
|
||||
HashMap<String, HashMap<HealthAndArmour, u16>>,
|
||||
) {
|
||||
) -> HashMap<String, (HashMap<Enemy, u16>, HashMap<HealthAndArmour, u16>)> {
|
||||
let mut file = BufReader::new(File::open(ow.path).unwrap());
|
||||
let mut enemy_maps: HashMap<String, HashMap<Enemy, u16>> = HashMap::new();
|
||||
let mut health_maps: HashMap<String, HashMap<HealthAndArmour, u16>> = HashMap::new();
|
||||
let mut level_summary: HashMap<String, (HashMap<Enemy, u16>, HashMap<HealthAndArmour, u16>)> =
|
||||
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<u16> for Enemy {
|
||||
fn from(ttype: u16) -> Self {
|
||||
match ttype {
|
||||
@@ -212,6 +254,7 @@ impl std::convert::From<u16> 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]
|
||||
|
||||
Reference in New Issue
Block a user