import { defineStore } from "pinia"; import { TrigoGameFrontend } from "../utils/TrigoGameFrontend"; import type { Stone, BoardShape, Player, Move, Position, GameConfig, TerritoryResult } from "../../../inc/trigo"; /** * Game Store State * * Refactored to use TrigoGameFrontend as the single source of truth */ export interface GameState { game: TrigoGameFrontend; config: GameConfig; } /** * Pinia store for game state management * * Now delegates all game logic to TrigoGameFrontend */ export const useGameStore = defineStore("game", { state: (): GameState => ({ game: new TrigoGameFrontend({ x: 5, y: 5, z: 5 }), config: { boardShape: { x: 5, y: 5, z: 5 }, allowUndo: true } }), getters: { // Board state board: (state): Stone[][][] => state.game.getBoard(), boardShape: (state): BoardShape => state.game.getShape(), // Current player currentPlayer: (state): Player => state.game.getCurrentPlayerString(), currentPlayerColor: (state): Player => state.game.getCurrentPlayerString(), opponentPlayer: (state): Player => state.game.getOpponentPlayer(), // Move history moveHistory: (state): Move[] => state.game.getMoveHistory(), moveCount: (state): number => state.game.getMoveCount(), currentMoveIndex: (state): number => state.game.getCurrentMoveIndex(), currentMoves: (state): Move[] => { const history = state.game.getMoveHistory(); const currentIndex = state.game.getCurrentMoveIndex(); return history.slice(0, currentIndex); }, // Game status gameStatus: (state) => state.game.getStatus(), gameResult: (state) => state.game.getResult(), isGameActive: (state): boolean => state.game.isGameActive(), // Captured stones capturedStones: (state): { black: number; white: number } => { const counts = state.game.getCapturedCounts(); return { black: counts.white, // Black captured white stones white: counts.black // White captured black stones }; }, // Pass tracking passCount: (state): number => state.game.getConsecutivePassCount(), // Undo/Redo capabilities canUndo: (state): boolean => { return state.config.allowUndo && state.game.canUndo(); }, canRedo: (state): boolean => { return state.config.allowUndo && state.game.canRedo(); }, // Position checks isValidPosition: (state) => (x: number, y: number, z: number): boolean => { return state.game.isValidPosition(x, y, z); }, isEmpty: (state) => (x: number, y: number, z: number): boolean => { return state.game.isEmpty(x, y, z); }, getStone: (state) => (x: number, y: number, z: number): Stone => { return state.game.getStoneAt(x, y, z) as Stone; } }, actions: { /** * Initialize a new game */ initializeGame(boardShape: BoardShape = { x: 5, y: 5, z: 5 }): void { this.game = new TrigoGameFrontend(boardShape); this.config.boardShape = boardShape; this.saveToSessionStorage(); }, /** * Start the game */ startGame(): void { this.game.startGame(); this.saveToSessionStorage(); }, /** * Make a move */ makeMove( x: number, y: number, z: number ): { success: boolean; capturedPositions?: Position[] } { // Check if game is active if (!this.game.isGameActive()) { console.warn("Game is not active"); return { success: false }; } // Attempt to make the move const success = this.game.makeMove(x, y, z); if (success) { // Get captured positions from last step const lastStep = this.game.getLastStep(); const capturedPositions = lastStep?.capturedPositions; // Save to storage this.saveToSessionStorage(); return { success: true, capturedPositions }; } return { success: false }; }, /** * Pass turn */ pass(): boolean { if (!this.game.isGameActive()) { return false; } const success = this.game.pass(); if (success) { this.saveToSessionStorage(); } return success; }, /** * Resign/surrender */ resign(): boolean { if (!this.game.isGameActive()) { return false; } const success = this.game.surrender(); if (success) { this.saveToSessionStorage(); } return success; }, /** * Undo last move */ undoMove(): boolean { if (!this.canUndo) { return false; } const success = this.game.undoMove(); if (success) { this.saveToSessionStorage(); } return success; }, /** * Redo next move */ redoMove(): boolean { if (!this.canRedo) { return false; } const success = this.game.redoMove(); if (success) { this.saveToSessionStorage(); } return success; }, /** * Jump to specific move in history */ jumpToMove(index: number): boolean { const success = this.game.jumpToMove(index); if (success) { this.saveToSessionStorage(); } return success; }, /** * Reset game to initial state */ resetGame(): void { this.game.reset(); this.saveToSessionStorage(); }, /** * Change board shape (only when game is idle) */ setBoardShape(shape: BoardShape): boolean { if (this.game.getStatus() !== "idle") { console.warn("Cannot change board shape while game is active"); return false; } this.initializeGame(shape); return true; }, /** * Calculate territory */ computeTerritory(): TerritoryResult { return this.game.computeTerritory(); }, /** * Get neighboring positions (6 directions in 3D) */ getNeighbors(x: number, y: number, z: number): Array<{ x: number; y: number; z: number }> { const neighbors = [ { x: x + 1, y, z }, { x: x - 1, y, z }, { x, y: y + 1, z }, { x, y: y - 1, z }, { x, y, z: z + 1 }, { x, y, z: z - 1 } ]; return neighbors.filter((pos) => this.isValidPosition(pos.x, pos.y, pos.z)); }, /** * Save game state to session storage */ saveToSessionStorage(): void { try { this.game.saveToSessionStorage("trigoGameState"); } catch (error) { console.error("Failed to save game state:", error); } }, /** * Load game state from session storage */ loadFromSessionStorage(): boolean { try { const success = this.game.loadFromSessionStorage("trigoGameState"); if (success) { console.log("Game state restored from session storage"); } return success; } catch (error) { console.error("Failed to load game state:", error); return false; } }, /** * Clear saved game state */ clearSessionStorage(): void { try { this.game.clearSessionStorage("trigoGameState"); } catch (error) { console.error("Failed to clear session storage:", error); } } } });