diff --git a/src/lib.rs b/src/lib.rs index 7b9f860..9baeff9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,12 +6,12 @@ pub fn add(left: usize, right: usize) -> usize { #[cfg(test)] mod tests { - + extern crate alloc; - + use alloc::string::String; - use crate::{keysmash, scrunkly}; + use crate::{keysmash, scrunkly, StateMachine}; use super::catgirl_nonsense; @@ -56,9 +56,320 @@ mod tests { } assert_eq!(&result, "aw sproinkly,,,,scringle limtle cutest the like scrinkly double scrimblookimty... ittle adornale boink"); } + + #[test] + fn uwurandom_test() { + // Use a stable-algorithm RNG with fixed seed + let mut rng = rand_pcg::Pcg32::new(0xcafef00dd15ea5e5, 0xa02bdbf7bb3c0a7); + let mut state_machine = StateMachine::new(&mut rng); + let mut result = String::new(); + for _ in 0..1000 { + let (new_state, generated) = state_machine.generate(&mut rng); + result.push(generated); + state_machine = new_state; + } + assert_eq!(&result, "nyaaaaa aww looo,,scringle limtle cutest the l *falls asleep* mrowmewnyanyaaameowwwmeowmraownya AAAAAA :3 uwu gbafhg;djkafgjhjrajfjdfghfhdfgajgadkafg;lkjlkgahjrg;alfg >////< uwu aw icat spunkus!! and scrinky to and cute!! then,,aww when.. the scrunge........ lo awwwww th uwu aw. i!!!!! hap n flungle boinkly.. icat tien mraowmreowrmeowmreowmeowpurrrowwwwwwwwwmraowmrowmewmrowmraowmrowmeowrmraowrmeowmewmrowrmeowrmrowrnyanyaamewmrowmrowrmeowmrrrowmeowmraowmeowrmewmrownynya uwu mrowmewnyaaaamewpurrowmeowmrownyaaamrowmraowmeowwwwwmewnyanya kghgafkfgadhfhiurahdhiufghgafguegauahjfjhgdfl;ag;hfhhgjhafgajfjdhajfgahfgbkaghrgldfghdhkfghiurgskjfgafgjhng AAAAAAAA aww widdle sproinge! aw icamty. limty!!!! the limtle tienpsy and i,,,so icamt!! boinky whe ghg;ajdfg;kfghgbargahdskajfglkjajfkafjhiujfgjajlkgl;ldfgahgkgaurafgjlkadfdhgldhkjhghiuradkaurhjdfkalkahjkjhghi >/////< uwu nyaaa mrwmeowrnyamrowmewpurrppurrrppurrownyaaamrowmeowmeowmewmeowpurrrrrrrmeowmraowmrowmewmrwmenya dfgbafdhgurguralkafkhraujgkfl"); + } } -pub use keysmash::StateMachine as KeysmashChain; mod catgirl_nonsense; mod keysmash; -mod scrunkly; \ No newline at end of file +mod scrunkly; + +static ACTIONS: [&str; 12] = [ + "*tilts head*", + "*twitches ears slightly*", + "*purrs*", + "*falls asleep*", + "*sits on ur keyboard*", + "*nuzzles*", + "*stares at u*", + "*points towards case of monster zero ultra*", + "*sneezes*", + "*plays with yarn*", + "*eats all ur doritos*", + "*lies down on a random surface*", +]; + +enum StateMachine { + Uwu { + left: u8, + }, + CatgirlNonsense(CatgirlNonsenseMachine), + Nyaaaaaaa(NyaaaaaaaMachine), + Blush(BlushMachine), + ColonThree { + left: u8, + }, + Actions { + left: &'static str, + }, + Keysmash { + machine: keysmash::StateMachine, + left: u8, + }, + Screaming { + left: u8, + }, + Scrunkly(ScrunklyMachine), + Owo { + left: u8, + }, + Space { + prev: u8, + }, +} + +impl StateMachine { + fn new(mut rng: impl ::rand_core::RngCore) -> Self { + match rng.next_u32() % 10 { + 0 => StateMachine::Uwu { left: 3 }, + 1 => StateMachine::CatgirlNonsense(CatgirlNonsenseMachine::new()), + 2 => StateMachine::Nyaaaaaaa(NyaaaaaaaMachine::new()), + 3 => StateMachine::Blush(BlushMachine::new()), + 4 => StateMachine::ColonThree { left: 2 }, + 5 => StateMachine::Actions { + left: ACTIONS[(rng.next_u32() % 12) as usize], + }, + 6 => StateMachine::Keysmash { + machine: keysmash::StateMachine::new_random(&mut rng).0, + left: ((rng.next_u32() % 125) + 25) as u8, + }, + 7 => StateMachine::Screaming { + left: ((rng.next_u32() % 12) + 5) as u8, + }, + 8 => StateMachine::Scrunkly(ScrunklyMachine::new()), + 9 => StateMachine::Uwu { left: 3 }, + _ => unreachable!(), + } + } + + fn get_discrim(&self) -> u8 { + match self { + StateMachine::Uwu { left } => 0, + StateMachine::CatgirlNonsense(_) => 1, + StateMachine::Nyaaaaaaa(_) => 2, + StateMachine::Blush(_) => 3, + StateMachine::ColonThree { left } => 4, + StateMachine::Actions { left } => 5, + StateMachine::Keysmash { machine, left } => 6, + StateMachine::Screaming { left } => 7, + StateMachine::Scrunkly(_) => 8, + StateMachine::Owo { left } => 9, + StateMachine::Space { prev } => 10, + } + } + + fn generate(self, mut rng: impl ::rand_core::RngCore) -> (Self, char) { + match self { + StateMachine::Uwu { left } => match left { + 3 => (StateMachine::Uwu { left: 2 }, 'u'), + 2 => (StateMachine::Uwu { left: 1 }, 'w'), + 1 => (StateMachine::Space { prev: 0 }, 'u'), + _ => unreachable!(), + }, + StateMachine::CatgirlNonsense(machine) => match machine.generate(rng) { + (Some(machine), generated) => (StateMachine::CatgirlNonsense(machine), generated), + (None, generated) => (StateMachine::Space { prev: 1 }, generated), + }, + StateMachine::Nyaaaaaaa(machine) => match machine.generate(rng) { + (Some(machine), generated) => (StateMachine::Nyaaaaaaa(machine), generated), + (None, generated) => (StateMachine::Space { prev: 2 }, generated), + }, + StateMachine::Blush(machine) => match machine.generate(rng) { + (Some(machine), generated) => (StateMachine::Blush(machine), generated), + (None, generated) => (StateMachine::Space { prev: 3 }, generated), + }, + StateMachine::ColonThree { left } => match left { + 2 => (StateMachine::ColonThree { left: 1 }, ':'), + 1 => (StateMachine::Space { prev: 4 }, '3'), + _ => unreachable!(), + }, + StateMachine::Actions { left } => match left.len() { + 1 => ( + StateMachine::Space { prev: 5 }, + left.chars().next().unwrap(), + ), + _ => ( + StateMachine::Actions { + left: left.split_at(1).1, + }, + left.chars().next().unwrap(), + ), + }, + StateMachine::Keysmash { machine, left } => match left { + 1 => (StateMachine::Space { prev: 6 }, machine.generate(rng).1), + x => { + let (new_state, generated) = machine.generate(rng); + ( + StateMachine::Keysmash { + machine: new_state, + left: x - 1, + }, + generated, + ) + } + }, + StateMachine::Screaming { left } => match left { + 1 => (StateMachine::Space { prev: 7 }, 'A'), + _ => (StateMachine::Screaming { left: left - 1 }, 'A'), + }, + StateMachine::Scrunkly(machine) => match machine.generate(rng) { + (Some(machine), generated) => (StateMachine::Scrunkly(machine), generated), + (None, generated) => (StateMachine::Space { prev: 8 }, generated), + }, + StateMachine::Owo { left } => match left { + 3 => (StateMachine::Owo { left: 2 }, 'o'), + 2 => (StateMachine::Owo { left: 1 }, 'w'), + 1 => (StateMachine::Space { prev: 9 }, 'o'), + _ => unreachable!(), + }, + StateMachine::Space { prev } => loop { + let new = StateMachine::new(&mut rng); + if new.get_discrim() != prev { + break (new, ' '); + } + }, + } + } +} + +enum CatgirlNonsenseMachine { + StartM, + StartR, + Middle { + machine: catgirl_nonsense::StateMachine, + left: u8, + }, + EndN, + EndY, + EndA, +} + +impl CatgirlNonsenseMachine { + fn new() -> Self { + CatgirlNonsenseMachine::StartM + } + fn generate(self, mut rng: impl ::rand_core::RngCore) -> (Option, char) { + match self { + CatgirlNonsenseMachine::StartM => (Some(CatgirlNonsenseMachine::StartR), 'm'), + CatgirlNonsenseMachine::StartR => ( + Some(CatgirlNonsenseMachine::Middle { + machine: catgirl_nonsense::StateMachine::Mr, + left: ((rng.next_u32() % 125) + 25) as u8, + }), + 'r', + ), + CatgirlNonsenseMachine::Middle { machine, left } => match left { + 1 => (Some(CatgirlNonsenseMachine::EndN), machine.generate(rng).1), + x => { + let (new_state, generated) = machine.generate(rng); + ( + Some(CatgirlNonsenseMachine::Middle { + machine: new_state, + left: x - 1, + }), + generated, + ) + } + }, + CatgirlNonsenseMachine::EndN => (Some(CatgirlNonsenseMachine::EndY), 'n'), + CatgirlNonsenseMachine::EndY => (Some(CatgirlNonsenseMachine::EndA), 'y'), + CatgirlNonsenseMachine::EndA => (None, 'a'), + } + } +} + +enum ScrunklyMachine { + StartA, + StartW, + End { + machine: scrunkly::StateMachine, + left: u8, + }, +} + +impl ScrunklyMachine { + fn new() -> Self { + ScrunklyMachine::StartA + } + fn generate(self, mut rng: impl ::rand_core::RngCore) -> (Option, char) { + match self { + ScrunklyMachine::StartA => (Some(Self::StartW), 'a'), + ScrunklyMachine::StartW => ( + Some(Self::End { + machine: scrunkly::StateMachine::Aw, + left: ((rng.next_u32() % 75) + 25) as u8, + }), + 'w', + ), + ScrunklyMachine::End { machine, left } => match left { + 1 => (None, machine.generate(rng).1), + x => { + let (new_state, generated) = machine.generate(rng); + ( + Some(ScrunklyMachine::End { + machine: new_state, + left: x - 1, + }), + generated, + ) + } + }, + } + } +} + +enum NyaaaaaaaMachine { + N, + Y, + A { left: u8 }, +} + +impl NyaaaaaaaMachine { + fn new() -> Self { + Self::N + } + fn generate(self, mut rng: impl ::rand_core::RngCore) -> (Option, char) { + match self { + Self::N => (Some(Self::Y), 'n'), + Self::Y => ( + Some(Self::A { + left: ((rng.next_u32() % 7) + 1) as u8, + }), + 'y', + ), + Self::A { left } => match left { + 1 => (None, 'a'), + x => (Some(Self::A { left: x - 1 }), 'a'), + }, + } + } +} + +enum BlushMachine { + Start, + Middle { left: u8 }, + End, +} + +impl BlushMachine { + fn new() -> Self { + Self::Start + } + fn generate(self, mut rng: impl ::rand_core::RngCore) -> (Option, char) { + match self { + BlushMachine::Start => ( + Some(BlushMachine::Middle { + left: ((rng.next_u32() % 4) + 3) as u8, + }), + '>', + ), + BlushMachine::Middle { left } => match left { + 1 => (Some(BlushMachine::End), '/'), + x => (Some(BlushMachine::Middle { left: x - 1 }), '/'), + }, + BlushMachine::End => (None, '<'), + } + } +}