Fix simultaneous defense sweep
Refactor Eternal Domination defense to ensure guards move only in a single, simultaneous sweep without randomManifestation. Introduces a deterministic, border-patchwork approach that shifts existing guards along predefined paths, removes ad-hoc scanning, and preserves guard count while updating movement logic to reflect a coordinated defense. X-Lovable-Edit-ID: edt-cbb19a37-58ea-4c8f-80e1-5d999d4db6dd
This commit is contained in:
commit
abbfb79cea
1 changed files with 9 additions and 29 deletions
|
|
@ -282,34 +282,14 @@ const defendAttack = (guards: Set<string>, attack: Position): {
|
|||
shiftBorderToFillGap(newGuards, movements, currentGap);
|
||||
}
|
||||
|
||||
// STEP 3: Check if we need a second chain (Figure 10 shows two chains)
|
||||
// This happens when the attack disrupts multiple domination lines
|
||||
// NOTE: The paper's strategy restores the original configuration via the border "patchwork"
|
||||
// (complementary paths) rather than ad-hoc re-domination fixes.
|
||||
//
|
||||
// The previous implementation included an extra "scan for undominated vertices and move a nearby guard"
|
||||
// step, which can look like guards "manifest" and is not part of the Figure 10 defense.
|
||||
|
||||
// Find interior positions that are now undominated and need filling
|
||||
for (let x = 1; x < COLS - 1; x++) {
|
||||
for (let y = 2; y < ROWS - 2; y++) {
|
||||
if (!isDominated(x, y, newGuards)) {
|
||||
// Need to get a guard here
|
||||
const nbs = getHexNeighbors(x, y);
|
||||
const nearbyGuard = nbs.find(n => newGuards.has(posKey(n)) && isInterior(n.x, n.y));
|
||||
|
||||
if (nearbyGuard) {
|
||||
newGuards.delete(posKey(nearbyGuard));
|
||||
newGuards.add(posKey({ x, y }));
|
||||
movements.push({ from: nearbyGuard, to: { x, y }, type: 'interior' });
|
||||
} else {
|
||||
// Use border guard
|
||||
const borderGuard = nbs.find(n => newGuards.has(posKey(n)) && isBorder(n.x, n.y));
|
||||
if (borderGuard) {
|
||||
newGuards.delete(posKey(borderGuard));
|
||||
newGuards.add(posKey({ x, y }));
|
||||
movements.push({ from: borderGuard, to: { x, y }, type: 'toInterior' });
|
||||
shiftBorderToFillGap(newGuards, movements, borderGuard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Safety: guards are never created/destroyed—only moved.
|
||||
if (newGuards.size !== guards.size) return null;
|
||||
|
||||
return { newGuards, movements };
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue