use serde::{Deserialize, Serialize};
pub use itihas::calendar as history_calendar;
pub use itihas::causality;
pub use itihas::civilization;
pub use itihas::era;
pub use itihas::event as history_event;
pub use itihas::figure;
pub use itihas::ItihasError;
pub use sankhya::babylonian;
pub use sankhya::chinese;
pub use sankhya::egyptian;
pub use sankhya::epoch;
pub use sankhya::greek;
pub use sankhya::gregorian;
pub use sankhya::hebrew;
pub use sankhya::islamic;
pub use sankhya::mayan;
pub use sankhya::persian;
pub use sankhya::roman;
pub use sankhya::vedic;
pub use sankhya::SankhyaError;
pub use varna::dialect;
pub use varna::grammar;
pub use varna::lexicon;
pub use varna::phoneme as lang_phoneme;
pub use varna::registry;
pub use varna::script;
pub use varna::VarnaError;
pub use pramana::bayesian as stats_bayesian;
pub use pramana::combinatorics;
pub use pramana::descriptive;
pub use pramana::distribution;
pub use pramana::hypothesis;
pub use pramana::markov;
pub use pramana::monte_carlo;
pub use pramana::regression;
pub use pramana::rng;
pub use pramana::timeseries;
pub use pramana::PramanaError;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CultureProfile {
pub civilization: String,
pub language: String,
pub calendar: String,
pub era: String,
pub active: bool,
}
impl CultureProfile {
pub fn new(
civilization: impl Into<String>,
language: impl Into<String>,
calendar: impl Into<String>,
) -> Self {
let civilization = civilization.into();
let language = language.into();
let calendar = calendar.into();
tracing::trace!(
%civilization, %language, %calendar,
"created culture profile"
);
Self {
civilization,
language,
calendar,
era: String::new(),
active: true,
}
}
pub fn with_era(mut self, era: impl Into<String>) -> Self {
self.era = era.into();
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StochasticSource {
pub distribution: String,
pub param_a: f64,
pub param_b: f64,
#[serde(skip)]
pub last_sample: f64,
pub active: bool,
}
impl StochasticSource {
pub fn uniform(min: f64, max: f64) -> Self {
tracing::trace!(
distribution = "uniform",
min,
max,
"created stochastic source"
);
Self {
distribution: "uniform".into(),
param_a: min,
param_b: max,
last_sample: 0.0,
active: true,
}
}
pub fn normal(mean: f64, std_dev: f64) -> Self {
tracing::trace!(
distribution = "normal",
mean,
std_dev,
"created stochastic source"
);
Self {
distribution: "normal".into(),
param_a: mean,
param_b: std_dev,
last_sample: 0.0,
active: true,
}
}
pub fn poisson(lambda: f64) -> Self {
Self {
distribution: "poisson".into(),
param_a: lambda,
param_b: 0.0,
last_sample: 0.0,
active: true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn culture_profile_builder() {
let c = CultureProfile::new("Roman Empire", "la", "julian").with_era("Classical");
assert_eq!(c.civilization, "Roman Empire");
assert_eq!(c.language, "la");
assert_eq!(c.era, "Classical");
}
#[test]
fn stochastic_uniform() {
let s = StochasticSource::uniform(0.0, 1.0);
assert_eq!(s.distribution, "uniform");
assert_eq!(s.param_a, 0.0);
assert_eq!(s.param_b, 1.0);
}
#[test]
fn stochastic_normal() {
let s = StochasticSource::normal(100.0, 15.0);
assert_eq!(s.distribution, "normal");
assert_eq!(s.param_a, 100.0);
}
#[test]
fn culture_as_component() {
let mut world = crate::World::new();
let e = world.spawn();
world
.insert_component(e, CultureProfile::new("Norse", "no", "gregorian"))
.unwrap();
assert!(world.has_component::<CultureProfile>(e));
}
#[test]
fn stochastic_as_component() {
let mut world = crate::World::new();
let e = world.spawn();
world
.insert_component(e, StochasticSource::poisson(5.0))
.unwrap();
let s = world.get_component::<StochasticSource>(e).unwrap();
assert_eq!(s.param_a, 5.0);
}
}