1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
use rand::prelude::*; use std::collections::HashMap; use super::row::*; use super::skill::*; use super::slab_def::*; #[derive(PartialEq, PartialOrd)] struct DefDensity { def: SlabDef, density: f64, } impl std::cmp::Eq for DefDensity {} impl std::cmp::Ord for DefDensity { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.def.cmp(&other.def) } } fn build_rng_seed(seed: u64, row_index: usize) -> [u8; 32] { let mut buf: [u8; 32] = [0; 32]; let buf1 = bincode::serialize(&seed).unwrap(); let mut i: usize = 0; for v in buf1.into_iter() { buf[i] = v; i += 1; } let buf2 = bincode::serialize(&row_index).unwrap(); for v in buf2.into_iter() { buf[i] = v; i += 1; } buf } pub fn generate_first_row(seed: u64, width: usize, skill: Skill) -> Row { let rng_seed = build_rng_seed(seed, 0); let rng: StdRng = SeedableRng::from_seed(rng_seed); let def_density = skill.def_density0(); row_from_def_density(rng, width, &def_density) } pub fn generate_next_row(seed: u64, j: usize, previous_row: &Row, skill: Skill) -> Row { let rng_seed = build_rng_seed(seed, j); let rng: StdRng = SeedableRng::from_seed(rng_seed); let def_density = skill.def_density(); row_from_previous(rng, previous_row, &def_density, skill.mutability()) } fn row_from_def_density( mut rng: impl Rng, width: usize, def_density: &HashMap<SlabDef, f64>, ) -> Row { let mut row = Row::default(); let mut v: Vec<DefDensity> = Vec::new(); for (def, density) in def_density { v.push(DefDensity { def: *def, density: *density, }); } v.sort(); for i in 0..width { let f: f64 = rng.gen(); let mut limit: f64 = 0.0; for dd in &v { if f >= limit && f < limit + dd.density { row.set(i as isize, dd.def); break; } limit += dd.density; } } row } fn row_from_previous( mut rng: impl Rng, previous_row: &Row, def_density: &HashMap<SlabDef, f64>, mutability: f64, ) -> Row { let mut row = Row::default(); let mut v: Vec<DefDensity> = Vec::new(); for (def, density) in def_density { v.push(DefDensity { def: *def, density: *density, }); } v.sort(); for i in 0..(previous_row.slabs.len() as isize) { let f: f64 = rng.gen(); let mut limit: f64 = 0.0; for dd in &v { if f >= limit && f < limit + dd.density { row.set(i, dd.def); break; } limit += dd.density; } let change: f64 = rng.gen(); let previous_def = previous_row.get(i); if change >= mutability && !previous_def.is_special() && !row.get(i).is_special() { row.set(i as isize, previous_def); } } row }