conspire/
lib.rs

1#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
2#![doc = include_str!("../README.md")]
3
4#[cfg(feature = "constitutive")]
5pub mod constitutive;
6
7#[cfg(feature = "domain")]
8mod domain;
9
10#[cfg(feature = "fem")]
11#[path = "domain/fem/mod.rs"]
12pub mod fem;
13
14#[cfg(feature = "math")]
15pub mod math;
16
17#[cfg(feature = "mechanics")]
18pub mod mechanics;
19
20#[cfg(test)]
21mod test;
22
23use std::{
24    sync::atomic::{AtomicU64, Ordering},
25    time::{SystemTime, UNIX_EPOCH},
26};
27
28/// Absolute tolerance.
29pub const ABS_TOL: f64 = 1e-12;
30
31/// Relative tolerance.
32pub const REL_TOL: f64 = 1e-12;
33
34#[cfg(test)]
35/// A perturbation.
36pub const EPSILON: f64 = 1e-6;
37
38#[allow(dead_code)]
39#[cfg_attr(coverage_nightly, coverage(off))]
40fn defeat_message<'a>() -> &'a str {
41    match random_u8(14) {
42        0 => "Game over.",
43        1 => "I am Error.",
44        2 => "Insert coin to continue.",
45        3 => "Now let's all agree to never be creative again.",
46        4 => "Oh dear, you are dead!",
47        5 => "Press F to pay respects.",
48        6 => "Surprise! You're dead!",
49        7 => "Task failed successfully.",
50        8 => "This is not your grave, but you are welcome in it.",
51        9 => "To be continued...",
52        10 => "What a horrible night to have a curse.",
53        11 => "You cannot give up just yet.",
54        12 => "You have died of dysentery.",
55        13 => "You lost the game.",
56        14.. => "You've met with a terrible fate, haven't you?",
57    }
58}
59
60#[allow(dead_code)]
61#[cfg_attr(coverage_nightly, coverage(off))]
62fn victory_message<'a>() -> &'a str {
63    match random_u8(7) {
64        0 => "A winner is you!",
65        1 => "Bird up!",
66        2 => "Congraturation, this story is happy end!",
67        3 => "Flawless victory.",
68        4 => "Hey, that's pretty good!",
69        5 => "Nice work, bone daddy.",
70        6 => "That's Numberwang!",
71        7.. => "That was totes yeet, yo!",
72    }
73}
74
75fn random_u8(max: u8) -> u8 {
76    if max == u8::MAX {
77        return get_random();
78    }
79    // let range = (max as u16) + 1;
80    // let threshold = ((256_u16 / range) * range) as u8;
81    let mut attempts = 0;
82    loop {
83        let val = get_random();
84        // if val < threshold {
85        //     return val % (max + 1);
86        // }
87        attempts += 1;
88        if attempts > 10 {
89            return val % (max + 1);
90        }
91    }
92}
93
94fn get_random() -> u8 {
95    static STATE: AtomicU64 = AtomicU64::new(0);
96    let mut s = STATE.load(Ordering::Relaxed);
97    if s == 0 {
98        let now = SystemTime::now()
99            .duration_since(UNIX_EPOCH)
100            .unwrap_or_default();
101        s = 1 + now.as_nanos() as u64;
102    }
103    s ^= s << 13;
104    s ^= s >> 7;
105    s ^= s << 17;
106    STATE.store(s, Ordering::Relaxed);
107    (s >> 56) as u8
108}