This commit is contained in:
Skye 2022-09-21 18:42:06 +09:00
parent fe50ee1f2c
commit e540cd5b9a
5 changed files with 47 additions and 8 deletions

View file

@ -253,7 +253,7 @@ const catgirlTable = generateMarkov(catgirlNonsense.split('\n'), 2)
const keysmashTable = generateMarkov(keysmash, 1); const keysmashTable = generateMarkov(keysmash, 1);
const scrunklyTable = generateMarkov(scrunks, 2); const scrunklyTable = generateMarkov(scrunks, 2);
console.log(JSON.stringify(magic(catgirlTable))) console.log(JSON.stringify(magic(scrunklyTable)))
// console.log(generateFromArray(catgirlTable, 100, 'ny')); // console.log(generateFromArray(catgirlTable, 100, 'ny'));
// //

View file

@ -5,7 +5,7 @@ pub fn add(left: usize, right: usize) -> usize {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::keysmash; use crate::{keysmash, scrunkly};
use super::catgirl_nonsense; use super::catgirl_nonsense;
@ -27,16 +27,31 @@ mod tests {
fn keysmash_test() { fn keysmash_test() {
// Use a stable-algorithm RNG with fixed seed // Use a stable-algorithm RNG with fixed seed
let mut rng = rand_pcg::Pcg32::new(0xcafef00dd15ea5e5, 0xa02bdbf7bb3c0a7); let mut rng = rand_pcg::Pcg32::new(0xcafef00dd15ea5e5, 0xa02bdbf7bb3c0a7);
let mut state_machine = keysmash::StateMachine::A; let (mut state_machine, result) = keysmash::StateMachine::new_random(&mut rng);
let mut result = String::from("a"); let mut result = String::from(result);
for _ in 0..100 { for _ in 0..100 {
let (new_state, generated) = state_machine.generate(&mut rng); let (new_state, generated) = state_machine.generate(&mut rng);
result.push(generated); result.push(generated);
state_machine = new_state; state_machine = new_state;
} }
assert_eq!(&result, "ajhfhiurgjfgajhnghgadfghkfghiurgjeghnhgjalkjfhgnhrgjhnhiuradfdbahrgbafhg;djkafgjhjrajfjdfghfhdfgajgad"); assert_eq!(&result, "ra;ajgjdhdfkgldskadfghkfghiurgjeghnhgjalkjfhgnhrgjhnhiuradfdbahrgbafhg;djkafgjhjrajfjdfghfhdfgajgadka");
}
#[test]
fn scrunkly_test() {
// Use a stable-algorithm RNG with fixed seed
let mut rng = rand_pcg::Pcg32::new(0xcafef00dd15ea5e5, 0xa02bdbf7bb3c0a7);
let mut state_machine = scrunkly::StateMachine::Aw;
let mut result = String::from("aw");
for _ in 0..100 {
let (new_state, generated) = state_machine.generate(&mut rng);
result.push(generated);
state_machine = new_state;
}
assert_eq!(&result, "aw sproinkly,,,,scringle limtle cutest the like scrinkly double scrimblookimty... ittle adornale boink");
} }
} }
mod catgirl_nonsense; mod catgirl_nonsense;
mod keysmash; mod keysmash;
mod scrunkly;

1
src/scrunkly.rs Normal file

File diff suppressed because one or more lines are too long

View file

@ -12,8 +12,15 @@ pub fn gen_fsm(item: TokenStream) -> TokenStream {
let input: Vec<MarkovArr> = serde_json::from_str(&format!("[{}]", item)).unwrap(); let input: Vec<MarkovArr> = serde_json::from_str(&format!("[{}]", item)).unwrap();
let mut match_arms = quote!(); let mut match_arms = quote!();
let mut variants = quote!(); let mut variants = quote!();
for state in input.iter() { let mut random_selection_match_arms = quote!();
for (idx, state) in input.iter().enumerate() {
let name = to_ident(&state.name); let name = to_ident(&state.name);
let name_lit = &state.name;
let idx = idx as u32;
random_selection_match_arms = quote!(
#random_selection_match_arms
#idx => (Self::#name, #name_lit),
);
variants = quote!( variants = quote!(
#variants #variants
#name, #name,
@ -47,6 +54,7 @@ pub fn gen_fsm(item: TokenStream) -> TokenStream {
}, },
); );
} }
let variant_count = input.len() as u32;
quote!( quote!(
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum StateMachine { pub enum StateMachine {
@ -58,11 +66,26 @@ pub fn gen_fsm(item: TokenStream) -> TokenStream {
#match_arms #match_arms
} }
} }
pub fn new_random(mut rng: impl ::rand_core::RngCore) -> (Self, &'static str) {
match rng.next_u32() % #variant_count {
#random_selection_match_arms
_ => unreachable!()
}
}
} }
) )
.into() .into()
} }
fn to_ident(name: &str) -> Ident { fn to_ident(name: &str) -> Ident {
Ident::new(&name.replace(';', " semicolon").to_case(Case::Pascal), Span::call_site().into()) Ident::new(
&name
.replace(';', " semicolon") // Sanitize ident-unsafe characters
.replace('!', " exclamation")
.replace(',', " comma")
.replace('.', " period") // I'm not calling it a full stop
.replace(' ', " space")
.to_case(Case::Pascal),
Span::call_site().into(),
)
} }