diff --git a/src/editor.rs b/src/editor.rs index 2120942..dbbadd8 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -14,7 +14,7 @@ use crate::{ marble_engine::{ board::Board, pos::{Pos, PosInt}, - tile::{Direction, GateType, MathOp, MirrorType, PTile, Tile, WireType}, + tile::{Direction, GateType, MarbleTarget, MathOp, MirrorType, OpenTile, PTile, Tile, WireType}, Machine, }, simple_button, simple_option_button, slider, @@ -722,7 +722,7 @@ impl Editor { let max = selection.0.max(selection.1); for x in min.x..=max.x { for y in min.y..=max.y { - self.source_board.set(Pos { x, y }, Tile::Blank); + self.source_board.set(Pos { x, y }, Tile::default()); } } } @@ -935,7 +935,7 @@ impl Editor { let pos = *pos; for n in 0..10 { if d.is_key_pressed(unsafe { transmute::(b'0' as u32 + n) }) { - self.set_tile(pos, Tile::Digit(n as u8)); + self.set_tile(pos, Tile::Open(OpenTile::Digit(n as u8), MarbleTarget::Free)); } } } @@ -994,9 +994,8 @@ impl Editor { Tool::Digits(_pos) => { self.active_tool = Tool::Digits(Some(pos)); if let Some(tile) = self.source_board.get_mut(pos) { - if let Tile::Digit(_) = tile { - } else { - *tile = Tile::Digit(0); + if ! matches!(tile, Tile::Open(OpenTile::Digit(_), _)) { + *tile = Tile::Open(OpenTile::Digit(0), MarbleTarget::Free); } } } @@ -1019,7 +1018,7 @@ impl Editor { if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) && self.active_tool == Tool::Erase { - self.set_tile(tile_pos.into(), Tile::Blank) + self.set_tile(tile_pos.into(), Tile::default()) } if let Tool::SelectArea(selection) = &mut self.active_tool { if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) { diff --git a/src/marble_engine.rs b/src/marble_engine.rs index bb897fe..624079f 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -153,7 +153,7 @@ impl Machine { continue; } - let can_move_to = |tile| matches!(tile, Some(Tile::Blank | Tile::Digit(_))); + let can_move_to = |tile| matches!(tile, Some(Tile::Open(_, _))); let can_move_over = |tile| match tile { Tile::Mirror(mirror) => { @@ -228,7 +228,7 @@ impl Machine { // resolve deletions of tiles for (i, event) in self.events.iter().enumerate() { if let Event::Remove = event { - self.board.set(self.marbles[i], Tile::Blank); + self.board.set(self.marbles[i], Tile::default()); } } @@ -268,10 +268,10 @@ impl Machine { match event { Event::MoveTo(new_pos, new_dir) => { let mut value = *value; - self.board.set(self.marbles[i], Tile::Blank); + self.board.set(self.marbles[i], Tile::default()); self.marbles[i] = new_pos; let new_tile = self.board.get_mut(new_pos).unwrap(); - if let Tile::Digit(n) = new_tile { + if let Tile::Open(OpenTile::Digit(n), _) = new_tile { value = value.wrapping_mul(10).wrapping_add(*n as MarbleValue); } *new_tile = Tile::Marble { diff --git a/src/marble_engine/board.rs b/src/marble_engine/board.rs index 907e0db..6052ff5 100644 --- a/src/marble_engine/board.rs +++ b/src/marble_engine/board.rs @@ -26,7 +26,7 @@ impl Board { rows.push(tiles); } for line in &mut rows { - line.resize(width, Tile::Blank); + line.resize(width, Tile::default()); } Board::new(rows) @@ -44,7 +44,7 @@ impl Board { } pub fn new_empty(width: usize, height: usize) -> Self { - let rows = vec![vec![Tile::Blank; width]; height]; + let rows = vec![vec![Tile::default(); width]; height]; Self { rows, width, @@ -65,7 +65,7 @@ impl Board { for row in &self.rows { for tile in row { match tile { - Tile::Blank | Tile::Block => (), + Tile::Open(OpenTile::Blank, _) | Tile::Block => (), _ => sum += 1, } } @@ -104,7 +104,7 @@ impl Board { pub fn get_blank_mut(&mut self, p: Pos) -> Option<&mut Tile> { if self.in_bounds(p) { let tile = &mut self.rows[p.y as usize][p.x as usize]; - if tile == &Tile::Blank { + if let Tile::Open(OpenTile::Blank, _) = tile{ return Some(tile); } } @@ -147,7 +147,7 @@ impl Board { if p.x < 0 { let len = p.x.unsigned_abs() as usize; for row in &mut self.rows { - let mut new_row = vec![Tile::Blank; len]; + let mut new_row = vec![Tile::default(); len]; new_row.append(row); *row = new_row; } @@ -156,21 +156,21 @@ impl Board { } else if p.x as usize >= self.width { let new_width = p.x as usize + 1; for row in &mut self.rows { - row.resize(new_width, Tile::Blank); + row.resize(new_width, Tile::default()); } self.width = new_width; } if p.y < 0 { let len = p.y.unsigned_abs() as usize; - let mut new_rows = vec![vec![Tile::Blank; self.width]; len]; + let mut new_rows = vec![vec![Tile::default(); self.width]; len]; new_rows.append(&mut self.rows); self.rows = new_rows; offset_y = len; self.height += len; } else if p.y as usize >= self.height { let new_height = p.y as usize + 1; - self.rows.resize(new_height, vec![Tile::Blank; self.width]); + self.rows.resize(new_height, vec![Tile::default(); self.width]); self.height = new_height; } (offset_x as PosInt, offset_y as PosInt) diff --git a/src/marble_engine/tile.rs b/src/marble_engine/tile.rs index 89e4072..fe430d7 100644 --- a/src/marble_engine/tile.rs +++ b/src/marble_engine/tile.rs @@ -2,21 +2,31 @@ use crate::marble_engine::Pos; pub type MarbleValue = u32; -#[derive(Debug, Default, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Tile { - #[default] - Blank, + Open(OpenTile, MarbleTarget), Block, - Marble { - value: MarbleValue, - dir: Direction, - }, - Digit(u8), + Marble { value: MarbleValue, dir: Direction }, Mirror(MirrorType), Arrow(Direction), Powerable(PTile, bool), } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum MarbleTarget { + Free, + ClaimedIndirect, + Claimed, + BlockedIndirect, + Blocked, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum OpenTile { + Blank, + Digit(u8), +} + #[derive(Debug, Clone, Copy, PartialEq)] pub enum PTile { Trigger, @@ -66,6 +76,12 @@ pub enum Direction { Right, } +impl Default for Tile { + fn default() -> Self { + Tile::Open(OpenTile::Blank, MarbleTarget::Free) + } +} + impl Tile { pub const fn from_char(c: char) -> Tile { match c { @@ -95,19 +111,18 @@ impl Tile { 'D' => Tile::Powerable(PTile::Math(MathOp::Div), false), 'R' => Tile::Powerable(PTile::Math(MathOp::Rem), false), 'B' => Tile::Powerable(PTile::Bag, false), - d @ '0'..='9' => Tile::Digit(d as u8 - b'0'), + d @ '0'..='9' => Tile::Open(OpenTile::Digit(d as u8 - b'0'), MarbleTarget::Free), '#' => Tile::Block, - ' ' => Tile::Blank, - _ => Tile::Blank, + _ => Tile::Open(OpenTile::Blank, MarbleTarget::Free), } } pub fn to_char(self) -> char { match self { - Tile::Blank => ' ', + Tile::Open(OpenTile::Blank, _) => ' ', Tile::Block => '#', Tile::Marble { value: _, dir: _ } => 'o', - Tile::Digit(n) => (b'0' + n) as char, + Tile::Open(OpenTile::Digit(n), _) => (b'0' + n) as char, Tile::Mirror(dir) => match dir { MirrorType::Forward => '/', MirrorType::Back => '\\', @@ -146,23 +161,23 @@ impl Tile { } pub fn is_blank(&self) -> bool { - matches!(self, Tile::Blank) + matches!(self, Tile::Open(OpenTile::Blank, _)) } pub fn read_value(&self) -> MarbleValue { match self { Tile::Marble { value, dir: _ } => *value, - Tile::Digit(d) => *d as MarbleValue, + Tile::Open(OpenTile::Digit(d), _) => *d as MarbleValue, _ => 0, } } pub fn texture(&self) -> String { match self { - Tile::Blank => "", + Tile::Open(OpenTile::Blank, _) => "", Tile::Block => "block", Tile::Marble { value: _, dir: _ } => "marble", - Tile::Digit(n) => return format!("tile_digit_{n}"), + Tile::Open(OpenTile::Digit(n), _) => return format!("tile_digit_{n}"), Tile::Mirror(mirror) => mirror.texture_name(), Tile::Arrow(dir) => dir.arrow_tile_texture_name(), Tile::Powerable(tile, state) => {