diff --git a/Cargo.lock b/Cargo.lock index 8f88c77..7706606 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1479,8 +1479,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "lights-out" -version = "0.1.1" +version = "0.1.2" dependencies = [ + "rand", "slint", "slint-build", ] @@ -2068,6 +2069,24 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "raw-window-handle" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index 4c51fe8..f2a5b43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lights-out" -version = "0.1.1" +version = "0.1.2" authors = ["Tastaturtaste "] edition = "2021" build = "build.rs" @@ -9,6 +9,7 @@ license = "Apache-2.0" # Has to be compatible with slint's GPLv3 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rand = { version = "0.8.5", default-features = false, features = ["small_rng", "getrandom"] } slint = "1.0" [build-dependencies] diff --git a/src/main.rs b/src/main.rs index ad3aa8c..f1a638c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use rand::rngs::SmallRng; +use rand::{Rng, SeedableRng}; use std::{ cell::{Cell, RefCell}, rc::Rc, @@ -23,13 +25,16 @@ impl LightsOutState { } fn resize(&mut self, size: usize) { self.size = size; + let n = size * size; + self.activations.resize(n, false); + self.lights.resize(n, false); + self.switch_to_solve.resize(n, false); self.deactivate_all(); } fn deactivate_all(&mut self) { - let n = self.size * self.size; - self.activations = vec![false; n]; - self.lights = vec![false; n]; - self.switch_to_solve = vec![false; n]; + self.activations = self.activations.iter().map(|_| false).collect(); + self.lights = self.lights.iter().map(|_| false).collect(); + self.switch_to_solve = self.switch_to_solve.iter().map(|_| false).collect(); } } @@ -133,7 +138,7 @@ fn main() -> Result<(), slint::PlatformError> { } }); ui.on_notify_switch_individual_lights_clicked({ - let state_ref = lights_out_state; + let state_ref = lights_out_state.clone(); move |switch_individual_lights_on_click: bool| { let mut lights_out_state = state_ref.borrow_mut(); // When switching to individual light mode nothing special has to be done. @@ -148,6 +153,32 @@ fn main() -> Result<(), slint::PlatformError> { ); } }); + ui.on_notify_randomize_clicked({ + let state_ref = lights_out_state; + let ui_handle = ui.as_weak(); + let mut rng = SmallRng::from_entropy(); + move || { + let ui = ui_handle.unwrap(); + let mut lights_out_state = state_ref.borrow_mut(); + lights_out_state.deactivate_all(); + for light in &mut lights_out_state.lights { + *light = rng.gen::(); + } + lights_out_state.activations = solve_switch_system( + build_light_system_matrix(lights_out_state.size), + lights_out_state.lights.clone(), + ); + ui.set_button_field_lights( + Rc::new(slint::VecModel::from(lights_out_state.lights.clone())).into(), + ); + ui.set_button_field_switch_to_solve( + Rc::new(slint::VecModel::from( + lights_out_state.switch_to_solve.clone(), + )) + .into(), + ); + } + }); ui.run() } diff --git a/ui/appwindow.slint b/ui/appwindow.slint index 485957f..20985c3 100644 --- a/ui/appwindow.slint +++ b/ui/appwindow.slint @@ -55,6 +55,9 @@ export component LightsOut inherits Window { placeholder-text: "Field size"; max-width: 100px; } + randomize_button := Button{ + text: "Randomize"; + } solve_button := Button { text: "Solve"; } @@ -83,6 +86,7 @@ export component LightsOut inherits Window { callback notify_solve_clicked <=> solve_button.clicked; callback notify_resize_request <=> resize_field.accepted; callback notify_switch_individual_lights_clicked(bool); + callback notify_randomize_clicked <=> randomize_button.clicked; in-out property button_field_size <=> button_field.size; in property <[bool]> button_field_lights <=> button_field.lit; out property requested_size <=> resize_field.text;