fix input being consumed even when marble creation is blocked; made multiple simultaneous inputs use the same value

This commit is contained in:
Crispy 2025-04-20 20:35:22 +02:00
parent f0b878e93d
commit 80ab3b676e
4 changed files with 33 additions and 11 deletions

View file

@ -21,7 +21,7 @@ pub struct Machine {
// used across steps
powered: Vec<Pos>,
// used within steps
new_marbles: Vec<(Pos, MarbleValue, Direction)>,
new_marbles: Vec<(Pos, MarbleValue, Direction, bool)>,
influenced_direction: Vec<(bool, DirInfluence)>,
claim_positions: Vec<Pos>,
removed_marbles: Vec<usize>,
@ -216,20 +216,19 @@ impl Machine {
MathOp::Div => val_a.checked_div(val_b).unwrap_or_default(),
MathOp::Rem => val_a.checked_rem(val_b).unwrap_or_default(),
};
self.new_marbles.push((front_pos, value, dir));
self.new_marbles.push((front_pos, value, dir, false));
}
}
PTile::IO => {
if front_tile == &Tile::BLANK && self.input_index < self.input.len()
{
let value = self.input[self.input_index] as MarbleValue;
self.input_index += 1;
self.new_marbles.push((front_pos, value, dir));
self.new_marbles.push((front_pos, value, dir, true));
}
}
PTile::Silo => {
if front_tile == &Tile::BLANK {
self.new_marbles.push((front_pos, 0, dir));
self.new_marbles.push((front_pos, 0, dir, false));
}
}
PTile::Flipper => {
@ -321,9 +320,9 @@ impl Machine {
#[cfg_attr(feature = "inline_less", inline(never), no_mangle)]
fn step_prepare_creating_marbles(&mut self) {
// #### new marbles ####
// self.claim_positions.clear(); // already drained
// prepare creating the new marbles
for &(pos, _val, _dir) in &self.new_marbles {
self.claim_positions.clear(); // already drained
// prepare creating the new marbles
for &(pos, _val, _dir, _is_input) in &self.new_marbles {
let Some(Tile::Open(OpenTile::Blank, claim)) = self.grid.get_mut(pos) else {
unreachable!()
};
@ -336,15 +335,20 @@ impl Machine {
#[cfg_attr(feature = "inline_less", inline(never), no_mangle)]
fn step_create_marbles(&mut self) {
// create new marbles
let mut advance_input = false;
// new marbles are past old_marbles index, so will not move this step
for (pos, value, dir) in self.new_marbles.drain(..) {
for (pos, value, dir, is_input) in self.new_marbles.drain(..) {
let Some(Tile::Open(OpenTile::Blank, Claim::ClaimedIndirect)) = self.grid.get_mut(pos)
else {
continue;
};
advance_input |= is_input;
self.grid.set(pos, Tile::Marble { value, dir });
self.marbles.push(pos);
}
if advance_input {
self.input_index += 1;
}
}
#[cfg_attr(feature = "inline_less", inline(never), no_mangle)]