PkmnLib_rs/src/static_data/libraries/type_library.rs

120 lines
3.3 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
#[derive(Debug)]
pub struct TypeLibrary {
types: HashMap<String, u8>,
effectiveness: Vec<Vec<f32>>,
}
impl TypeLibrary {
pub fn new(capacity: usize) -> TypeLibrary {
TypeLibrary {
types: HashMap::with_capacity(capacity),
effectiveness: vec![],
}
}
pub fn get_type_id(&self, key: &str) -> u8 {
self.types[key]
}
pub fn get_single_effectiveness(&self, attacking: u8, defending: u8) -> f32 {
self.effectiveness[attacking as usize][defending as usize]
}
pub fn get_effectiveness(&self, attacking: u8, defending: &[u8]) -> f32 {
let mut e = 1.0;
for def in defending {
e *= self.get_single_effectiveness(attacking, *def);
}
e
}
pub fn register_type(&mut self, name: &str) -> u8 {
let id = self.types.len() as u8;
self.types.insert(name.to_string(), id);
self.effectiveness.resize((id + 1) as usize, vec![]);
for effectiveness in &mut self.effectiveness {
effectiveness.resize((id + 1) as usize, 1.0)
}
id
}
pub fn set_effectiveness(&mut self, attacking: u8, defending: u8, effectiveness: f32) {
self.effectiveness[attacking as usize][defending as usize] = effectiveness;
}
}
#[cfg(test)]
pub mod tests {
use crate::static_data::libraries::type_library::TypeLibrary;
use assert_approx_eq::assert_approx_eq;
pub fn build() -> TypeLibrary {
let mut lib = TypeLibrary::new(2);
// Borrow as mut so we can insert
let w = &mut lib;
w.register_type("foo");
w.register_type("bar");
// Drops borrow as mut
w.set_effectiveness(0, 1, 0.5);
w.set_effectiveness(1, 0, 2.0);
lib
}
#[test]
fn add_two_types_retrieve_them() {
let mut lib = TypeLibrary::new(2);
// Borrow as mut so we can insert
let w = &mut lib;
w.register_type("foo");
w.register_type("bar");
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
assert_eq!(r.get_type_id("foo"), 0);
assert_eq!(r.get_type_id("bar"), 1);
}
#[test]
fn add_two_types_set_effectiveness_retrieve() {
let mut lib = TypeLibrary::new(2);
// Borrow as mut so we can insert
let w = &mut lib;
w.register_type("foo");
w.register_type("bar");
w.set_effectiveness(0, 1, 0.5);
w.set_effectiveness(1, 0, 2.0);
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
assert_approx_eq!(r.get_single_effectiveness(0, 1), 0.5);
assert_approx_eq!(r.get_single_effectiveness(1, 0), 2.0);
}
#[test]
fn add_two_types_get_aggregate_effectiveness() {
let mut lib = TypeLibrary::new(2);
// Borrow as mut so we can insert
let w = &mut lib;
w.register_type("foo");
w.register_type("bar");
w.set_effectiveness(0, 1, 0.5);
w.set_effectiveness(1, 0, 2.0);
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
assert_approx_eq!(r.get_effectiveness(0, &[1_u8, 1_u8]), 0.25);
assert_approx_eq!(r.get_effectiveness(1, &[0_u8, 0_u8]), 4.0);
}
}