diff --git a/src/editor.rs b/src/editor.rs index a85c676..b25d19c 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -3,15 +3,17 @@ use std::path::PathBuf; use std::str::FromStr; use std::{env, isize}; -use egui::{InnerResponse, RichText}; +use egui::{ComboBox, InnerResponse, RichText}; use tinyfiledialogs; const STEPS_PER_FRAME: usize = 50; +use crate::random::Seed; use crate::{ config::GenerationConfig, generator::Generator, map::Map, position::Position, random::Random, }; use egui::{epaint::Shadow, CollapsingHeader, Color32, Frame, Label, Margin, Ui}; + use macroquad::camera::{set_camera, Camera2D}; use macroquad::input::{ is_key_pressed, is_mouse_button_down, is_mouse_button_released, mouse_position, mouse_wheel, @@ -161,6 +163,22 @@ pub fn edit_range_usize(ui: &mut Ui, values: &mut (usize, usize)) { }); } + +pub fn enum_input_ui(ui: &mut Ui, seed: &mut Seed) { + + + match seed { + // U64 + Seed::U64(value) => { + ui.add(egui::DragValue::new(value)); + }, + // String + Seed::Str(value) => { + ui.add(egui::TextEdit::singleline(value).desired_width(100.0)); + } + } +} + pub struct Editor { state: EditorState, pub configs: HashMap, @@ -190,7 +208,7 @@ pub struct Editor { impl Editor { pub fn new(config: GenerationConfig) -> Editor { let configs: HashMap = GenerationConfig::get_configs(); - let gen = Generator::new(&config, 0); // TODO: overwritten anyways? Option? + let gen = Generator::new(&config, Seed::from_u64(0)); // TODO: overwritten anyways? Option? Editor { state: EditorState::Paused(PausedState::Setup), configs, @@ -275,8 +293,22 @@ impl Editor { }); }); + + Seed + egui::ComboBox::from_label("seed type") + .selected_text(format!("{:}", self.config.name.clone())) + .show_ui(ui, |ui| { + for (name, cfg) in self.configs.iter() { + ui.selectable_value(&mut self.config, cfg.clone(), name); + } + }); + if self.is_setup() { field_edit_widget(ui, &mut self.user_str_seed, edit_string, "str seed", true); + + let text_edit = egui::TextEdit::singleline(value).desired_width(100.0); + ui.add(text_edit); + ui.checkbox(&mut self.fixed_seed, "fixed seed"); } ui.separator(); @@ -438,11 +470,7 @@ impl Editor { ui.add(Label::new(format!("playback: {:?}", self.state))); ui.add(Label::new(format!( "seed: {:?}", - ( - &self.gen.rnd.seed_hex, - &self.gen.rnd.seed_u64, - &self.gen.rnd.seed_str - ) + (&self.gen.rnd.seed_u64, &self.gen.rnd.seed_str) ))); ui.add(Label::new(format!("config: {:?}", &self.config))); }); @@ -499,20 +527,20 @@ impl Editor { } fn on_start(&mut self) { - let seed_u64 = if !self.user_str_seed.is_empty() { + let seed = if !self.user_str_seed.is_empty() { // generate new seed based on user string - let seed_u64 = Random::str_seed_to_u64(&self.user_str_seed); + let seed_u64 = Seed::from_string(&self.user_str_seed); if !self.fixed_seed { self.user_str_seed = String::new(); } seed_u64 } else if self.fixed_seed { - self.gen.rnd.seed_u64 // re-use last seed + Seed::from_u64(self.gen.rnd.seed_u64) // re-use last seed } else { - self.gen.rnd.random_u64() // generate new seed from previous generator + Seed::from_u64(self.gen.rnd.random_u64()) // generate new seed from previous generator }; - self.gen = Generator::new(&self.config, seed_u64); + self.gen = Generator::new(&self.config, seed); } fn mouse_in_viewport(cam: &Camera2D) -> bool { diff --git a/src/generator.rs b/src/generator.rs index f941a09..718881a 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -3,7 +3,7 @@ use crate::{ kernel::Kernel, map::{BlockType, Map}, position::Position, - random::Random, + random::{Random, Seed}, walker::CuteWalker, }; @@ -18,7 +18,7 @@ pub struct Generator { impl Generator { /// derive a initial generator state based on a GenerationConfig - pub fn new(config: &GenerationConfig, seed: u64) -> Generator { + pub fn new(config: &GenerationConfig, seed: Seed) -> Generator { let spawn = Position::new(50, 250); let map = Map::new(300, 300, BlockType::Hookable, spawn.clone()); let init_inner_kernel = Kernel::new(config.inner_size_bounds.1, 0.0); @@ -137,7 +137,7 @@ impl Generator { seed: u64, config: &GenerationConfig, ) -> Result { - let mut gen = Generator::new(&config, seed); + let mut gen = Generator::new(&config, Seed::from_u64(seed)); for _ in 0..max_steps { if gen.walker.finished { diff --git a/src/random.rs b/src/random.rs index 416bdab..623821c 100644 --- a/src/random.rs +++ b/src/random.rs @@ -6,18 +6,45 @@ use seahash::hash; pub struct Random { pub seed_str: Option, - pub seed_hex: String, pub seed_u64: u64, gen: SmallRng, weighted_dist: WeightedAliasIndex, } +pub enum Seed { + U64(u64), + Str(String), +} + +impl Seed { + pub fn from_u64(seed_u64: u64) -> Seed { + Seed::U64(seed_u64) + } + + pub fn from_string(seed_str: &String) -> Seed { + Seed::Str(seed_str.to_owned()) + } + + pub fn str_to_u64(seed_str: &String) -> u64 { + hash(seed_str.as_bytes()) + } +} + impl Random { - pub fn new(seed_u64: u64, weights: Vec) -> Random { + pub fn new(seed: Seed, weights: Vec) -> Random { + let mut seed_str: Option = None; + let seed_u64 = match seed { + Seed::U64(seed_u64) => seed_u64, + Seed::Str(seed) => { + let seed_u64 = Seed::str_to_u64(&seed); + seed_str = Some(seed); + seed_u64 + } + }; + Random { - seed_str: None, + seed_str, seed_u64, - seed_hex: format!("{:X}", seed_u64), gen: SmallRng::seed_from_u64(seed_u64), weighted_dist: Random::get_weighted_dist(weights), } @@ -29,19 +56,9 @@ impl Random { tmp_rng.next_u64() } - pub fn from_str_seed(seed_str: String, weights: Vec) -> Random { - let seed_u64 = hash(seed_str.as_bytes()); - let mut rnd = Random::new(seed_u64, weights); - rnd.seed_str = Some(seed_str); - - rnd - } - /// uses another rnd struct to derive initial seed for a new rnd struct pub fn from_previous_rnd(rnd: &mut Random, weights: Vec) -> Random { - let seed_u64 = rnd.gen.next_u64(); - - Random::new(seed_u64, weights) + Random::new(Seed::from_u64(rnd.gen.next_u64()), weights) } pub fn in_range_inclusive(&mut self, low: usize, high: usize) -> usize { @@ -64,10 +81,6 @@ impl Random { self.gen.next_u64() } - pub fn str_seed_to_u64(seed_str: &String) -> u64 { - hash(seed_str.as_bytes()) - } - fn get_weighted_dist(weights: Vec) -> WeightedAliasIndex { // sadly WeightedAliasIndex is initialized using a Vec. So im manually checking for the // correct size. I feel like there must be a better way also the current apprach allows