store tile vacancy in grid

This commit is contained in:
Crispy 2024-12-08 23:16:45 +01:00
parent 353f5b74e5
commit 0275e0c9b5
4 changed files with 50 additions and 36 deletions

View file

@ -14,7 +14,7 @@ use crate::{
marble_engine::{ marble_engine::{
board::Board, board::Board,
pos::{Pos, PosInt}, pos::{Pos, PosInt},
tile::{Direction, GateType, MathOp, MirrorType, PTile, Tile, WireType}, tile::{Direction, GateType, MarbleTarget, MathOp, MirrorType, OpenTile, PTile, Tile, WireType},
Machine, Machine,
}, },
simple_button, simple_option_button, slider, simple_button, simple_option_button, slider,
@ -722,7 +722,7 @@ impl Editor {
let max = selection.0.max(selection.1); let max = selection.0.max(selection.1);
for x in min.x..=max.x { for x in min.x..=max.x {
for y in min.y..=max.y { 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; let pos = *pos;
for n in 0..10 { for n in 0..10 {
if d.is_key_pressed(unsafe { transmute::<u32, KeyboardKey>(b'0' as u32 + n) }) { if d.is_key_pressed(unsafe { transmute::<u32, KeyboardKey>(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) => { Tool::Digits(_pos) => {
self.active_tool = Tool::Digits(Some(pos)); self.active_tool = Tool::Digits(Some(pos));
if let Some(tile) = self.source_board.get_mut(pos) { if let Some(tile) = self.source_board.get_mut(pos) {
if let Tile::Digit(_) = tile { if ! matches!(tile, Tile::Open(OpenTile::Digit(_), _)) {
} else { *tile = Tile::Open(OpenTile::Digit(0), MarbleTarget::Free);
*tile = Tile::Digit(0);
} }
} }
} }
@ -1019,7 +1018,7 @@ impl Editor {
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT)
&& self.active_tool == Tool::Erase && 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 let Tool::SelectArea(selection) = &mut self.active_tool {
if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) { if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) {

View file

@ -153,7 +153,7 @@ impl Machine {
continue; 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 { let can_move_over = |tile| match tile {
Tile::Mirror(mirror) => { Tile::Mirror(mirror) => {
@ -228,7 +228,7 @@ impl Machine {
// resolve deletions of tiles // resolve deletions of tiles
for (i, event) in self.events.iter().enumerate() { for (i, event) in self.events.iter().enumerate() {
if let Event::Remove = event { 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 { match event {
Event::MoveTo(new_pos, new_dir) => { Event::MoveTo(new_pos, new_dir) => {
let mut value = *value; 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; self.marbles[i] = new_pos;
let new_tile = self.board.get_mut(new_pos).unwrap(); 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); value = value.wrapping_mul(10).wrapping_add(*n as MarbleValue);
} }
*new_tile = Tile::Marble { *new_tile = Tile::Marble {

View file

@ -26,7 +26,7 @@ impl Board {
rows.push(tiles); rows.push(tiles);
} }
for line in &mut rows { for line in &mut rows {
line.resize(width, Tile::Blank); line.resize(width, Tile::default());
} }
Board::new(rows) Board::new(rows)
@ -44,7 +44,7 @@ impl Board {
} }
pub fn new_empty(width: usize, height: usize) -> Self { 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 { Self {
rows, rows,
width, width,
@ -65,7 +65,7 @@ impl Board {
for row in &self.rows { for row in &self.rows {
for tile in row { for tile in row {
match tile { match tile {
Tile::Blank | Tile::Block => (), Tile::Open(OpenTile::Blank, _) | Tile::Block => (),
_ => sum += 1, _ => sum += 1,
} }
} }
@ -104,7 +104,7 @@ impl Board {
pub fn get_blank_mut(&mut self, p: Pos) -> Option<&mut Tile> { pub fn get_blank_mut(&mut self, p: Pos) -> Option<&mut Tile> {
if self.in_bounds(p) { if self.in_bounds(p) {
let tile = &mut self.rows[p.y as usize][p.x as usize]; 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); return Some(tile);
} }
} }
@ -147,7 +147,7 @@ impl Board {
if p.x < 0 { if p.x < 0 {
let len = p.x.unsigned_abs() as usize; let len = p.x.unsigned_abs() as usize;
for row in &mut self.rows { 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); new_row.append(row);
*row = new_row; *row = new_row;
} }
@ -156,21 +156,21 @@ impl Board {
} else if p.x as usize >= self.width { } else if p.x as usize >= self.width {
let new_width = p.x as usize + 1; let new_width = p.x as usize + 1;
for row in &mut self.rows { for row in &mut self.rows {
row.resize(new_width, Tile::Blank); row.resize(new_width, Tile::default());
} }
self.width = new_width; self.width = new_width;
} }
if p.y < 0 { if p.y < 0 {
let len = p.y.unsigned_abs() as usize; 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); new_rows.append(&mut self.rows);
self.rows = new_rows; self.rows = new_rows;
offset_y = len; offset_y = len;
self.height += len; self.height += len;
} else if p.y as usize >= self.height { } else if p.y as usize >= self.height {
let new_height = p.y as usize + 1; 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; self.height = new_height;
} }
(offset_x as PosInt, offset_y as PosInt) (offset_x as PosInt, offset_y as PosInt)

View file

@ -2,21 +2,31 @@ use crate::marble_engine::Pos;
pub type MarbleValue = u32; pub type MarbleValue = u32;
#[derive(Debug, Default, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Tile { pub enum Tile {
#[default] Open(OpenTile, MarbleTarget),
Blank,
Block, Block,
Marble { Marble { value: MarbleValue, dir: Direction },
value: MarbleValue,
dir: Direction,
},
Digit(u8),
Mirror(MirrorType), Mirror(MirrorType),
Arrow(Direction), Arrow(Direction),
Powerable(PTile, bool), 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)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum PTile { pub enum PTile {
Trigger, Trigger,
@ -66,6 +76,12 @@ pub enum Direction {
Right, Right,
} }
impl Default for Tile {
fn default() -> Self {
Tile::Open(OpenTile::Blank, MarbleTarget::Free)
}
}
impl Tile { impl Tile {
pub const fn from_char(c: char) -> Tile { pub const fn from_char(c: char) -> Tile {
match c { match c {
@ -95,19 +111,18 @@ impl Tile {
'D' => Tile::Powerable(PTile::Math(MathOp::Div), false), 'D' => Tile::Powerable(PTile::Math(MathOp::Div), false),
'R' => Tile::Powerable(PTile::Math(MathOp::Rem), false), 'R' => Tile::Powerable(PTile::Math(MathOp::Rem), false),
'B' => Tile::Powerable(PTile::Bag, 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::Block,
' ' => Tile::Blank, _ => Tile::Open(OpenTile::Blank, MarbleTarget::Free),
_ => Tile::Blank,
} }
} }
pub fn to_char(self) -> char { pub fn to_char(self) -> char {
match self { match self {
Tile::Blank => ' ', Tile::Open(OpenTile::Blank, _) => ' ',
Tile::Block => '#', Tile::Block => '#',
Tile::Marble { value: _, dir: _ } => 'o', 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 { Tile::Mirror(dir) => match dir {
MirrorType::Forward => '/', MirrorType::Forward => '/',
MirrorType::Back => '\\', MirrorType::Back => '\\',
@ -146,23 +161,23 @@ impl Tile {
} }
pub fn is_blank(&self) -> bool { pub fn is_blank(&self) -> bool {
matches!(self, Tile::Blank) matches!(self, Tile::Open(OpenTile::Blank, _))
} }
pub fn read_value(&self) -> MarbleValue { pub fn read_value(&self) -> MarbleValue {
match self { match self {
Tile::Marble { value, dir: _ } => *value, Tile::Marble { value, dir: _ } => *value,
Tile::Digit(d) => *d as MarbleValue, Tile::Open(OpenTile::Digit(d), _) => *d as MarbleValue,
_ => 0, _ => 0,
} }
} }
pub fn texture(&self) -> String { pub fn texture(&self) -> String {
match self { match self {
Tile::Blank => "", Tile::Open(OpenTile::Blank, _) => "",
Tile::Block => "block", Tile::Block => "block",
Tile::Marble { value: _, dir: _ } => "marble", 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::Mirror(mirror) => mirror.texture_name(),
Tile::Arrow(dir) => dir.arrow_tile_texture_name(), Tile::Arrow(dir) => dir.arrow_tile_texture_name(),
Tile::Powerable(tile, state) => { Tile::Powerable(tile, state) => {