From 07cbd886189052c10f3308bba8dc6b3be15e57de Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sat, 4 May 2024 12:49:50 +0200 Subject: [PATCH] fix 'copy' rule cells not copying the correct cell on rotated or flipped rule variants --- petri/src/lib.rs | 29 ++++++++++++++++++++++------- uscope/src/main.rs | 21 +++++++++++++-------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/petri/src/lib.rs b/petri/src/lib.rs index 5fcfb67..0eda324 100644 --- a/petri/src/lib.rs +++ b/petri/src/lib.rs @@ -60,7 +60,7 @@ pub enum RuleCellTo { /// randomly choose from the group GroupRandom(usize), /// copy the cell from the corresponding input position - Copy(usize), + Copy(usize, usize), } impl SubRule { @@ -197,7 +197,10 @@ impl Rule { let mut new = b.clone(); for y in 0..new.height { for x in 0..new.width { - let old = b.get(new.width - x - 1, y); + let mut old = b.get(new.width - x - 1, y); + if let (_, RuleCellTo::Copy(cx, _cy)) = &mut old { + *cx = new.width - *cx - 1; + } new.set_both(x, y, old); } } @@ -209,7 +212,10 @@ impl Rule { let mut new = b.clone(); for y in 0..new.height { for x in 0..new.width { - let old = b.get(x, new.height - y - 1); + let mut old = b.get(x, new.height - y - 1); + if let (_, RuleCellTo::Copy(_cx, cy)) = &mut old { + *cy = new.height - *cy - 1; + } new.set_both(x, y, old); } } @@ -222,7 +228,11 @@ impl Rule { let mut new = b.clone(); for y in 0..new.height { for x in 0..new.width { - let old = b.get(new.width - x - 1, new.height - y - 1); + let mut old = b.get(new.width - x - 1, new.height - y - 1); + if let (_, RuleCellTo::Copy(cx, cy)) = &mut old { + *cx = new.width - *cx - 1; + *cy = new.height - *cy - 1; + } new.set_both(x, y, old); } } @@ -235,7 +245,10 @@ impl Rule { new.width = b.height; for y in 0..new.height { for x in 0..new.width { - let old = b.get(y, x); + let mut old = b.get(y, x); + if let (_, RuleCellTo::Copy(cx, cy)) = &mut old { + (*cx, *cy) = (*cy, *cx); + } new.set_both(x, y, old); } } @@ -280,6 +293,7 @@ impl Dish { let mut default_rules = vec![ Rule { enabled: true, + name: "fall".into(), base: SubRule { width: 1, height: 2, @@ -292,6 +306,7 @@ impl Dish { }, Rule { enabled: true, + name: "slide".into(), base: SubRule { width: 2, height: 2, @@ -384,8 +399,8 @@ impl Dish { self.set_cell(px, py, cell); } } - RuleCellTo::Copy(index) => { - let cell = old_state[index]; + RuleCellTo::Copy(x, y) => { + let cell = old_state[x + y * variant.width]; if let Some(cell) = cell { // if the copy source is outside the world, do nothing self.set_cell(px, py, cell); diff --git a/uscope/src/main.rs b/uscope/src/main.rs index 91c254d..fd23e43 100644 --- a/uscope/src/main.rs +++ b/uscope/src/main.rs @@ -495,11 +495,9 @@ fn rule_cell_edit_to( let group = &groups[*group_id]; draw_group(ui, rect, group, cells); } - RuleCellTo::Copy(index) => { + RuleCellTo::Copy(x, y) => { let this = rect.center(); - let x = *index % rule_width; - let y = *index / rule_width; - let target = origin + Vec2::from((x as f32, y as f32)) * CSIZE + let target = origin + Vec2::from((*x as f32, *y as f32)) * CSIZE - Vec2::X * (CSIZE * (rule_width as f32 + 1.) + RESIZE_BUTTON_WIDTH * 2.) + Vec2::splat(CSIZE) * 0.5; overlay_lines.push((this, target)); @@ -519,8 +517,15 @@ fn rule_cell_edit_to( *group_id %= groups.len(); changed = true; } - RuleCellTo::Copy(index) => { - *index = (*index + 1) % (rule_width * rule_height); + RuleCellTo::Copy(x, y) => { + *x += 1; + if *x >= rule_width { + *x = 0; + *y += 1; + if *y >= rule_height { + *y = 0; + } + } changed = true; } } @@ -536,9 +541,9 @@ fn rule_cell_edit_to( *rule = RuleCellTo::GroupRandom(0); } RuleCellTo::GroupRandom(_) => { - *rule = RuleCellTo::Copy(0); + *rule = RuleCellTo::Copy(0, 0); } - RuleCellTo::Copy(_) => { + RuleCellTo::Copy(_, _) => { *rule = RuleCellTo::None; } }