add sub-tick debugging, add direction information to state of powerable tiles
This commit is contained in:
parent
181f76a341
commit
d3a3471fcb
8 changed files with 176 additions and 65 deletions
|
@ -17,6 +17,14 @@ pub struct Machine {
|
|||
input_index: usize,
|
||||
output: Vec<u8>,
|
||||
steps: usize,
|
||||
pub subtick_index: usize,
|
||||
pub debug_subticks: Vec<DebugSubTick>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DebugSubTick {
|
||||
pub board: Board,
|
||||
pub pos: Option<Pos>,
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
|
@ -29,6 +37,8 @@ impl Machine {
|
|||
input_index: 0,
|
||||
output: Vec::new(),
|
||||
steps: 0,
|
||||
subtick_index: 0,
|
||||
debug_subticks: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +47,8 @@ impl Machine {
|
|||
self.input_index = 0;
|
||||
self.output.clear();
|
||||
self.powered.clear();
|
||||
self.debug_subticks.clear();
|
||||
self.subtick_index = 0;
|
||||
}
|
||||
|
||||
pub fn set_board(&mut self, board: Board) {
|
||||
|
@ -97,6 +109,15 @@ impl Machine {
|
|||
|
||||
pub fn step(&mut self) {
|
||||
self.steps += 1;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
self.subtick_index = 0;
|
||||
self.debug_subticks.clear();
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
pos: None,
|
||||
});
|
||||
}
|
||||
|
||||
let old_marbles = self.marbles.len();
|
||||
|
||||
|
@ -104,27 +125,24 @@ impl Machine {
|
|||
// activate all powered machines
|
||||
for &pos in &self.powered {
|
||||
match self.board.get_mut(pos) {
|
||||
Some(Tile::Powerable(machine, state)) => {
|
||||
*state = false;
|
||||
Some(Tile::Powerable(PTile::Comparator(_), board_power_state)) => {
|
||||
// already handled at the power propagation stage (end of sim step)
|
||||
*board_power_state = Power::OFF;
|
||||
}
|
||||
Some(Tile::Powerable(machine, board_power_state)) => {
|
||||
let state = *board_power_state;
|
||||
*board_power_state = Power::OFF;
|
||||
let machine = *machine;
|
||||
for dir in Direction::ALL {
|
||||
let front_pos = dir.step(pos);
|
||||
let source_pos = dir.opposite().step(pos);
|
||||
match self.board.get(source_pos) {
|
||||
Some(Tile::Wire(wiretype, true)) => {
|
||||
if !wiretype.has_output(dir) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Some(Tile::Button(true)) => (),
|
||||
_ => continue,
|
||||
if !state.get_dir(dir) {
|
||||
continue;
|
||||
}
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
// `machine`` is being powered, in direction `dir``
|
||||
// `machine` is being powered, in direction `dir`
|
||||
match machine {
|
||||
PTile::Comparator(_) => (), // handled at the power propagation stage (end of step)
|
||||
PTile::Math(op) => {
|
||||
if front_tile.is_blank() {
|
||||
let pos_a = dir.left().step(pos);
|
||||
|
@ -169,24 +187,16 @@ impl Machine {
|
|||
_ => (),
|
||||
};
|
||||
}
|
||||
PTile::Comparator(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Tile::Button(_state)) => (),
|
||||
Some(Tile::Wire(_, _state)) => (),
|
||||
_ => unreachable!(),
|
||||
Some(Tile::Button(state) | Tile::Wire(_, state)) => {
|
||||
*state = false;
|
||||
}
|
||||
_ => unreachable!("non-powerable tile at {pos:?} in self.powered"),
|
||||
};
|
||||
}
|
||||
|
||||
// old wires have to be reset after machine processing,
|
||||
// so they can figure out which directions they are powered from
|
||||
for &p in &self.powered {
|
||||
match self.board.get_mut(p) {
|
||||
Some(Tile::Button(state)) => *state = false,
|
||||
Some(Tile::Wire(_, state)) => *state = false,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
self.powered.clear();
|
||||
|
||||
if self.marbles.is_empty() {
|
||||
|
@ -199,7 +209,6 @@ impl Machine {
|
|||
One(Direction),
|
||||
Multiple,
|
||||
}
|
||||
|
||||
// #### find all direct bounces ####
|
||||
let mut will_reverse_direction = vec![false; self.marbles.len()];
|
||||
// todo store in tile to remove search through self.marbles
|
||||
|
@ -408,8 +417,8 @@ impl Machine {
|
|||
let target_pos = dir.step(pos);
|
||||
match self.board.get_mut(target_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !*state {
|
||||
*state = true;
|
||||
if !state.get_dir(dir) {
|
||||
state.add_dir(dir);
|
||||
self.powered.push(target_pos);
|
||||
}
|
||||
}
|
||||
|
@ -423,6 +432,11 @@ impl Machine {
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
Tile::Wire(wiretype, state) => {
|
||||
*state = true;
|
||||
|
@ -430,8 +444,8 @@ impl Machine {
|
|||
let target_pos = dir.step(pos);
|
||||
match self.board.get_mut(target_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !*state {
|
||||
*state = true;
|
||||
if !state.get_dir(*dir) {
|
||||
state.add_dir(*dir);
|
||||
self.powered.push(target_pos);
|
||||
}
|
||||
}
|
||||
|
@ -445,22 +459,20 @@ impl Machine {
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
Tile::Powerable(PTile::Comparator(comp), state) => {
|
||||
*state = true;
|
||||
let comp = *comp;
|
||||
let state = *state;
|
||||
for dir in Direction::ALL {
|
||||
let front_pos = dir.step(pos);
|
||||
let source_pos = dir.opposite().step(pos);
|
||||
match self.board.get(source_pos) {
|
||||
Some(Tile::Wire(wiretype, true)) => {
|
||||
if !wiretype.has_output(dir) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Some(Tile::Button(true)) => (),
|
||||
_ => continue,
|
||||
if !state.get_dir(dir) {
|
||||
continue;
|
||||
}
|
||||
let front_pos = dir.step(pos);
|
||||
let Some(front_tile) = self.board.get_mut(front_pos) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -477,13 +489,37 @@ impl Machine {
|
|||
Comparison::NotEqual => val_a != val_b,
|
||||
};
|
||||
if result {
|
||||
self.powered.push(front_pos);
|
||||
match self.board.get_mut(front_pos) {
|
||||
Some(Tile::Powerable(_, state)) => {
|
||||
if !state.get_dir(dir) {
|
||||
state.add_dir(dir);
|
||||
self.powered.push(front_pos);
|
||||
}
|
||||
}
|
||||
Some(Tile::Wire(_, state)) => {
|
||||
if !*state {
|
||||
*state = true;
|
||||
self.powered.push(front_pos);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
Tile::Powerable(_, _state) => {
|
||||
#[cfg(debug_assertions)]
|
||||
self.debug_subticks.push(DebugSubTick {
|
||||
board: self.board.clone(),
|
||||
pos: Some(pos),
|
||||
});
|
||||
}
|
||||
// state may be false if it was powered by a machine in earlier step
|
||||
Tile::Powerable(_, state) => *state = true,
|
||||
_ => {
|
||||
dbg!(tile);
|
||||
unreachable!()
|
||||
|
@ -491,5 +527,9 @@ impl Machine {
|
|||
}
|
||||
i += 1;
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
self.subtick_index = self.debug_subticks.len() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue