fix: Hex Wars - Mine-Feld wird Felsen, Kopf außerhalb Blast-Radius

This commit is contained in:
2026-06-28 17:09:35 +02:00
parent 3afffdec03
commit 61bed6236c

View File

@@ -136,22 +136,28 @@ function explodeMine(grid, terrain, row, col, ownerId, oppId, exploded = new Set
let destroyedByOwner = 0; let destroyedByOwner = 0;
let destroyedByOpp = 0; let destroyedByOpp = 0;
const blastCells = []; const blastCells = [];
const chainMines = []; // Nachbar-Minen die ebenfalls zünden const chainMines = [];
// Das Mine-Feld selbst wird auch zu Felsen
grid[row][col] = 0;
terrain[row][col] = T_ROCK;
blastCells.push([row, col]);
// Alle 8 Nachbarn werden zu Felsen — erst Ketten-Minen merken, dann umwandeln
for (const [dr,dc] of DIRS8) { for (const [dr,dc] of DIRS8) {
const r=row+dr, c=col+dc; const r=row+dr, c=col+dc;
if (r<0||r>=GRID||c<0||c>=GRID) continue; if (r<0||r>=GRID||c<0||c>=GRID) continue;
if (terrain[r][c] === T_ROCK) continue; // bereits Felsen, überspringen if (terrain[r][c] === T_ROCK) continue; // schon Felsen
// Merke ob da eine Mine lag (BEVOR wir terrain ändern) // Ketten-Mine merken BEVOR terrain geändert wird
if (terrain[r][c] === T_MINE && !exploded.has(`${r},${c}`)) { if (terrain[r][c] === T_MINE && !exploded.has(`${r},${c}`)) {
chainMines.push([r,c]); chainMines.push([r,c]);
} }
// Punktabzug für besetzte Felder // Punktabzug für besetzte Felder
if (grid[r][c] === ownerId) destroyedByOwner++; if (grid[r][c] === ownerId) destroyedByOwner++;
else if (grid[r][c] === oppId) destroyedByOpp++; else if (grid[r][c] === oppId) destroyedByOpp++;
// Feld wird zu Felsen // Feld wird zu Felsen
grid[r][c] = 0; grid[r][c] = 0;
@@ -159,10 +165,8 @@ function explodeMine(grid, terrain, row, col, ownerId, oppId, exploded = new Set
blastCells.push([r,c]); blastCells.push([r,c]);
} }
// Kettenexplosionen zünden // Kettenexplosionen
for (const [mr,mc] of chainMines) { for (const [mr,mc] of chainMines) {
// terrain[mr][mc] ist jetzt bereits T_ROCK (oben gesetzt),
// aber die Mine war dort — wir zünden sie trotzdem
const chain = explodeMine(grid, terrain, mr, mc, ownerId, oppId, exploded); const chain = explodeMine(grid, terrain, mr, mc, ownerId, oppId, exploded);
destroyedByOwner += chain.destroyedByOwner; destroyedByOwner += chain.destroyedByOwner;
destroyedByOpp += chain.destroyedByOpp; destroyedByOpp += chain.destroyedByOpp;
@@ -363,22 +367,26 @@ router.post('/:id/move', authenticate, (req, res) => {
// Der alte Kopf (myHR, myHC) wird durch explodeMine nicht zerstört (Explosion trifft Nachbarn), // Der alte Kopf (myHR, myHC) wird durch explodeMine nicht zerstört (Explosion trifft Nachbarn),
// also ist er noch vorhanden — Kopf bleibt beim alten Kopf (vor dem Mine-Zug). // also ist er noch vorhanden — Kopf bleibt beim alten Kopf (vor dem Mine-Zug).
// Falls kein alter Kopf bekannt: suche nächstes eigenes Feld neben der Mine. // Falls kein alter Kopf bekannt: suche nächstes eigenes Feld neben der Mine.
if (myHR !== null) { // Kopf nach Explosion: erstes eigenes Feld das AUSSERHALB des 3x3-Radius der Mine liegt
// Alten Kopf wiederherstellen — Mine-Feld selbst ist kein guter Ausgangspunkt // (Mine + 8 Nachbarn sind alle Felsen — der Kopf muss weiter weg sein)
if (game.owner_id === me) newOwnerHead = `${myHR},${myHC}`; let safeHead = null;
else newOppHead = `${myHR},${myHC}`; // Alle eigenen Felder sammeln und nach Entfernung zur Mine sortieren
} else { const ownCells = [];
// Fallback: nächstes eigenes Feld neben der Mine suchen for (let r=0;r<GRID;r++) for (let c=0;c<GRID;c++) {
let fallbackHead = null; if (grid[r][c] === me) {
for (const [dr,dc] of DIRS8) { const outside = Math.abs(r-row)>1 || Math.abs(c-col)>1;
const nr=row+dr, nc=col+dc; if (outside) ownCells.push([r, c, Math.abs(r-row)+Math.abs(c-col)]);
if (nr>=0&&nr<GRID&&nc>=0&&nc<GRID&&grid[nr][nc]===me) { fallbackHead=`${nr},${nc}`; break; }
}
if (fallbackHead) {
if (game.owner_id === me) newOwnerHead = fallbackHead;
else newOppHead = fallbackHead;
} }
} }
// Nächstes eigenes Feld außerhalb des Radius (Manhattan-Distanz minimal)
if (ownCells.length > 0) {
ownCells.sort((a,b) => a[2]-b[2]);
safeHead = `${ownCells[0][0]},${ownCells[0][1]}`;
}
if (safeHead) {
if (game.owner_id === me) newOwnerHead = safeHead;
else newOppHead = safeHead;
}
} }
// ── Mine ins Sichtfeld gekommen: Explosion prüfen ──────────────────────── // ── Mine ins Sichtfeld gekommen: Explosion prüfen ────────────────────────