From f0c556833c3ba80bf9a9646f85a8a184c8826dd0 Mon Sep 17 00:00:00 2001 From: HeNine <> Date: Mon, 29 May 2023 15:12:45 +0200 Subject: [PATCH] bandit --- examples/vs_bandit.rs | 68 +++++++++++++++++++++++++++++++++++ src/lib.rs | 4 ++- src/premade/mod.rs | 31 ++++++++++++++-- src/test_util/battle_stats.rs | 36 +++++++++++++++++++ src/test_util/mod.rs | 1 + 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 examples/vs_bandit.rs create mode 100644 src/test_util/battle_stats.rs create mode 100644 src/test_util/mod.rs diff --git a/examples/vs_bandit.rs b/examples/vs_bandit.rs new file mode 100644 index 0000000..5d78296 --- /dev/null +++ b/examples/vs_bandit.rs @@ -0,0 +1,68 @@ +use kartsimrust::{ + premade::{get_bandit, get_bob, get_george}, + test_util::battle_stats::battle_stats, +}; + +fn main() { + env_logger::init(); + + let mut characters = vec![get_bob()]; + let mut enemies = (0..1).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "Bob won {:.2}% of battles in an average of {:.1} turns.", + p, mu_t + ); + + characters = vec![get_george()]; + enemies = (0..1).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "George won {:.2}% of battles in an average of {:.1} turns.", + p, mu_t + ); + + characters = vec![get_bob()]; + enemies = (0..2).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "Bob won {:.2}% of battles against 2 Bandits in an average of {:.1} turns.", + p, mu_t + ); + + characters = vec![get_bob(), get_george()]; + enemies = (0..1).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "Bob and George won {:.2}% of battles against 1 Bandit in an average of {:.1} turns.", + p, mu_t + ); + + characters = vec![get_bob(), get_george()]; + enemies = (0..2).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "Bob and George won {:.2}% of battles against 2 Bandits in an average of {:.1} turns.", + p, mu_t + ); + + characters = vec![get_bob(), get_george()]; + enemies = (0..3).map(|_| get_bandit()).collect::>(); + + let (p, mu_t) = battle_stats(characters, enemies); + + println!( + "Bob and George won {:.2}% of battles against 3 Bandits in an average of {:.1} turns.", + p, mu_t + ) +} diff --git a/src/lib.rs b/src/lib.rs index 6ceeddb..b773b19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,4 +9,6 @@ pub mod stats; pub mod random_character; -pub mod premade; \ No newline at end of file +pub mod premade; + +pub mod test_util; \ No newline at end of file diff --git a/src/premade/mod.rs b/src/premade/mod.rs index 5661b05..c67edab 100644 --- a/src/premade/mod.rs +++ b/src/premade/mod.rs @@ -38,7 +38,7 @@ pub fn get_george() -> Character { } /* - * Drub is a goblin. + * Drub is a ~~goblin~~ drub. */ pub fn get_drub() -> Character { let mut drub = create_character( @@ -57,10 +57,30 @@ pub fn get_drub() -> Character { return drub; } +/* + * Just an average bandit. + */ +pub fn get_bandit() -> Character { + let mut drub = create_character( + String::from("Bandit"), + Class::NPC, + Class::NPC, + StatBlock::from((1, 0, 2, 1, 1, 1, 0, 1)), + StatBlock::default(), + Armor::Medium, + WeaponType::BladedWeapon.create_weapon(String::from("Shortsword")), + ); + + drub.proficiencies.bladed_weapons = true; + drub.proficiencies.medium_armor = true; + + return drub; +} + #[cfg(test)] mod premade_tests { - use super::{get_bob, get_drub, get_george}; + use super::{get_bandit, get_bob, get_drub, get_george}; #[test] fn print_bob() { @@ -82,4 +102,11 @@ mod premade_tests { println!("{}", drub); } + + #[test] + fn print_bandit() { + let bandit = get_bandit(); + + println!("{}", bandit); + } } diff --git a/src/test_util/battle_stats.rs b/src/test_util/battle_stats.rs new file mode 100644 index 0000000..ff2ff66 --- /dev/null +++ b/src/test_util/battle_stats.rs @@ -0,0 +1,36 @@ +use crate::{character::Character, combat::make_them_fight}; + +pub fn battle_stats(characters: Vec, enemies: Vec) -> (f64, f64) { + let mut a = 1.0; + let mut b = 1.0; + + let mut total_turns = 0.0; + let mut battles = 0.0; + + let mut chars: Vec = characters.iter().map(|c| c.clone()).collect(); + let mut enms: Vec = enemies.iter().map(|c| c.clone()).collect(); + + loop { + if let Some(turns) = make_them_fight(chars.iter_mut().collect(), enms.iter_mut().collect()) + { + battles += 1.0; + total_turns += turns as f64; + + if chars.iter().all(|c| c.is_dead()) { + b += 1.0; + log::trace!("Bob died in {} turns.", turns) + } else { + a += 1.0; + log::trace!("Bandit died in {} turns.", turns) + } + + if (a * b) / (f64::powi(a + b, 2) * (a + b + 1.0)) <= 0.0001 { + break; + } + } else { + log::trace!("No one died.") + } + } + + (a / (a + b) * 100.0, total_turns / battles) +} diff --git a/src/test_util/mod.rs b/src/test_util/mod.rs new file mode 100644 index 0000000..9e20cec --- /dev/null +++ b/src/test_util/mod.rs @@ -0,0 +1 @@ +pub mod battle_stats; \ No newline at end of file