mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Extract the random number generator
This commit is contained in:
parent
9752377a15
commit
610722a1bf
|
@ -831,7 +831,7 @@ mod test {
|
|||
use core::cell::RefCell;
|
||||
|
||||
use super::*;
|
||||
use crate::Gba;
|
||||
use crate::{rng, Gba};
|
||||
|
||||
#[test_case]
|
||||
fn can_store_and_retrieve_8_elements(_gba: &mut Gba) {
|
||||
|
@ -956,14 +956,13 @@ mod test {
|
|||
#[test_case]
|
||||
fn extreme_case(_gba: &mut Gba) {
|
||||
let mut map = HashMap::new();
|
||||
let mut rng = crate::rng::RandomNumberGenerator::new();
|
||||
|
||||
let mut answers: [Option<i32>; 128] = [None; 128];
|
||||
|
||||
for _ in 0..5_000 {
|
||||
let command = rng.next().rem_euclid(2);
|
||||
let key = rng.next().rem_euclid(answers.len() as i32);
|
||||
let value = rng.next();
|
||||
let command = rng::next().rem_euclid(2);
|
||||
let key = rng::next().rem_euclid(answers.len() as i32);
|
||||
let value = rng::next();
|
||||
|
||||
match command {
|
||||
0 => {
|
||||
|
|
41
agb/src/rng.rs
Normal file
41
agb/src/rng.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use core::cell::RefCell;
|
||||
|
||||
use bare_metal::Mutex;
|
||||
|
||||
use crate::interrupt::free;
|
||||
|
||||
pub struct RandomNumberGenerator {
|
||||
state: [u32; 4],
|
||||
}
|
||||
|
||||
impl RandomNumberGenerator {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
state: [1014776995, 476057059, 3301633994, 706340607],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> i32 {
|
||||
let result = (self.state[0].wrapping_add(self.state[3]))
|
||||
.rotate_left(7)
|
||||
.wrapping_mul(9);
|
||||
let t = self.state[1].wrapping_shr(9);
|
||||
|
||||
self.state[2] ^= self.state[0];
|
||||
self.state[3] ^= self.state[1];
|
||||
self.state[1] ^= self.state[2];
|
||||
self.state[0] ^= self.state[3];
|
||||
|
||||
self.state[2] ^= t;
|
||||
self.state[3] = self.state[3].rotate_left(11);
|
||||
|
||||
result as i32
|
||||
}
|
||||
}
|
||||
|
||||
static GLOBAL_RNG: Mutex<RefCell<RandomNumberGenerator>> =
|
||||
Mutex::new(RefCell::new(RandomNumberGenerator::new()));
|
||||
|
||||
pub fn next() -> i32 {
|
||||
free(|cs| GLOBAL_RNG.borrow(*cs).borrow_mut().next())
|
||||
}
|
Loading…
Reference in a new issue