Implement solid territory supply system

This commit is contained in:
sokol
2026-02-21 17:59:41 +03:00
parent 7035f0457b
commit 254287c124
3 changed files with 89 additions and 15 deletions

View File

@@ -513,14 +513,16 @@ class GameUI {
instruction.textContent = 'Select a cell with dice to move'; instruction.textContent = 'Select a cell with dice to move';
} }
// Update selected cell info // Update selected cell info - always show with placeholder if nothing selected
const cellInfo = document.getElementById('selected-cell-info'); const cellInfo = document.getElementById('selected-cell-info');
if (this.selectedCell) {
cellInfo.style.display = 'block'; cellInfo.style.display = 'block';
if (this.selectedCell) {
document.getElementById('cell-strength').textContent = this.selectedCell.getStrength(); document.getElementById('cell-strength').textContent = this.selectedCell.getStrength();
document.getElementById('cell-dice').textContent = this.selectedCell.dice.length; document.getElementById('cell-dice').textContent = this.selectedCell.dice.length;
} else { } else {
cellInfo.style.display = 'none'; document.getElementById('cell-strength').textContent = '-';
document.getElementById('cell-dice').textContent = '-';
} }
// Update buttons // Update buttons

View File

@@ -187,17 +187,53 @@ class HexMap {
} }
/** /**
* Calculate supply for a player: S = sum of all owned cells * Calculate supply for a player: S = size of largest solid (connected) territory
* A solid territory is a connected region of player's cells
*/ */
calculateSupply(playerId) { calculateSupply(playerId) {
const playerCells = this.getPlayerCells(playerId); const playerCells = this.getPlayerCells(playerId);
let supply = 0; if (playerCells.length === 0) return 0;
// Build adjacency map for player cells
const cellMap = new Map();
for (const cell of playerCells) { for (const cell of playerCells) {
supply += 1; // Each owned cell gives +1 supply cellMap.set(this.getKey(cell.q, cell.r), cell);
} }
return supply; // Find connected components using BFS
const visited = new Set();
let maxTerritory = 0;
for (const cell of playerCells) {
const key = this.getKey(cell.q, cell.r);
if (visited.has(key)) continue;
// BFS to find size of this territory
let territorySize = 0;
const queue = [cell];
visited.add(key);
while (queue.length > 0) {
const current = queue.shift();
territorySize++;
// Get all neighbors that are also player cells
const neighbors = this.getNeighbors(current.q, current.r);
for (const neighbor of neighbors) {
if (neighbor.getOwner() === playerId) {
const nKey = this.getKey(neighbor.q, neighbor.r);
if (!visited.has(nKey)) {
visited.add(nKey);
queue.push(neighbor);
}
}
}
}
maxTerritory = Math.max(maxTerritory, territorySize);
}
return maxTerritory;
} }
/** /**

View File

@@ -187,17 +187,53 @@ class HexMap {
} }
/** /**
* Calculate supply for a player: S = sum of all owned cells * Calculate supply for a player: S = size of largest solid (connected) territory
* A solid territory is a connected region of player's cells
*/ */
calculateSupply(playerId) { calculateSupply(playerId) {
const playerCells = this.getPlayerCells(playerId); const playerCells = this.getPlayerCells(playerId);
let supply = 0; if (playerCells.length === 0) return 0;
// Build adjacency map for player cells
const cellMap = new Map();
for (const cell of playerCells) { for (const cell of playerCells) {
supply += 1; // Each owned cell gives +1 supply cellMap.set(this.getKey(cell.q, cell.r), cell);
} }
return supply; // Find connected components using BFS
const visited = new Set();
let maxTerritory = 0;
for (const cell of playerCells) {
const key = this.getKey(cell.q, cell.r);
if (visited.has(key)) continue;
// BFS to find size of this territory
let territorySize = 0;
const queue = [cell];
visited.add(key);
while (queue.length > 0) {
const current = queue.shift();
territorySize++;
// Get all neighbors that are also player cells
const neighbors = this.getNeighbors(current.q, current.r);
for (const neighbor of neighbors) {
if (neighbor.getOwner() === playerId) {
const nKey = this.getKey(neighbor.q, neighbor.r);
if (!visited.has(nKey)) {
visited.add(nKey);
queue.push(neighbor);
}
}
}
}
maxTerritory = Math.max(maxTerritory, territorySize);
}
return maxTerritory;
} }
/** /**