fix(physics): use predicted magnetic gate bounds

Correct the readable 1000:9b69 reconstruction to read DGROUP 07db/07df and name the helper for its predicted-position role. Rust magnetic rectangles now enter only from an old position inside the record and deactivate when the recomputed prediction exits any edge, replacing the prior swept approximation.

Test Plan:
- bash original/tools/test_reconstructed_c.sh
- python3 original/tools/audit_reconstruction.py --require-complete
- cargo test --all-targets
- cargo clippy --all-targets --all-features -- -D warnings
- rumdl check original/C_RECONSTRUCTION_FINAL_AUDIT.md tdkpin-rs/CHANGELOG.md tdkpin-rs/RECONSTRUCTION.md tdkpin-rs/README.md
- git diff --check
This commit is contained in:
2026-08-23 18:25:23 +02:00
parent 8c51094b31
commit 742b8b7981
9 changed files with 66 additions and 22 deletions
+42 -10
View File
@@ -1430,15 +1430,10 @@ impl Game {
if !self.object_active[object_id] {
continue;
}
let predicted = old_position.add(*velocity);
let sweep_min_x = old_position.x.min(predicted.x);
let sweep_max_x = old_position.x.max(predicted.x);
let sweep_min_y = old_position.y.min(predicted.y);
let sweep_max_y = old_position.y.max(predicted.y);
if sweep_max_x < min_x
|| sweep_min_x > max_x
|| sweep_max_y < min_y
|| sweep_min_y > max_y
if old_position.x < min_x
|| old_position.x > max_x
|| old_position.y < min_y
|| old_position.y > max_y
{
continue;
}
@@ -1453,7 +1448,12 @@ impl Game {
.multiply(vertical_factor)
.round_i32()
.wrapping_neg();
if old_position.add(*velocity).y < min_y {
let predicted = old_position.add(*velocity);
if predicted.x < min_x
|| predicted.x > max_x
|| predicted.y < min_y
|| predicted.y > max_y
{
self.object_active[object_id] = false;
}
}
@@ -2944,6 +2944,38 @@ mod tests {
assert_eq!(game.player().score, 1_000);
}
#[test]
fn magnetic_rectangles_use_old_position_for_entry_and_prediction_for_exit() {
let mut game = Game::new_with_seed(1, 7);
game.object_active[153] = true;
let seed_before = game.random.seed();
let mut entering_from_outside = MilliVec { x: 0, y: -3_000 };
game.apply_magnetic_fields(
MilliVec {
x: 15_000,
y: 390_000,
},
&mut entering_from_outside,
);
assert_eq!(entering_from_outside, MilliVec { x: 0, y: -3_000 });
assert_eq!(game.random.seed(), seed_before);
assert!(game.object_active[153]);
let mut exiting_sideways = MilliVec { x: -2_000, y: 0 };
game.apply_magnetic_fields(
MilliVec {
x: 1_000,
y: 350_000,
},
&mut exiting_sideways,
);
assert_eq!(exiting_sideways.x, -1_800);
assert!(!game.object_active[153]);
}
#[test]
fn wheel_holes_accumulate_and_transfer_the_per_player_secondary_score() {
let mut game = Game::new(1);