add comment storage to boards
This commit is contained in:
parent
0b9f41cbf6
commit
5c48b531f6
13 changed files with 219 additions and 113 deletions
|
@ -1,16 +1,16 @@
|
|||
use raylib::prelude::*;
|
||||
|
||||
pub mod board;
|
||||
pub mod grid;
|
||||
pub mod pos;
|
||||
pub mod tile;
|
||||
use crate::{theme::TILE_TEXTURE_SIZE, ui::draw_usize_small, util::Textures};
|
||||
use board::Board;
|
||||
use grid::Grid;
|
||||
use pos::*;
|
||||
use tile::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Machine {
|
||||
board: Board,
|
||||
grid: Grid,
|
||||
marbles: Vec<Pos>,
|
||||
powered: Vec<Pos>,
|
||||
input: Vec<u8>,
|
||||
|
@ -23,14 +23,14 @@ pub struct Machine {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct DebugSubTick {
|
||||
pub board: Board,
|
||||
pub grid: Grid,
|
||||
pub pos: Option<Pos>,
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn new_empty() -> Self {
|
||||
Self {
|
||||
board: Board::new_empty(5, 5),
|
||||
grid: Grid::new_empty(5, 5),
|
||||
marbles: Vec::new(),
|
||||
powered: Vec::new(),
|
||||
input: Vec::new(),
|
||||
|
@ -51,14 +51,14 @@ impl Machine {
|
|||
self.subtick_index = 0;
|
||||
}
|
||||
|
||||
pub fn set_board(&mut self, board: Board) {
|
||||
pub fn set_grid(&mut self, board: Grid) {
|
||||
self.marbles = board.get_marbles();
|
||||
self.powered.clear();
|
||||
self.board = board;
|
||||
self.grid = board;
|
||||
}
|
||||
|
||||
pub fn board(&self) -> &Board {
|
||||
&self.board
|
||||
pub fn grid(&self) -> &Grid {
|
||||
&self.grid
|
||||
}
|
||||
|
||||
pub fn output(&self) -> &[u8] {
|
||||
|
@ -93,7 +93,7 @@ impl Machine {
|
|||
for marble in &self.marbles {
|
||||
let x = marble.x;
|
||||
let y = marble.y;
|
||||
if let Some(tile) = self.board.get(*marble) {
|
||||
if let Some(tile) = self.grid.get(*marble) {
|
||||
let px = x as i32 * tile_size + offset.x as i32;
|
||||
let py = y as i32 * tile_size + offset.y as i32;
|
||||
if let Tile::Marble { value, dir } = tile {
|
||||
|
@ -114,7 +114,7 @@ impl Machine {
|
|||
self.subtick_index = 0;
|
||||
self.debug_subticks.clear();
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
grid: self.grid.clone(),
|
||||
pos: None,
|
||||
});
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ impl Machine {
|
|||
let mut new_marbles = Vec::new();
|
||||
// activate all powered machines
|
||||
for &pos in &self.powered {
|
||||
match self.board.get_mut(pos) {
|
||||
match self.grid.get_mut(pos) {
|
||||
Some(Tile::Powerable(PTile::Comparator(_), board_power_state)) => {
|
||||
// already handled at the power propagation stage (end of sim step)
|
||||
*board_power_state = Power::OFF;
|
||||
|
@ -138,7 +138,7 @@ impl Machine {
|
|||
continue;
|
||||
}
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
let Some(front_tile) = self.grid.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
// `machine` is being powered, in direction `dir`
|
||||
|
@ -147,8 +147,8 @@ impl Machine {
|
|||
if front_tile.is_blank() {
|
||||
let pos_a = dir.left().step(pos);
|
||||
let pos_b = dir.right().step(pos);
|
||||
let val_a = self.board.get_or_blank(pos_a).read_value();
|
||||
let val_b = self.board.get_or_blank(pos_b).read_value();
|
||||
let val_a = self.grid.get_or_blank(pos_a).read_value();
|
||||
let val_b = self.grid.get_or_blank(pos_b).read_value();
|
||||
|
||||
let value = match op {
|
||||
MathOp::Add => val_a.wrapping_add(val_b),
|
||||
|
@ -215,11 +215,11 @@ impl Machine {
|
|||
let mut influenced_direction = vec![DirInfluence::None; self.marbles.len()];
|
||||
|
||||
for (i, &pos) in self.marbles.iter().enumerate() {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.board.get(pos) else {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.grid.get(pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get(front_pos) else {
|
||||
let Some(front_tile) = self.grid.get(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
match front_tile {
|
||||
|
@ -252,7 +252,7 @@ impl Machine {
|
|||
}
|
||||
// #### apply all direct bounces ####
|
||||
for (i, &pos) in self.marbles.iter().enumerate() {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.board.get_mut(pos) else {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.grid.get_mut(pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
if will_reverse_direction[i] {
|
||||
|
@ -266,7 +266,7 @@ impl Machine {
|
|||
let mut claim_positions = Vec::new();
|
||||
// prepare creating the new marbles
|
||||
for &(pos, _val, _dir) in &new_marbles {
|
||||
let Some(Tile::Open(OpenTile::Blank, claim)) = self.board.get_mut(pos) else {
|
||||
let Some(Tile::Open(OpenTile::Blank, claim)) = self.grid.get_mut(pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
if claim.claim_indirect() {
|
||||
|
@ -276,22 +276,22 @@ impl Machine {
|
|||
// create new marbles
|
||||
// new marbles are past old_marbles index, so will not move this step
|
||||
for (pos, value, dir) in new_marbles {
|
||||
let Some(Tile::Open(OpenTile::Blank, Claim::ClaimedIndirect)) = self.board.get_mut(pos)
|
||||
let Some(Tile::Open(OpenTile::Blank, Claim::ClaimedIndirect)) = self.grid.get_mut(pos)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
self.board.set(pos, Tile::Marble { value, dir });
|
||||
self.grid.set(pos, Tile::Marble { value, dir });
|
||||
self.marbles.push(pos);
|
||||
}
|
||||
|
||||
// #### movement ####
|
||||
// mark claims to figure out what spaces can be moved to
|
||||
for &pos in &self.marbles[..old_marbles] {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.board.get(pos) else {
|
||||
let Some(Tile::Marble { value: _, dir }) = self.grid.get(pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
let Some(front_tile) = self.grid.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
if let Tile::Open(_type, claim) = front_tile {
|
||||
|
@ -305,7 +305,7 @@ impl Machine {
|
|||
Tile::Button(_) => dir.step(front_pos),
|
||||
_ => continue,
|
||||
};
|
||||
let Some(target_tile) = self.board.get_mut(target_pos) else {
|
||||
let Some(target_tile) = self.grid.get_mut(target_pos) else {
|
||||
continue;
|
||||
};
|
||||
if let Tile::Open(_type, claim) = target_tile {
|
||||
|
@ -319,15 +319,15 @@ impl Machine {
|
|||
let mut removed_marbles = Vec::new();
|
||||
// move marbles
|
||||
for (i, pos) in self.marbles[..old_marbles].iter_mut().enumerate() {
|
||||
let Some(Tile::Marble { value, dir }) = self.board.get(*pos) else {
|
||||
let Some(Tile::Marble { value, dir }) = self.grid.get(*pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
let front_pos = dir.step(*pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
let Some(front_tile) = self.grid.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut move_to = |tile, target_pos, dir, board: &mut Board| {
|
||||
let mut move_to = |tile, target_pos, dir, board: &mut Grid| {
|
||||
let value = match tile {
|
||||
OpenTile::Blank => value,
|
||||
OpenTile::Digit(n) => value.wrapping_mul(10).wrapping_add(n as MarbleValue),
|
||||
|
@ -339,11 +339,11 @@ impl Machine {
|
|||
|
||||
if let Tile::Open(space_type, claim_state) = front_tile {
|
||||
if *claim_state == Claim::Claimed {
|
||||
move_to(*space_type, front_pos, dir, &mut self.board);
|
||||
move_to(*space_type, front_pos, dir, &mut self.grid);
|
||||
} else if *claim_state != Claim::Free {
|
||||
// (Free means a marble was just here but moved earlier this tick)
|
||||
// bounce on failed direct movement
|
||||
self.board.set(
|
||||
self.grid.set(
|
||||
*pos,
|
||||
Tile::Marble {
|
||||
value,
|
||||
|
@ -379,11 +379,11 @@ impl Machine {
|
|||
}
|
||||
_ => continue,
|
||||
}
|
||||
let Some(target_tile) = self.board.get_mut(target_pos) else {
|
||||
let Some(target_tile) = self.grid.get_mut(target_pos) else {
|
||||
continue;
|
||||
};
|
||||
if let Tile::Open(space_type, Claim::ClaimedIndirect) = target_tile {
|
||||
move_to(*space_type, target_pos, new_dir, &mut self.board);
|
||||
move_to(*space_type, target_pos, new_dir, &mut self.grid);
|
||||
if is_button {
|
||||
self.powered.push(front_pos);
|
||||
}
|
||||
|
@ -392,14 +392,14 @@ impl Machine {
|
|||
}
|
||||
|
||||
for pos in claim_positions {
|
||||
if let Some(Tile::Open(_, claim_state)) = self.board.get_mut(pos) {
|
||||
if let Some(Tile::Open(_, claim_state)) = self.grid.get_mut(pos) {
|
||||
*claim_state = Claim::Free;
|
||||
}
|
||||
}
|
||||
|
||||
// remove marbles
|
||||
for &i in removed_marbles.iter().rev() {
|
||||
self.board.set(self.marbles[i], Tile::BLANK);
|
||||
self.grid.set(self.marbles[i], Tile::BLANK);
|
||||
self.marbles.swap_remove(i);
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ impl Machine {
|
|||
let mut i = 0;
|
||||
while i < self.powered.len() {
|
||||
let pos = self.powered[i];
|
||||
let Some(tile) = self.board.get_mut(pos) else {
|
||||
let Some(tile) = self.grid.get_mut(pos) else {
|
||||
unreachable!()
|
||||
};
|
||||
match tile {
|
||||
|
@ -415,7 +415,7 @@ impl Machine {
|
|||
*state = true;
|
||||
for dir in Direction::ALL {
|
||||
let target_pos = dir.step(pos);
|
||||
match self.board.get_mut(target_pos) {
|
||||
match self.grid.get_mut(target_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !state.get_dir(dir) {
|
||||
state.add_dir(dir);
|
||||
|
@ -434,7 +434,7 @@ impl Machine {
|
|||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
grid: self.grid.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ impl Machine {
|
|||
*state = true;
|
||||
for dir in wiretype.directions() {
|
||||
let target_pos = dir.step(pos);
|
||||
match self.board.get_mut(target_pos) {
|
||||
match self.grid.get_mut(target_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !state.get_dir(*dir) {
|
||||
state.add_dir(*dir);
|
||||
|
@ -461,7 +461,7 @@ impl Machine {
|
|||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
grid: self.grid.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
|
@ -473,14 +473,14 @@ impl Machine {
|
|||
continue;
|
||||
}
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
let Some(front_tile) = self.grid.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
if matches!(front_tile, Tile::Wire(_, _) | Tile::Powerable(_, _)) {
|
||||
let pos_a = dir.left().step(pos);
|
||||
let pos_b = dir.right().step(pos);
|
||||
let val_a = self.board.get_or_blank(pos_a).read_value();
|
||||
let val_b = self.board.get_or_blank(pos_b).read_value();
|
||||
let val_a = self.grid.get_or_blank(pos_a).read_value();
|
||||
let val_b = self.grid.get_or_blank(pos_b).read_value();
|
||||
|
||||
let result = match comp {
|
||||
Comparison::LessThan => val_a < val_b,
|
||||
|
@ -489,7 +489,7 @@ impl Machine {
|
|||
Comparison::NotEqual => val_a != val_b,
|
||||
};
|
||||
if result {
|
||||
match self.board.get_mut(front_pos) {
|
||||
match self.grid.get_mut(front_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !state.get_dir(dir) {
|
||||
state.add_dir(dir);
|
||||
|
@ -509,14 +509,14 @@ impl Machine {
|
|||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
grid: self.grid.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
Tile::Powerable(_, _state) => {
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
grid: self.grid.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue