export class GoCounting {
constructor(board) {
this.board = board.split('\n').map(row => [...row]);
this.rows = this.board.length;
this.cols = this.board[0] ? this.board[0].length : 0;
}
getTerritory(x, y) {
if (y < 0 || y >= this.rows || x < 0 || x >= this.cols) return { owner: 'NONE', territory: [] };
if (this.board[y][x] !== ' ') return { owner: 'NONE', territory: [] };
const territory = [];
const visited = new Set();
const queue = [[x, y]];
const stoneColors = new Set();
while (queue.length > 0) {
const [cx, cy] = queue.shift();
const key = `${cx},${cy}`;
if (visited.has(key)) continue;
visited.add(key);
if (this.board[cy][cx] === ' ') {
territory.push([cx, cy]);
[[cx + 1, cy], [cx - 1, cy], [cx, cy + 1], [cx, cy - 1]].forEach(([nx, ny]) => {
if (nx >= 0 && nx < this.cols && ny >= 0 && ny < this.rows) queue.push([nx, ny]);
});
} else {
stoneColors.add(this.board[cy][cx]);
}
}
let owner = 'NONE';
if (stoneColors.size === 1) {
const color = stoneColors.values().next().value;
owner = color === 'B' ? 'BLACK' : 'WHITE';
}
return { owner, territory: territory.sort((a, b) => a[0] - b[0] || a[1] - b[1]) };
}
getTerritories() {
const result = { TERRITORY_BLACK: [], TERRITORY_WHITE: [], TERRITORY_NONE: [] };
const visited = new Set();
for (let y = 0; y < this.rows; y++) {
for (let x = 0; x < this.cols; x++) {
if (this.board[y][x] === ' ' && !visited.has(`${x},${y}`)) {
const { owner, territory } = this.getTerritory(x, y);
territory.forEach(([tx, ty]) => visited.add(`${tx},${ty}`));
result[`TERRITORY_${owner}`].push(...territory);
}
}
}
return result;
}
}