diff --git a/src/lib/components/Board.svelte b/src/lib/components/Board.svelte index 9f913fd..9dcabea 100644 --- a/src/lib/components/Board.svelte +++ b/src/lib/components/Board.svelte @@ -2,6 +2,12 @@ import { untrack } from 'svelte'; import JGO from 'jgoboard'; + interface TerritoryData { + territory: Array>; + blackTerritory: number; + whiteTerritory: number; + } + interface Props { boardSize?: number; gameState?: any; @@ -9,6 +15,7 @@ onPass?: () => void; interactive?: boolean; currentTurn?: 'black' | 'white'; + territoryData?: TerritoryData | null; } let { @@ -17,7 +24,8 @@ onMove = () => {}, onPass = () => {}, interactive = true, - currentTurn = 'black' + currentTurn = 'black', + territoryData = null }: Props = $props(); let boardElement: HTMLDivElement; @@ -444,7 +452,33 @@ {/if}
-
+
+
+ {#if territoryData && territoryData.territory} + {@const padding = gridSize * 0.8} + {@const margin = gridSize * 0.8} + {@const markerSize = gridSize * 0.5} + {@const boardOffset = padding + margin + markerSize} +
+ {#each territoryData.territory as row, y} + {#each row as cell, x} + {#if cell === 'black' || cell === 'white'} +
+ {/if} + {/each} + {/each} +
+ {/if} +
{#if interactive && isReady} @@ -478,6 +512,11 @@ justify-content: center; } + .board-with-overlay { + position: relative; + display: inline-block; + } + .jgoboard { box-shadow: 0 8px 24px rgba(90, 122, 144, 0.15); display: block; @@ -544,4 +583,29 @@ visibility: hidden; height: 0; } + + .territory-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; + } + + .territory-marker { + position: absolute; + border-radius: 50%; + transform: translate(-50%, -50%); + } + + .territory-marker.black { + background: rgba(20, 20, 20, 0.7); + box-shadow: 0 0 2px rgba(0, 0, 0, 0.5); + } + + .territory-marker.white { + background: rgba(255, 255, 255, 0.85); + box-shadow: 0 0 2px rgba(0, 0, 0, 0.3); + } diff --git a/src/lib/server/board-svg.ts b/src/lib/server/board-svg.ts index bed0eac..1a3e9ce 100644 --- a/src/lib/server/board-svg.ts +++ b/src/lib/server/board-svg.ts @@ -7,19 +7,117 @@ export interface BoardSvgOptions { padding?: number; showLastMove?: boolean; backgroundColor?: string; + showTerritory?: boolean; +} + +export interface TerritoryMap { + territory: Array>; + blackTerritory: number; + whiteTerritory: number; + blackCaptures: number; + whiteCaptures: number; +} + +/** + * Calculate territory for each empty intersection using flood fill. + * An empty region belongs to a player if it's completely surrounded by their stones. + */ +export function calculateTerritory( + boardState: Array>, + boardSize: number +): TerritoryMap { + const territory: Array> = Array.from( + { length: boardSize }, + () => Array.from({ length: boardSize }, () => null) + ); + + const visited: Array> = Array.from( + { length: boardSize }, + () => Array.from({ length: boardSize }, () => false) + ); + + let blackTerritory = 0; + let whiteTerritory = 0; + + // Flood fill to find connected empty regions + function floodFill(startY: number, startX: number): { points: Array<[number, number]>; owner: 'black' | 'white' | 'neutral' } { + const points: Array<[number, number]> = []; + const stack: Array<[number, number]> = [[startY, startX]]; + let touchesBlack = false; + let touchesWhite = false; + + while (stack.length > 0) { + const [y, x] = stack.pop()!; + + if (y < 0 || y >= boardSize || x < 0 || x >= boardSize) continue; + if (visited[y][x]) continue; + + const cell = boardState[y][x]; + + if (cell === 'black') { + touchesBlack = true; + continue; + } + if (cell === 'white') { + touchesWhite = true; + continue; + } + + // Empty intersection + visited[y][x] = true; + points.push([y, x]); + + // Add neighbors + stack.push([y - 1, x], [y + 1, x], [y, x - 1], [y, x + 1]); + } + + let owner: 'black' | 'white' | 'neutral'; + if (touchesBlack && !touchesWhite) { + owner = 'black'; + } else if (touchesWhite && !touchesBlack) { + owner = 'white'; + } else { + owner = 'neutral'; + } + + return { points, owner }; + } + + // Find all empty regions + for (let y = 0; y < boardSize; y++) { + for (let x = 0; x < boardSize; x++) { + if (!visited[y][x] && boardState[y][x] === null) { + const { points, owner } = floodFill(y, x); + for (const [py, px] of points) { + territory[py][px] = owner; + if (owner === 'black') blackTerritory++; + else if (owner === 'white') whiteTerritory++; + } + } + } + } + + return { + territory, + blackTerritory, + whiteTerritory, + blackCaptures: 0, // Would need to track captures during game + whiteCaptures: 0, + }; } export function generateBoardSvg( boardSize: number, boardState: Array>, lastMove: { x: number; y: number } | null = null, - options: BoardSvgOptions = {} + options: BoardSvgOptions = {}, + territoryMap?: TerritoryMap ): string { const { size: svgSize = 200, padding = 10, showLastMove = true, - backgroundColor = '#DEB887', + showTerritory = false, } = options; const innerSize = svgSize - padding * 2; @@ -69,6 +167,23 @@ export function generateBoardSvg( svg += ``; } + // Territory markers (small squares at intersections) + if (showTerritory && territoryMap) { + const markerSize = step * 0.25; + for (let y = 0; y < boardSize; y++) { + for (let x = 0; x < boardSize; x++) { + const owner = territoryMap.territory[y]?.[x]; + if (owner && owner !== 'neutral' && boardState[y]?.[x] === null) { + const px = padding + x * step; + const py = padding + y * step; + const color = owner === 'black' ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.7)'; + const stroke = owner === 'black' ? 'none' : 'rgba(0, 0, 0, 0.3)'; + svg += ``; + } + } + } + } + // Stones for (let y = 0; y < boardState.length; y++) { for (let x = 0; x < (boardState[y]?.length || 0); x++) { diff --git a/src/routes/api/games/[id]/score/+server.ts b/src/routes/api/games/[id]/score/+server.ts index 2c6c0de..51d5d39 100644 --- a/src/routes/api/games/[id]/score/+server.ts +++ b/src/routes/api/games/[id]/score/+server.ts @@ -4,6 +4,7 @@ import { getSession, getAgent } from '$lib/server/auth'; import { getDb } from '$lib/server/db'; import { calculateScore } from '$lib/server/scoring'; import { fetchGameActionsFromPds } from '$lib/atproto-client'; +import { buildBoardStateFromMoves, calculateTerritory } from '$lib/server/board-svg'; /** * GET: Calculate suggested scores using tenuki's scoring engine @@ -35,6 +36,7 @@ export const GET: RequestHandler = async (event) => { if (moves.length === 0) { return json({ suggested: null, + territory: null, message: 'No moves to score', }); } @@ -43,12 +45,24 @@ export const GET: RequestHandler = async (event) => { // Default komi of 6.5 for territory scoring const score = calculateScore(moves, game.board_size, 6.5); + // Build board state and calculate territory + const { boardState } = await buildBoardStateFromMoves( + moves.map(m => ({ x: m.x, y: m.y, color: m.color })), + game.board_size + ); + const territoryMap = calculateTerritory(boardState, game.board_size); + return json({ suggested: { blackScore: Math.round(score.black), whiteScore: Math.round(score.white), winner: score.winner, }, + territory: { + territory: territoryMap.territory, + blackTerritory: territoryMap.blackTerritory, + whiteTerritory: territoryMap.whiteTerritory, + }, message: 'Scores calculated automatically. Please verify and adjust if needed (e.g., for dead stones).', }); } catch (err) { diff --git a/src/routes/game/[id]/+page.svelte b/src/routes/game/[id]/+page.svelte index cbbceda..e4d3787 100644 --- a/src/routes/game/[id]/+page.svelte +++ b/src/routes/game/[id]/+page.svelte @@ -24,6 +24,7 @@ let blackScore = $state(0); let whiteScore = $state(0); let suggestedScores = $state<{ blackScore: number; whiteScore: number; winner: string } | null>(null); + let territoryData = $state<{ territory: Array>; blackTerritory: number; whiteTerritory: number } | null>(null); let loadingSuggestions = $state(false); let firehose: GameFirehose | null = null; let showMoveNotification = $state(false); @@ -107,6 +108,19 @@ reviewMoveIndex !== null ? moves[reviewMoveIndex] : (moves.length > 0 ? moves[moves.length - 1] : null) ); + // Auto-fetch territory data when viewing the scoring section (for all users) + $effect(() => { + if ( + gameStatus === 'completed' && + gameBlackScore === null && + data.session && + !territoryData && + !loadingSuggestions + ) { + fetchSuggestedScores(); + } + }); + // Get move URI for reactions - use actual URI if available, fallback to synthetic function getMoveUri(move: MoveRecord): string { if (move.uri) { @@ -335,6 +349,9 @@ blackScore = result.suggested.blackScore; whiteScore = result.suggested.whiteScore; } + if (result.territory) { + territoryData = result.territory; + } } } catch (err) { console.error('Failed to fetch suggested scores:', err); @@ -788,6 +805,7 @@ onPass={handlePass} interactive={gameStatus === 'active' && isMyTurn() && reviewMoveIndex === null} currentTurn={currentTurn()} + territoryData={gameStatus === 'completed' && gameBlackScore === null ? territoryData : null} /> {/if} @@ -820,75 +838,113 @@ - + {#if gameStatus === 'completed' && gameBlackScore === null && data.session}
-

Submit Final Scores

-

- Both players have passed. Review the calculated scores below and adjust if needed (e.g., for dead stones). -

+ {#if data.session.did === gamePlayerOne} + +

Submit Final Scores

+

+ Both players have passed. Territory is shown on the board above. Review the calculated scores and adjust if needed (e.g., for dead stones). +

+ + {#if showScoreInput} + {#if loadingSuggestions} +

Calculating scores...

+ {:else} + {#if suggestedScores} +
+ Auto-calculated + {#if suggestedScores.winner !== 'tie'} + + {suggestedScores.winner === 'black' ? '⚫' : '⚪'} + {suggestedScores.winner} leads by {Math.abs(suggestedScores.blackScore - suggestedScores.whiteScore)} points + + {:else} + Tie game + {/if} +
+ {/if} +
{ e.preventDefault(); handleScoreSubmit(); }} class="score-form"> +
+ + +
+ +
+ + +
+ +
+ + +
+
+ {/if} + {:else} + + {/if} + {:else} + +

Game Scoring

+

+ Both players have passed. Territory is shown on the board above. +

- {#if showScoreInput} {#if loadingSuggestions}

Calculating scores...

- {:else} - {#if suggestedScores} -
- Auto-calculated + {:else if suggestedScores} +
+

Tentative Scores

+
+
+ ⚫ Black: {suggestedScores.blackScore} +
+
+ ⚪ White: {suggestedScores.whiteScore} +
{#if suggestedScores.winner !== 'tie'} - +
{suggestedScores.winner === 'black' ? '⚫' : '⚪'} {suggestedScores.winner} leads by {Math.abs(suggestedScores.blackScore - suggestedScores.whiteScore)} points - +
{:else} - Tie game +
Tie game
{/if}
- {/if} -
{ e.preventDefault(); handleScoreSubmit(); }} class="score-form"> -
- - -
- -
- - -
- -
- - -
-
+
{/if} - {:else} - + +
+ ⏳ + Waiting for black ({playerOneHandle}) to confirm the final scores... +
{/if}
@@ -1638,6 +1694,64 @@ background: var(--sky-blue-pale); } + .tentative-scores { + background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%); + border-radius: 0.75rem; + padding: 1.25rem; + margin: 1rem 0; + } + + .tentative-scores h4 { + margin: 0 0 0.75rem 0; + color: #065f46; + font-size: 1rem; + font-weight: 600; + } + + .score-display { + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + .score-row { + display: flex; + align-items: center; + gap: 0.5rem; + color: #065f46; + font-size: 1rem; + } + + .score-row strong { + font-size: 1.125rem; + } + + .tentative-winner { + margin-top: 0.5rem; + padding-top: 0.5rem; + border-top: 1px solid rgba(6, 95, 70, 0.2); + color: #065f46; + font-weight: 600; + font-size: 0.9rem; + } + + .waiting-for-black { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 1rem; + background: var(--sky-apricot-light); + border: 1px solid var(--sky-apricot); + border-radius: 0.5rem; + color: var(--sky-apricot-dark); + font-weight: 500; + margin-top: 1rem; + } + + .waiting-icon { + font-size: 1.25rem; + } + .turn-message { margin-top: 1rem; color: var(--sky-gray); diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bf6b02d81df47999cd26c1d95ff57412e8cb477f GIT binary patch literal 26251 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 literal 0 HcmV?d00001