diff --git a/backend/src/tools/gebietseroberung/routes.js b/backend/src/tools/gebietseroberung/routes.js index ef72d16..74d62ee 100644 --- a/backend/src/tools/gebietseroberung/routes.js +++ b/backend/src/tools/gebietseroberung/routes.js @@ -126,20 +126,49 @@ function calcScore(grid, terrain, playerId) { // ── Minenexplosion: alle 8 Nachbarn der Mine werden zerstört ───────────────── // Gibt zurück: { grid, destroyedByOwner, destroyedByOpp, blastCells } -function explodeMine(grid, terrain, row, col, ownerId, oppId) { +// Kettenexplosion: Mine explodiert, alle 8 Nachbarn werden zu Felsen. +// Wenn ein Nachbar auch eine Mine ist, explodiert diese ebenfalls (rekursiv). +// exploded = Set von bereits gezündeten Minen-Positionen (verhindert Endlosschleife) +function explodeMine(grid, terrain, row, col, ownerId, oppId, exploded = new Set()) { + const key = `${row},${col}`; + if (exploded.has(key)) return { destroyedByOwner:0, destroyedByOpp:0, blastCells:[] }; + exploded.add(key); + let destroyedByOwner = 0; let destroyedByOpp = 0; - const blastCells = []; + const blastCells = []; + const chainMines = []; // Nachbar-Minen die ebenfalls zünden for (const [dr,dc] of DIRS8) { const r=row+dr, c=col+dc; if (r<0||r>=GRID||c<0||c>=GRID) continue; - const cell = grid[r][c]; - if (cell === ownerId) { destroyedByOwner++; grid[r][c] = 0; blastCells.push([r,c]); } - else if (cell === oppId) { destroyedByOpp++; grid[r][c] = 0; blastCells.push([r,c]); } - else if (cell === 0 && terrain[r][c] !== T_ROCK) { blastCells.push([r,c]); } + if (terrain[r][c] === T_ROCK) continue; // bereits Felsen, überspringen + + // Merke ob da eine Mine lag (BEVOR wir terrain ändern) + 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++; + + // Feld wird zu Felsen + grid[r][c] = 0; + terrain[r][c] = T_ROCK; + blastCells.push([r,c]); } - // Mine selbst wird neutral (bereits besetzt durch Spieler, bleibt als besetztes Mine-Feld) + + // Kettenexplosionen zünden + 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; + blastCells.push(...chain.blastCells); + } + return { destroyedByOwner, destroyedByOpp, blastCells }; } diff --git a/frontend/src/tools/gebietseroberung.jsx b/frontend/src/tools/gebietseroberung.jsx index 6828d9e..025ba01 100644 --- a/frontend/src/tools/gebietseroberung.jsx +++ b/frontend/src/tools/gebietseroberung.jsx @@ -48,7 +48,7 @@ function HelpModal({ onClose }) {