Initial commit, implements most of the static_data side.

This commit is contained in:
2021-01-30 22:29:59 +01:00
commit 2a08fb2645
33 changed files with 1237 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
use crate::utils::random::Random;
use std::collections::HashMap;
pub trait DataLibrary<'a, T: 'a> {
fn map(&self) -> &HashMap<String, T>;
fn list_values(&self) -> &Vec<String>;
fn get_modify(&mut self) -> (&mut HashMap<String, T>, &mut Vec<String>);
fn add(&mut self, key: &str, value: T) {
let modifies = self.get_modify();
modifies.0.insert(key.to_string(), value);
modifies.1.push(key.to_string());
}
fn remove(&mut self, key: &str) {
let modifies = self.get_modify();
let index = modifies.1.iter().position(|r| *r == key).unwrap();
modifies.0.remove(key);
modifies.1.remove(index);
}
fn get(&self, key: &str) -> Option<&T> {
self.map().get(key)
}
fn get_mut(&mut self, key: &str) -> Option<&mut T> {
self.get_modify().0.get_mut(key)
}
fn len(&self) -> usize {
self.map().len()
}
fn is_empty(&self) -> bool {
self.map().is_empty()
}
fn random_value(&self, rand: &mut Random) -> &T {
let i = rand.get_between(0, self.list_values().len() as i32);
let key = &self.list_values()[i as usize];
return &self.map()[key];
}
}

View File

@@ -0,0 +1,69 @@
use crate::defines::LevelInt;
use crate::static_data::growth_rates::growth_rate::GrowthRate;
use std::collections::HashMap;
use std::fmt;
use std::fmt::{Debug, Formatter};
pub struct GrowthRateLibrary {
growth_rates: HashMap<String, Box<dyn GrowthRate>>,
}
impl GrowthRateLibrary {
pub fn new(capacity: usize) -> GrowthRateLibrary {
GrowthRateLibrary {
growth_rates: HashMap::with_capacity(capacity),
}
}
pub fn calculate_level(&self, growth_rate: &str, experience: u32) -> LevelInt {
self.growth_rates[growth_rate].calculate_level(experience)
}
pub fn calculate_experience(&self, growth_rate: &str, level: LevelInt) -> u32 {
self.growth_rates[growth_rate].calculate_experience(level)
}
pub fn add_growth_rate(&mut self, key: &str, value: Box<dyn GrowthRate>) {
self.growth_rates.insert(key.to_string(), value);
}
}
impl Debug for GrowthRateLibrary {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("GrowthRateLibrary").finish()
}
}
#[cfg(test)]
mod tests {
use crate::static_data::growth_rates::lookup_growth_rate::LookupGrowthRate;
use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary;
#[test]
fn add_growth_rate_to_library_and_calculate_level() {
let mut lib = GrowthRateLibrary::new(1);
// Borrow as mut so we can insert
let w = &mut lib;
w.add_growth_rate("foo", Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100])));
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
assert_eq!(r.calculate_level("foo", 3), 1);
assert_eq!(r.calculate_level("foo", 50), 3);
}
#[test]
fn add_growth_rate_to_library_and_calculate_experience() {
let mut lib = GrowthRateLibrary::new(1);
// Borrow as mut so we can insert
let w = &mut lib;
w.add_growth_rate("foo", Box::new(LookupGrowthRate::new(vec![0, 5, 10, 100])));
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
assert_eq!(r.calculate_experience("foo", 1), 0);
assert_eq!(r.calculate_experience("foo", 3), 10);
}
}

View File

@@ -0,0 +1,32 @@
use crate::static_data::items::item::Item;
use crate::static_data::libraries::data_library::DataLibrary;
use std::collections::HashMap;
#[derive(Debug)]
pub struct ItemLibrary {
map: HashMap<String, Item>,
list: Vec<String>,
}
impl ItemLibrary {
pub fn new(capacity: usize) -> ItemLibrary {
ItemLibrary {
map: HashMap::with_capacity(capacity),
list: Vec::with_capacity(capacity),
}
}
}
impl DataLibrary<'_, Item> for ItemLibrary {
fn map(&self) -> &HashMap<String, Item> {
&self.map
}
fn list_values(&self) -> &Vec<String> {
&self.list
}
fn get_modify(&mut self) -> (&mut HashMap<String, Item>, &mut Vec<String>) {
(&mut self.map, &mut self.list)
}
}

View File

@@ -0,0 +1,8 @@
use crate::defines::LevelInt;
use derive_getters::Getters;
#[derive(Getters, Debug)]
pub struct LibrarySettings {
maximum_level: LevelInt,
maximum_move_count: u8,
}

View File

@@ -0,0 +1,8 @@
pub mod data_library;
pub mod growth_rate_library;
pub mod item_library;
pub mod library_settings;
pub mod move_library;
pub mod species_library;
pub mod static_data;
pub mod type_library;

View File

@@ -0,0 +1,32 @@
use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::moves::move_data::MoveData;
use std::collections::HashMap;
#[derive(Debug)]
pub struct MoveLibrary {
map: HashMap<String, MoveData>,
list: Vec<String>,
}
impl MoveLibrary {
pub fn new(capacity: usize) -> MoveLibrary {
MoveLibrary {
map: HashMap::with_capacity(capacity),
list: Vec::with_capacity(capacity),
}
}
}
impl DataLibrary<'_, MoveData> for MoveLibrary {
fn map(&self) -> &HashMap<String, MoveData> {
&self.map
}
fn list_values(&self) -> &Vec<String> {
&self.list
}
fn get_modify(&mut self) -> (&mut HashMap<String, MoveData>, &mut Vec<String>) {
(&mut self.map, &mut self.list)
}
}

View File

@@ -0,0 +1,103 @@
use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::species_data::species::Species;
use std::collections::HashMap;
#[derive(Debug)]
pub struct SpeciesLibrary<'a> {
map: HashMap<String, Species<'a>>,
list: Vec<String>,
}
impl<'a> SpeciesLibrary<'a> {
pub fn new(capacity: usize) -> SpeciesLibrary<'a> {
SpeciesLibrary {
map: HashMap::with_capacity(capacity),
list: Vec::with_capacity(capacity),
}
}
}
impl<'a> DataLibrary<'a, Species<'a>> for SpeciesLibrary<'a> {
fn map(&self) -> &HashMap<String, Species<'a>> {
&self.map
}
fn list_values(&self) -> &Vec<String> {
&self.list
}
fn get_modify(&mut self) -> (&mut HashMap<String, Species<'a>>, &mut Vec<String>) {
(&mut self.map, &mut self.list)
}
}
#[cfg(test)]
mod tests {
use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::libraries::species_library::SpeciesLibrary;
use crate::static_data::species_data::form::Form;
use crate::static_data::species_data::learnable_moves::LearnableMoves;
use crate::static_data::species_data::species::Species;
use crate::static_data::statistic_set::StatisticSet;
use std::collections::HashSet;
fn build_species<'a>() -> Species<'a> {
Species::new(
0,
"foo",
0.5,
"",
0,
Form::new(
"default",
0.0,
0.0,
0,
Vec::new(),
StatisticSet::default(),
Vec::new(),
Vec::new(),
LearnableMoves::new(),
HashSet::new(),
),
HashSet::new(),
)
}
#[test]
fn add_species_to_library_and_fetch() {
let mut lib = SpeciesLibrary::new(1);
let species = build_species();
// Borrow as mut so we can insert
let w = &mut lib;
w.add("foo", species);
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
let mon = r.get("foo");
assert!(mon.is_some());
assert_eq!(*mon.unwrap().id(), 0_u16);
assert_eq!(mon.unwrap().name(), "foo");
assert_eq!(r.len(), 1);
}
#[test]
fn add_species_to_library_then_remove() {
let mut lib = SpeciesLibrary::new(1);
let species = build_species();
// Borrow as mut so we can insert
let w = &mut lib;
w.add("foo", species);
w.remove("foo");
// Drops borrow as mut
// Borrow as read so we can read
let r = &lib;
let mon = r.get("foo");
assert!(mon.is_none());
assert_eq!(r.len(), 0);
}
}

View File

@@ -0,0 +1,17 @@
use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary;
use crate::static_data::libraries::item_library::ItemLibrary;
use crate::static_data::libraries::library_settings::LibrarySettings;
use crate::static_data::libraries::move_library::MoveLibrary;
use crate::static_data::libraries::species_library::SpeciesLibrary;
use crate::static_data::libraries::type_library::TypeLibrary;
use derive_getters::Getters;
#[derive(Getters, Debug)]
struct StaticData<'a> {
settings: LibrarySettings,
species: SpeciesLibrary<'a>,
moves: MoveLibrary,
items: ItemLibrary,
growth_rates: GrowthRateLibrary,
types: TypeLibrary,
}

View File

@@ -0,0 +1,104 @@
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)]
mod tests {
use crate::static_data::libraries::type_library::TypeLibrary;
use assert_approx_eq::assert_approx_eq;
#[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);
}
}