const PLAYERS = [ { symbol: 'X', color: '#FF4757', label: 'Player 1' }, { symbol: 'Circle', color: '#2ED7F8', label: 'Player 2' }, { symbol: 'Triangle',color: '#2ECC71', label: 'Player 3' }, { symbol: 'Square', color: '#FFD32A', label: 'Player 4' }, ]; function getPlayer(sym) { return PLAYERS.find(p => p.symbol === sym) || PLAYERS[0]; } function makeBoard(size) { const hLines = Array.from({ length: size }, () => Array(size - 1).fill(null)); const vLines = Array.from({ length: size - 1 }, () => Array(size).fill(null)); const boxes = Array.from({ length: size - 1 }, () => Array(size - 1).fill(null)); return { size, hLines, vLines, boxes }; } function getCompletedBoxes(hLines, vLines, boxes, row, col, isHorizontal) { const size = hLines.length; const completed = []; if (isHorizontal) { if (row > 0 && vLines[row-1][col] && vLines[row-1][col+1] && hLines[row-1][col]) { completed.push([row-1, col]); } if (row < size - 1 && vLines[row][col] && vLines[row][col+1] && hLines[row+1][col]) { completed.push([row, col]); } } else { if (col > 0 && hLines[row][col-1] && hLines[row+1][col-1] && vLines[row][col-1]) { completed.push([row, col-1]); } if (col < size - 1 && hLines[row][col] && hLines[row+1][col] && vLines[row][col+1]) { completed.push([row, col]); } } return completed.filter(([br, bc]) => !boxes[br][bc]); } function isGameOver(boxes) { return boxes.every(row => row.every(cell => cell !== null)); } function getWinner(boxes, players) { const counts = {}; players.forEach(p => counts[p.symbol] = 0); for (let r = 0; r < boxes.length; r++) for (let c = 0; c < boxes[r].length; c++) if (boxes[r][c]) counts[boxes[r][c]]++; const max = Math.max(...Object.values(counts)); const tops = Object.keys(counts).filter(k => counts[k] === max); if (tops.length === 1) return tops[0]; return null; } function getScores(boxes) { const counts = {}; for (let r = 0; r < boxes.length; r++) for (let c = 0; c < boxes[r].length; c++) if (boxes[r][c]) counts[boxes[r][c]] = (counts[boxes[r][c]] || 0) + 1; return counts; } function makeSVG(symbol, color, size) { const ns = 'http://www.w3.org/2000/svg'; const svg = document.createElementNS(ns, 'svg'); svg.setAttribute('viewBox', '0 0 48 48'); svg.setAttribute('width', size); svg.setAttribute('height', size); svg.innerHTML = makeSVGPath(symbol, color); return svg; } function makeSVGString(symbol, color, size) { return `${makeSVGPath(symbol, color)}`; } function makeSVGPath(symbol, color) { switch (symbol) { case 'X': return ` `; case 'Circle': return ``; case 'Triangle': return ``; case 'Square': return ``; default: return ''; } } function escapeHtml(str) { const d = document.createElement('div'); d.appendChild(document.createTextNode(str)); return d.innerHTML; }