Compare commits

..

2 commits

Author SHA1 Message Date
6d86f6fdef toggle individual rules 2024-05-01 23:23:44 +02:00
c435d96f33 allow removing rules 2024-05-01 23:15:44 +02:00
2 changed files with 38 additions and 6 deletions

View file

@ -20,7 +20,7 @@ pub struct Chunk {
pub struct Rule { pub struct Rule {
pub from: RulePattern, pub from: RulePattern,
pub to: RulePattern, pub to: RulePattern,
// enabled: bool pub enabled: bool,
// probability: u8 // probability: u8
// flip: // flip:
// rotate: // rotate:
@ -29,6 +29,7 @@ pub struct Rule {
impl Rule { impl Rule {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
enabled: false,
from: RulePattern::new(), from: RulePattern::new(),
to: RulePattern::new(), to: RulePattern::new(),
} }
@ -72,6 +73,7 @@ impl Dish {
rules: vec![ rules: vec![
Rule { Rule {
enabled: true,
from: RulePattern { from: RulePattern {
width: 1, width: 1,
height: 2, height: 2,
@ -84,6 +86,7 @@ impl Dish {
}, },
}, },
Rule { Rule {
enabled: true,
from: RulePattern { from: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
@ -96,6 +99,7 @@ impl Dish {
}, },
}, },
Rule { Rule {
enabled: true,
from: RulePattern { from: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
@ -112,10 +116,22 @@ impl Dish {
} }
pub fn fire_blindly(&mut self) { pub fn fire_blindly(&mut self) {
assert!(!self.rules.is_empty()); if self.rules.is_empty() {
return;
}
let x = random::<usize>() % CHUNK_SIZE; let x = random::<usize>() % CHUNK_SIZE;
let y = random::<usize>() % CHUNK_SIZE; let y = random::<usize>() % CHUNK_SIZE;
let rule = random::<usize>() % self.rules.len(); let enabled_rules = self
.rules
.iter()
.enumerate()
.filter_map(|(i, r)| r.enabled.then_some(i))
.collect::<Vec<_>>();
if enabled_rules.is_empty() {
return;
}
let rule = random::<usize>() % enabled_rules.len();
let rule = enabled_rules[rule];
self.fire_rule(rule, x, y); self.fire_rule(rule, x, y);
} }

View file

@ -33,7 +33,7 @@ impl UScope {
fn new(_cc: &eframe::CreationContext<'_>) -> Self { fn new(_cc: &eframe::CreationContext<'_>) -> Self {
Self { Self {
dish: Dish::new(), dish: Dish::new(),
speed: 100, speed: 250,
brush: Cell(1), brush: Cell(1),
celltypes: vec![ celltypes: vec![
CellData::new("air", 0, 0, 0), CellData::new("air", 0, 0, 0),
@ -51,7 +51,10 @@ impl eframe::App for UScope {
} }
SidePanel::left("left_panel").show(ctx, |ui| { SidePanel::left("left_panel").show(ctx, |ui| {
ui.heading("Simulation"); ui.heading("Simulation");
ui.label("speed");
ui.add(Slider::new(&mut self.speed, 0..=5000)); ui.add(Slider::new(&mut self.speed, 0..=5000));
ui.separator();
ui.heading("Cells"); ui.heading("Cells");
for (i, cell) in self.celltypes.iter_mut().enumerate() { for (i, cell) in self.celltypes.iter_mut().enumerate() {
ui.horizontal(|ui| { ui.horizontal(|ui| {
@ -61,6 +64,7 @@ impl eframe::App for UScope {
ui.color_edit_button_srgba(&mut cell.color); ui.color_edit_button_srgba(&mut cell.color);
}); });
} }
if ui.button("add cell").clicked() { if ui.button("add cell").clicked() {
let h = random::<f32>(); let h = random::<f32>();
let s = random::<f32>() * 0.5 + 0.5; let s = random::<f32>() * 0.5 + 0.5;
@ -69,9 +73,19 @@ impl eframe::App for UScope {
let name = format!("cell #{}", self.celltypes.len()); let name = format!("cell #{}", self.celltypes.len());
self.celltypes.push(CellData { name, color }) self.celltypes.push(CellData { name, color })
} }
ui.separator();
ui.heading("Rules"); ui.heading("Rules");
for rule in &mut self.dish.rules { let mut to_remove = None;
for (i, rule) in self.dish.rules.iter_mut().enumerate() {
rule_editor(ui, rule, &self.celltypes); rule_editor(ui, rule, &self.celltypes);
if ui.button("delete").clicked() {
to_remove = Some(i);
}
ui.separator();
}
if let Some(i) = to_remove {
self.dish.rules.remove(i);
} }
if ui.button("add rule").clicked() { if ui.button("add rule").clicked() {
self.dish.rules.push(Rule::new()); self.dish.rules.push(Rule::new());
@ -108,8 +122,10 @@ fn paint_chunk(painter: Painter, chunk: &Chunk, cells: &[CellData]) {
} }
const CSIZE: f32 = 24.; const CSIZE: f32 = 24.;
const OUTLINE: (f32, Color32) = (1., Color32::GRAY); const OUTLINE: (f32, Color32) = (3., Color32::GRAY);
fn rule_editor(ui: &mut Ui, rule: &mut Rule, cells: &[CellData]) { fn rule_editor(ui: &mut Ui, rule: &mut Rule, cells: &[CellData]) {
ui.checkbox(&mut rule.enabled, "enable rule");
let cells_y = rule.from.height(); let cells_y = rule.from.height();
let cells_x = rule.from.width(); let cells_x = rule.from.width();
let margin = 8.; let margin = 8.;