From f2c7764143639836765deff875d4a5c2d4e160fa Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sat, 14 Dec 2024 23:42:17 +0100 Subject: [PATCH] prevent marbles from bouncing during the same step that they are created --- src/marble_engine.rs | 46 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/marble_engine.rs b/src/marble_engine.rs index f99ddd2..422301e 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -179,25 +179,6 @@ impl Machine { }; } - for &(pos, _val, _dir) in &new_marbles { - let Some(Tile::Open(OpenTile::Blank, claim)) = self.board.get_mut(pos) else { - unreachable!() - }; - *claim = match claim { - Claim::Free => Claim::Claimed, - Claim::Claimed | Claim::Blocked => Claim::Blocked, - _ => unreachable!(), - } - } - // 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::Claimed)) = self.board.get_mut(pos) else { - continue; - }; - self.board.set(pos, Tile::Marble { value, dir }); - self.marbles.push(pos); - } - // 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 { @@ -220,7 +201,7 @@ impl Machine { Multiple, } - // find all direct bounces + // #### find all direct bounces #### let mut will_reverse_direction = vec![false; self.marbles.len()]; // todo store in tile to remove search through self.marbles let mut influenced_direction = vec![DirInfluence::None; self.marbles.len()]; @@ -261,7 +242,7 @@ impl Machine { _ => (), } } - // apply all direct bounces + // #### apply all direct bounces #### for (i, &pos) in self.marbles.iter().enumerate() { let Some(Tile::Marble { value: _, dir }) = self.board.get_mut(pos) else { unreachable!() @@ -273,6 +254,29 @@ impl Machine { } } + // #### new marbles #### + // 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 { + unreachable!() + }; + *claim = match claim { + Claim::Free => Claim::Claimed, + Claim::Claimed | Claim::Blocked => Claim::Blocked, + _ => unreachable!(), + } + } + // 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::Claimed)) = self.board.get_mut(pos) else { + continue; + }; + self.board.set(pos, Tile::Marble { value, dir }); + self.marbles.push(pos); + } + + // #### movement #### let mut claim_positions = Vec::new(); // mark claims to figure out what spaces can be moved to for &pos in &self.marbles[..old_marbles] {