fix(puzzle): an object steps once per movement phase; negated conversion is settled per object
Bug 1 (modules 08-10): a YOU object pulled by an earlier mover took a second step of its own. Level movement now keeps the ids that stepped in a committed plan this phase; such a YOU object starts no move, and Planner try_move answers no for it. Regression: test_08x_pulled_you_moves_once (Module 8 Expansion Drop). Bug 2 (modules 09-10): convert honoured negation only per rule, so ALL IS ROCK beat BABA IS NOT ROCK. A target Y is now skipped for an object if any active negated rule IS NOT Y names it. Module 9 and 10 references (and their drop solutions) now carry ALL, the Module 7 Expansion Drop. Regression: test_09_negated_conversion_beats_group. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
638549161f
commit
8467c7929e
28 files changed
+293
-32
No files matched your search
@@ -5,6 +5,8 @@
|
||||
//! A move (Module 8) is planned for each `YOU` object, then committed; the rules are
|
||||
//! reparsed once, after all of them.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use super::grid::{Board, Kind, LevelDef, ObjectId};
|
||||
use super::movement::{Dir, Plan, Planner, Response};
|
||||
use super::parse::{parse, Rule};
|
||||
@@ -86,6 +88,10 @@ impl Level {
|
||||
/// move one at a time, the one furthest ahead in `dir` first (oldest first on a
|
||||
/// tie); each one's move is planned in full, then committed, before the next is
|
||||
/// planned. Every move uses the rules in force before the first.
|
||||
///
|
||||
/// An object steps at most once in a movement phase. A `YOU` object that an
|
||||
/// earlier move already carried along (pushed, or moved by any other response)
|
||||
/// doesn't start a move of its own, and no later move can make it step again.
|
||||
pub fn move_you(&mut self, dir: Dir) {
|
||||
let (dx, dy) = dir.delta();
|
||||
let mut you: Vec<_> = self
|
||||
@@ -95,14 +101,19 @@ impl Level {
|
||||
.map(|o| (-(o.x * dx + o.y * dy), o.id))
|
||||
.collect();
|
||||
you.sort();
|
||||
let mut stepped = BTreeSet::new();
|
||||
for (_, id) in you {
|
||||
if self.board.find(id).is_none() {
|
||||
continue; // destroyed by an earlier move
|
||||
}
|
||||
let mut planner = Planner::new(self, dir);
|
||||
if stepped.contains(&id) {
|
||||
continue; // already moved, by an earlier move
|
||||
}
|
||||
let mut planner = Planner::new(self, dir, &stepped);
|
||||
if planner.try_move(id) {
|
||||
let plan = planner.into_plan();
|
||||
self.commit(&plan, dir);
|
||||
stepped.extend(plan.moving.difference(&plan.destroyed));
|
||||
}
|
||||
}
|
||||
self.reparse();
|
||||
|
||||
Reference in new issue
Block a user