From 61bed6236cbf676b20ccb001aad020a67cee2327 Mon Sep 17 00:00:00 2001 From: Dicken Date: Sun, 28 Jun 2026 17:09:35 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Hex=20Wars=20-=20Mine-Feld=20wird=20Fels?= =?UTF-8?q?en,=20Kopf=20au=C3=9Ferhalb=20Blast-Radius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/tools/gebietseroberung/routes.js | 54 +++++++++++--------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/backend/src/tools/gebietseroberung/routes.js b/backend/src/tools/gebietseroberung/routes.js index 74d62ee..b664d26 100644 --- a/backend/src/tools/gebietseroberung/routes.js +++ b/backend/src/tools/gebietseroberung/routes.js @@ -136,22 +136,28 @@ function explodeMine(grid, terrain, row, col, ownerId, oppId, exploded = new Set let destroyedByOwner = 0; let destroyedByOpp = 0; - const blastCells = []; - const chainMines = []; // Nachbar-Minen die ebenfalls zünden + const blastCells = []; + 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) { const r=row+dr, c=col+dc; 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}`)) { chainMines.push([r,c]); } // Punktabzug für besetzte Felder - if (grid[r][c] === ownerId) destroyedByOwner++; - else if (grid[r][c] === oppId) destroyedByOpp++; + if (grid[r][c] === ownerId) destroyedByOwner++; + else if (grid[r][c] === oppId) destroyedByOpp++; // Feld wird zu Felsen grid[r][c] = 0; @@ -159,10 +165,8 @@ function explodeMine(grid, terrain, row, col, ownerId, oppId, exploded = new Set blastCells.push([r,c]); } - // Kettenexplosionen zünden + // Kettenexplosionen 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); destroyedByOwner += chain.destroyedByOwner; 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), // 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. - if (myHR !== null) { - // Alten Kopf wiederherstellen — Mine-Feld selbst ist kein guter Ausgangspunkt - if (game.owner_id === me) newOwnerHead = `${myHR},${myHC}`; - else newOppHead = `${myHR},${myHC}`; - } else { - // Fallback: nächstes eigenes Feld neben der Mine suchen - let fallbackHead = null; - for (const [dr,dc] of DIRS8) { - const nr=row+dr, nc=col+dc; - if (nr>=0&&nr=0&&nc1 || Math.abs(c-col)>1; + if (outside) ownCells.push([r, c, Math.abs(r-row)+Math.abs(c-col)]); } } + // 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 ────────────────────────