diff --git a/deploy.sh b/deploy.sh index 7b01a97b855cf881aade2504d10b69b3675aa556..a513553eb603472ceb67f43d5ad374eb2d701e4a 100755 --- a/deploy.sh +++ b/deploy.sh @@ -39,10 +39,9 @@ fi echo "📦 Copying trigo-web to HF Space repository..." cp -r "$TRIGO_WEB" "$HF_SPACE/" -# Remove node_modules and dist folders (will be built in Docker) -echo "🧹 Removing node_modules and dist folders (will be rebuilt in Docker)..." +# Remove node_modules folders (dist is kept - pre-built assets) +echo "🧹 Removing node_modules folders..." find "$HF_SPACE/trigo-web" -type d -name "node_modules" -exec rm -rf {} + 2>/dev/null || true -find "$HF_SPACE/trigo-web" -type d -name "dist" -exec rm -rf {} + 2>/dev/null || true # Remove test files echo "🧹 Removing test files..." diff --git a/trigo-web/backend/dist/backend/src/server.d.ts b/trigo-web/backend/dist/backend/src/server.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..21e340592d4f9f65cf2c72cac2342213c86f5128 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/server.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=server.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/server.d.ts.map b/trigo-web/backend/dist/backend/src/server.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..b30f69ded1eab6a2bbfacf40b40dd353b140597e --- /dev/null +++ b/trigo-web/backend/dist/backend/src/server.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/server.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/server.js b/trigo-web/backend/dist/backend/src/server.js new file mode 100644 index 0000000000000000000000000000000000000000..7d79962336021e6839715e6f06b72a681771d577 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/server.js @@ -0,0 +1,111 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const http_1 = require("http"); +const socket_io_1 = require("socket.io"); +const cors_1 = __importDefault(require("cors")); +const dotenv_1 = __importDefault(require("dotenv")); +const path_1 = __importDefault(require("path")); +const fs_1 = __importDefault(require("fs")); +const url_1 = require("url"); +const gameManager_1 = require("./services/gameManager"); +const gameSocket_1 = require("./sockets/gameSocket"); +// Get __dirname equivalent in ES modules +const __filename = (0, url_1.fileURLToPath)(import.meta.url); +const __dirname = path_1.default.dirname(__filename); +// Load environment variables +// Priority: .env.local > .env (load .env first, then .env.local overwrites) +// When running via ts-node: __dirname = backend/src/, so go up 1 level +// When running compiled: __dirname = dist/backend/src/, so go up 3 levels +const isDev = __dirname.includes("/src") && !__dirname.includes("/dist"); +const levelsUp = isDev ? "../" : "../../../"; +const envPath = path_1.default.join(__dirname, levelsUp, ".env"); +const envLocalPath = path_1.default.join(__dirname, levelsUp, ".env.local"); +// Load .env first (base configuration) +if (fs_1.default.existsSync(envPath)) { + dotenv_1.default.config({ path: envPath }); + console.log("[Config] Loaded .env"); +} +else { + console.log(`[Config] .env not found at: ${envPath}`); +} +// Load .env.local second (overrides .env for local development) +if (fs_1.default.existsSync(envLocalPath)) { + dotenv_1.default.config({ path: envLocalPath, override: true }); + console.log("[Config] Loaded .env.local (overriding .env)"); +} +else { + console.log(`[Config] .env.local not found at: ${envLocalPath}`); +} +const app = (0, express_1.default)(); +const httpServer = (0, http_1.createServer)(app); +const io = new socket_io_1.Server(httpServer, { + cors: { + origin: process.env.NODE_ENV === "production" + ? process.env.CLIENT_URL || "http://localhost:5173" + : true, // Allow all origins in development + methods: ["GET", "POST"], + credentials: true + } +}); +// Create GameManager instance +const gameManager = new gameManager_1.GameManager(); +const PORT = parseInt(process.env.PORT || "3000", 10); +const HOST = process.env.HOST || "0.0.0.0"; +console.log(`[Config] Server Configuration:`); +console.log(`[Config] PORT: ${PORT}`); +console.log(`[Config] HOST: ${HOST}`); +console.log(`[Config] NODE_ENV: ${process.env.NODE_ENV || "development"}`); +console.log(`[Config] CLIENT_URL: ${process.env.CLIENT_URL || "not set"}`); +// Middleware +app.use((0, cors_1.default)()); +app.use(express_1.default.json()); +// Serve static files from frontend build (for production) +if (process.env.NODE_ENV === "production") { + const frontendPath = path_1.default.join(__dirname, "../../../../app/dist"); + app.use(express_1.default.static(frontendPath)); + // Serve index.html for all routes (SPA support) + app.get("*", (req, res, next) => { + if (req.path.startsWith("/health") || req.path.startsWith("/socket.io")) { + return next(); + } + res.sendFile(path_1.default.join(frontendPath, "index.html")); + }); +} +// Health check endpoint +app.get("/health", (_req, res) => { + res.json({ status: "ok", timestamp: new Date().toISOString() }); +}); +// Socket.io connection handling +io.on("connection", (socket) => { + console.log(`New client connected: ${socket.id}`); + // Setup game-related socket handlers + (0, gameSocket_1.setupSocketHandlers)(io, socket, gameManager); + // Echo test handler (for testing) + socket.on("echo", (data, callback) => { + const timestamp = new Date().toISOString(); + const responseMessage = `Hello from server! Received: "${data.message}" at ${timestamp}`; + console.log(`[Echo] Client ${socket.id}: ${data.message}`); + // Send response via callback + if (callback && typeof callback === "function") { + callback({ + message: responseMessage, + serverTime: timestamp, + clientTime: data.timestamp + }); + } + }); + socket.on("disconnect", () => { + console.log(`Client disconnected: ${socket.id}`); + }); +}); +// Start server +httpServer.listen(PORT, HOST, () => { + console.log(`Server running on ${HOST}:${PORT}`); + console.log(`Health check: http://${HOST}:${PORT}/health`); + console.log(`Environment: ${process.env.NODE_ENV || "development"}`); +}); +//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/server.js.map b/trigo-web/backend/dist/backend/src/server.js.map new file mode 100644 index 0000000000000000000000000000000000000000..a3cc08e14a6772991b267fc6be018ad1d2b4027b --- /dev/null +++ b/trigo-web/backend/dist/backend/src/server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/services/gameManager.d.ts b/trigo-web/backend/dist/backend/src/services/gameManager.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..30834913661aad31ac4704418c044c8b688cbf11 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/services/gameManager.d.ts @@ -0,0 +1,97 @@ +import type { BoardShape } from "../../../inc/trigo"; +import { TrigoGame } from "../../../inc/trigo/game"; +export interface Player { + id: string; + nickname: string; + color: "black" | "white"; + connected: boolean; +} +export interface GameState { + gameStatus: "waiting" | "playing" | "finished"; + winner: "black" | "white" | null; +} +export interface GameRoom { + id: string; + adminId: string; + players: { + [playerId: string]: Player; + }; + game: TrigoGame; + gameState: GameState; + createdAt: Date; + startedAt: Date | null; +} +export declare class GameManager { + private rooms; + private playerRoomMap; + private defaultBoardShape; + constructor(); + createRoom(playerId: string, nickname: string, boardShape?: BoardShape, preferredColor?: "black" | "white"): GameRoom | null; + joinRoom(roomId: string, playerId: string, nickname: string, preferredColor?: "black" | "white"): GameRoom | null; + leaveRoom(roomId: string, playerId: string): void; + makeMove(roomId: string, playerId: string, move: { + x: number; + y: number; + z: number; + }): boolean; + passTurn(roomId: string, playerId: string): boolean; + resign(roomId: string, playerId: string): boolean; + /** + * Undo the last move (悔棋) + */ + undoMove(roomId: string, playerId: string): boolean; + /** + * Redo the last undone move (forward in history) + */ + redoMove(roomId: string, playerId: string): boolean; + /** + * Reset the game to initial state (new game in same room) + * Only admin can reset the game + */ + resetGame(roomId: string, adminId: string, options?: { + boardShape?: BoardShape; + playerColors?: { + [playerId: string]: "black" | "white"; + }; + }): { + success: boolean; + error?: string; + }; + /** + * Get game board state for a room + */ + getGameBoard(roomId: string): number[][][] | null; + /** + * Get game statistics for a room + */ + getGameStats(roomId: string): { + totalMoves: number; + blackMoves: number; + whiteMoves: number; + capturedByBlack: number; + capturedByWhite: number; + territory: import("../../../inc/trigo").TerritoryResult; + }; + /** + * Get current player for a room + */ + getCurrentPlayer(roomId: string): "black" | "white" | null; + /** + * Calculate and get territory for a room + */ + getTerritory(roomId: string): import("../../../inc/trigo").TerritoryResult; + /** + * End the game and determine winner based on territory + */ + endGameByTerritory(roomId: string): boolean; + /** + * Check if both players passed consecutively (game should end) + * Returns true if game was ended + */ + checkConsecutivePasses(roomId: string): boolean; + getRoom(roomId: string): GameRoom | undefined; + getPlayerRoom(playerId: string): GameRoom | undefined; + getActiveRooms(): GameRoom[]; + private generateRoomId; +} +//# sourceMappingURL=gameManager.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/services/gameManager.d.ts.map b/trigo-web/backend/dist/backend/src/services/gameManager.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..fef772d25c754d69de399575bc980dffdb7d491e --- /dev/null +++ b/trigo-web/backend/dist/backend/src/services/gameManager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"gameManager.d.ts","sourceRoot":"","sources":["../../../../src/services/gameManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/services/gameManager.js b/trigo-web/backend/dist/backend/src/services/gameManager.js new file mode 100644 index 0000000000000000000000000000000000000000..cda69068cfde9f5ae2a5f890f35bbf13437e95f0 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/services/gameManager.js @@ -0,0 +1,352 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GameManager = void 0; +const uuid_1 = require("uuid"); +const game_1 = require("../../../inc/trigo/game"); +class GameManager { + constructor() { + this.rooms = new Map(); + this.playerRoomMap = new Map(); + this.defaultBoardShape = { x: 5, y: 5, z: 5 }; // Default 5x5x5 board + console.log("GameManager initialized"); + } + createRoom(playerId, nickname, boardShape, preferredColor) { + const roomId = this.generateRoomId(); + const shape = boardShape || this.defaultBoardShape; + // Use preferred color if specified, default to black + const playerColor = preferredColor || "black"; + const room = { + id: roomId, + adminId: playerId, // Room creator is admin + players: { + [playerId]: { + id: playerId, + nickname, + color: playerColor, + connected: true + } + }, + game: new game_1.TrigoGame(shape, { + onStepAdvance: (_step, history) => { + console.log(`Step ${history.length}: Player made move`); + }, + onCapture: (captured) => { + console.log(`Captured ${captured.length} stones`); + }, + onWin: (winner) => { + console.log(`Game won by ${winner}`); + } + }), + gameState: { + gameStatus: "waiting", + winner: null + }, + createdAt: new Date(), + startedAt: null + }; + this.rooms.set(roomId, room); + this.playerRoomMap.set(playerId, roomId); + console.log(`Room ${roomId} created by ${playerId}`); + return room; + } + joinRoom(roomId, playerId, nickname, preferredColor) { + const room = this.rooms.get(roomId); + if (!room) { + return null; + } + const playerCount = Object.keys(room.players).length; + if (playerCount >= 2) { + return null; // Room is full + } + // Try to assign preferred color if specified + const firstPlayer = Object.values(room.players)[0]; + let assignedColor; + if (preferredColor && preferredColor !== firstPlayer.color) { + // Preferred color is available + assignedColor = preferredColor; + } + else { + // Assign opposite of first player's color + assignedColor = firstPlayer.color === "black" ? "white" : "black"; + } + room.players[playerId] = { + id: playerId, + nickname, + color: assignedColor, + connected: true + }; + this.playerRoomMap.set(playerId, roomId); + // Start the game when second player joins + if (playerCount === 1) { + room.gameState.gameStatus = "playing"; + room.startedAt = new Date(); + } + return room; + } + leaveRoom(roomId, playerId) { + const room = this.rooms.get(roomId); + if (!room) + return; + if (room.players[playerId]) { + room.players[playerId].connected = false; + } + this.playerRoomMap.delete(playerId); + // Check if room should be deleted + const connectedPlayers = Object.values(room.players).filter((p) => p.connected); + if (connectedPlayers.length === 0) { + this.rooms.delete(roomId); + console.log(`Room ${roomId} deleted - no players remaining`); + } + } + makeMove(roomId, playerId, move) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const player = room.players[playerId]; + if (!player) + return false; + // Check game status + if (room.gameState.gameStatus !== "playing") { + return false; + } + // Convert player color to Stone type + const expectedPlayer = player.color === "black" ? game_1.StoneType.BLACK : game_1.StoneType.WHITE; + const currentPlayer = room.game.getCurrentPlayer(); + // Check if it's the player's turn + if (currentPlayer !== expectedPlayer) { + return false; + } + // Attempt to make the move using TrigoGame + const position = { x: move.x, y: move.y, z: move.z }; + const success = room.game.drop(position); + return success; + } + passTurn(roomId, playerId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const player = room.players[playerId]; + if (!player) + return false; + // Check game status + if (room.gameState.gameStatus !== "playing") { + return false; + } + // Convert player color to Stone type + const expectedPlayer = player.color === "black" ? game_1.StoneType.BLACK : game_1.StoneType.WHITE; + const currentPlayer = room.game.getCurrentPlayer(); + // Check if it's the player's turn + if (currentPlayer !== expectedPlayer) { + return false; + } + return room.game.pass(); + } + resign(roomId, playerId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const player = room.players[playerId]; + if (!player) + return false; + // Surrender the game + room.game.surrender(); + // Update room state + room.gameState.gameStatus = "finished"; + room.gameState.winner = player.color === "black" ? "white" : "black"; + return true; + } + /** + * Undo the last move (悔棋) + */ + undoMove(roomId, playerId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const player = room.players[playerId]; + if (!player) + return false; + // Check game status + if (room.gameState.gameStatus !== "playing") { + return false; + } + return room.game.undo(); + } + /** + * Redo the last undone move (forward in history) + */ + redoMove(roomId, playerId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const player = room.players[playerId]; + if (!player) + return false; + if (room.gameState.gameStatus !== "playing") { + return false; + } + return room.game.redo(); + } + /** + * Reset the game to initial state (new game in same room) + * Only admin can reset the game + */ + resetGame(roomId, adminId, options) { + const room = this.rooms.get(roomId); + if (!room) + return { success: false, error: "Room not found" }; + // Check admin permission + if (room.adminId !== adminId) { + return { success: false, error: "Only room admin can reset the game" }; + } + const boardShape = options?.boardShape; + const playerColors = options?.playerColors; + // Apply player color assignments if provided + if (playerColors) { + const playerIds = Object.keys(room.players); + for (const playerId of playerIds) { + if (playerColors[playerId]) { + room.players[playerId].color = playerColors[playerId]; + } + } + console.log(`Player colors assigned:`, playerColors); + } + // If board shape is provided and different from current, create a new game + if (boardShape) { + const currentShape = room.game.getShape(); + if (boardShape.x !== currentShape.x || + boardShape.y !== currentShape.y || + boardShape.z !== currentShape.z) { + // Create new game with new board shape + room.game = new game_1.TrigoGame(boardShape, { + onStepAdvance: (_step, history) => { + console.log(`Step ${history.length}: Player made move`); + }, + onCapture: (captured) => { + console.log(`Captured ${captured.length} stones`); + }, + onWin: (winner) => { + console.log(`Game won by ${winner}`); + } + }); + console.log(`Game ${roomId} reset with new board shape: ${boardShape.x}x${boardShape.y}x${boardShape.z}`); + } + else { + // Same shape, just reset + room.game.reset(); + console.log(`Game ${roomId} reset to initial state`); + } + } + else { + // No shape provided, just reset + room.game.reset(); + console.log(`Game ${roomId} reset to initial state`); + } + room.gameState.gameStatus = "playing"; + room.gameState.winner = null; + room.startedAt = new Date(); + return { success: true }; + } + /** + * Get game board state for a room + */ + getGameBoard(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return null; + return room.game.getBoard(); + } + /** + * Get game statistics for a room + */ + getGameStats(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return null; + return room.game.getStats(); + } + /** + * Get current player for a room + */ + getCurrentPlayer(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return null; + const currentStone = room.game.getCurrentPlayer(); + return currentStone === game_1.StoneType.BLACK ? "black" : "white"; + } + /** + * Calculate and get territory for a room + */ + getTerritory(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return null; + return room.game.getTerritory(); + } + /** + * End the game and determine winner based on territory + */ + endGameByTerritory(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + if (room.gameState.gameStatus !== "playing") { + return false; + } + // Calculate final territory + const territory = room.game.getTerritory(); + // Determine winner + if (territory.black > territory.white) { + room.gameState.winner = "black"; + } + else if (territory.white > territory.black) { + room.gameState.winner = "white"; + } + else { + // Draw - could set winner to null or handle differently + room.gameState.winner = null; + } + room.gameState.gameStatus = "finished"; + console.log(`Game ${roomId} ended. Black: ${territory.black}, White: ${territory.white}, Winner: ${room.gameState.winner}`); + return true; + } + /** + * Check if both players passed consecutively (game should end) + * Returns true if game was ended + */ + checkConsecutivePasses(roomId) { + const room = this.rooms.get(roomId); + if (!room) + return false; + const history = room.game.getHistory(); + if (history.length < 2) + return false; + // Get last two moves + const lastMove = history[history.length - 1]; + const secondLastMove = history[history.length - 2]; + // Check if both were passes + if (lastMove.type === game_1.StepType.PASS && secondLastMove.type === game_1.StepType.PASS) { + // Two consecutive passes - end the game + this.endGameByTerritory(roomId); + return true; + } + return false; + } + getRoom(roomId) { + return this.rooms.get(roomId); + } + getPlayerRoom(playerId) { + const roomId = this.playerRoomMap.get(playerId); + if (!roomId) + return undefined; + return this.rooms.get(roomId); + } + getActiveRooms() { + return Array.from(this.rooms.values()).filter((room) => room.gameState.gameStatus !== "finished"); + } + generateRoomId() { + return (0, uuid_1.v4)().substring(0, 8).toUpperCase(); + } +} +exports.GameManager = GameManager; +//# sourceMappingURL=gameManager.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/services/gameManager.js.map b/trigo-web/backend/dist/backend/src/services/gameManager.js.map new file mode 100644 index 0000000000000000000000000000000000000000..f2e13595fe5e222aedf6f18e694b39dc6208b2fb --- /dev/null +++ b/trigo-web/backend/dist/backend/src/services/gameManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gameManager.js","sourceRoot":"","sources":["../../../../src/services/gameManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts b/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..24f36ebe258c2e72cf23ab1fc13fdd8a1a02376e --- /dev/null +++ b/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts @@ -0,0 +1,4 @@ +import { Server, Socket } from "socket.io"; +import { GameManager } from "../services/gameManager"; +export declare function setupSocketHandlers(io: Server, socket: Socket, gameManager: GameManager): void; +//# sourceMappingURL=gameSocket.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts.map b/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..b0c571ee37bfc14c2c65411f6776034a2544cb49 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/sockets/gameSocket.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"gameSocket.d.ts","sourceRoot":"","sources":["../../../../src/sockets/gameSocket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,QA6avF"} \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/sockets/gameSocket.js b/trigo-web/backend/dist/backend/src/sockets/gameSocket.js new file mode 100644 index 0000000000000000000000000000000000000000..bafc26d93094e29960e34a6ecf20bde793145813 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/sockets/gameSocket.js @@ -0,0 +1,410 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.setupSocketHandlers = setupSocketHandlers; +function setupSocketHandlers(io, socket, gameManager) { + console.log(`Setting up socket handlers for ${socket.id}`); + // Join room + socket.on("joinRoom", (data, callback) => { + console.log("[gameSocket] joinRoom event received:", { + roomId: data.roomId, + nickname: data.nickname, + preferredColor: data.preferredColor, + hasCallback: !!callback, + socketId: socket.id + }); + const { roomId, nickname, preferredColor } = data; + // Try to create or join room + try { + let room; + if (roomId) { + // Joining existing room + const existingRoom = gameManager.getRoom(roomId); + if (!existingRoom) { + // Room doesn't exist + if (callback) { + callback({ + success: false, + error: "Room not found", + errorCode: "ROOM_NOT_FOUND" + }); + } + return; + } + const playerCount = Object.keys(existingRoom.players).length; + if (playerCount >= 2) { + // Room is full + if (callback) { + callback({ + success: false, + error: "Room is full", + errorCode: "ROOM_FULL" + }); + } + return; + } + room = gameManager.joinRoom(roomId, socket.id, nickname, preferredColor); + } + else { + // Creating new room + room = gameManager.createRoom(socket.id, nickname, undefined, preferredColor); + } + if (room) { + socket.join(room.id); + // Get complete game data for frontend + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const stats = gameManager.getGameStats(room.id); + const tgn = room.game.toTGN(); + // Get player list with colors + const players = {}; + for (const [pid, player] of Object.entries(room.players)) { + players[pid] = { + nickname: player.nickname, + color: player.color + }; + } + const response = { + success: true, + roomId: room.id, + playerId: socket.id, + playerColor: room.players[socket.id]?.color, + isAdmin: room.adminId === socket.id, + adminId: room.adminId, + players, // Include all players in room + gameState: { + boardShape: room.game.getShape(), + currentPlayer, + currentMoveIndex: room.game.getCurrentStep(), + capturedStones: { + black: stats?.capturedByBlack || 0, + white: stats?.capturedByWhite || 0 + }, + gameStatus: room.gameState.gameStatus, + winner: room.gameState.winner, + tgn + } + }; + // Send response via callback + if (callback) { + console.log("[gameSocket] Sending response via callback:", { + roomId: response.roomId, + playerColor: response.playerColor + }); + callback(response); + } + else { + // Fallback to event emit for backward compatibility + console.log("[gameSocket] No callback, using roomJoined emit"); + socket.emit("roomJoined", response); + } + // Notify other players + socket.to(room.id).emit("playerJoined", { + playerId: socket.id, + nickname: nickname + }); + console.log(`Player ${socket.id} ${roomId ? "joined" : "created"} room ${room.id}`); + } + else { + // Generic failure + if (callback) { + callback({ + success: false, + error: "Failed to join or create room", + errorCode: "UNKNOWN_ERROR" + }); + } + } + } + catch (error) { + console.error(`Error in joinRoom handler:`, error); + if (callback) { + callback({ + success: false, + error: "Server error", + errorCode: "SERVER_ERROR" + }); + } + } + }); + // Leave room + socket.on("leaveRoom", () => { + const room = gameManager.getPlayerRoom(socket.id); + if (room) { + socket.leave(room.id); + gameManager.leaveRoom(room.id, socket.id); + // Notify others + socket.to(room.id).emit("playerLeft", { + playerId: socket.id + }); + } + }); + // Game moves + socket.on("makeMove", (data) => { + const room = gameManager.getPlayerRoom(socket.id); + if (room && gameManager.makeMove(room.id, socket.id, data)) { + // Get updated game data + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const stats = gameManager.getGameStats(room.id); + const lastStep = room.game.getLastStep(); + const tgn = room.game.toTGN(); + // Broadcast game update to all players in the room + io.to(room.id).emit("gameUpdate", { + currentPlayer, + action: "move", + lastMove: data, + capturedStones: { + black: stats?.capturedByBlack || 0, + white: stats?.capturedByWhite || 0 + }, + capturedPositions: lastStep?.capturedPositions, + currentMoveIndex: room.game.getCurrentStep(), + tgn + }); + } + else { + socket.emit("error", { message: "Invalid move" }); + } + }); + // Pass turn + socket.on("pass", () => { + const room = gameManager.getPlayerRoom(socket.id); + if (room && gameManager.passTurn(room.id, socket.id)) { + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const tgn = room.game.toTGN(); + io.to(room.id).emit("gameUpdate", { + currentPlayer, + action: "pass", + currentMoveIndex: room.game.getCurrentStep(), + tgn + }); + // Check for consecutive passes (game end) + if (gameManager.checkConsecutivePasses(room.id)) { + const territory = gameManager.getTerritory(room.id); + io.to(room.id).emit("gameEnded", { + winner: room.gameState.winner, + reason: "double-pass", + territory + }); + } + } + }); + // Resign + socket.on("resign", () => { + const room = gameManager.getPlayerRoom(socket.id); + if (room && gameManager.resign(room.id, socket.id)) { + io.to(room.id).emit("gameEnded", { + winner: room.gameState.winner, + reason: "resignation" + }); + } + }); + // Undo move + socket.on("undoMove", (callback) => { + const room = gameManager.getPlayerRoom(socket.id); + if (!room) { + if (callback) + callback({ success: false, error: "Not in a room", errorCode: "NOT_IN_ROOM" }); + return; + } + if (room.gameState.gameStatus !== "playing") { + if (callback) + callback({ success: false, error: "Game not active", errorCode: "GAME_NOT_ACTIVE" }); + return; + } + const success = gameManager.undoMove(room.id, socket.id); + if (success) { + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const stats = gameManager.getGameStats(room.id); + const tgn = room.game.toTGN(); + io.to(room.id).emit("gameUpdate", { + currentPlayer, + action: "undo", + currentMoveIndex: room.game.getCurrentStep(), + capturedStones: { + black: stats?.capturedByBlack || 0, + white: stats?.capturedByWhite || 0 + }, + tgn + }); + if (callback) + callback({ success: true }); + } + else { + if (callback) + callback({ success: false, error: "Cannot undo", errorCode: "UNDO_FAILED" }); + } + }); + // Redo move + socket.on("redoMove", (callback) => { + const room = gameManager.getPlayerRoom(socket.id); + if (!room) { + if (callback) + callback({ success: false, error: "Not in a room", errorCode: "NOT_IN_ROOM" }); + return; + } + if (room.gameState.gameStatus !== "playing") { + if (callback) + callback({ success: false, error: "Game not active", errorCode: "GAME_NOT_ACTIVE" }); + return; + } + if (!room.game.canRedo()) { + if (callback) + callback({ success: false, error: "Nothing to redo", errorCode: "NOTHING_TO_REDO" }); + return; + } + const success = gameManager.redoMove(room.id, socket.id); + if (success) { + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const stats = gameManager.getGameStats(room.id); + const lastStep = room.game.getLastStep(); + const tgn = room.game.toTGN(); + io.to(room.id).emit("gameUpdate", { + currentPlayer, + action: "redo", + lastMove: lastStep?.position, + capturedStones: { + black: stats?.capturedByBlack || 0, + white: stats?.capturedByWhite || 0 + }, + capturedPositions: lastStep?.capturedPositions, + currentMoveIndex: room.game.getCurrentStep(), + tgn + }); + if (callback) + callback({ success: true }); + } + else { + if (callback) + callback({ success: false, error: "Redo failed", errorCode: "REDO_FAILED" }); + } + }); + // Reset game + socket.on("resetGame", (data, callback) => { + const room = gameManager.getPlayerRoom(socket.id); + if (!room) { + const cb = typeof data === 'function' ? data : callback; + if (cb) + cb({ success: false, error: "Not in a room", errorCode: "NOT_IN_ROOM" }); + return; + } + // Handle both old signature (no data) and new signature (with options) + const options = typeof data === 'object' && data !== null ? { + boardShape: data.boardShape, + playerColors: data.playerColors + } : undefined; + const responseCb = typeof data === 'function' ? data : callback; + const result = gameManager.resetGame(room.id, socket.id, options); + if (result.success) { + const currentPlayer = gameManager.getCurrentPlayer(room.id); + const tgn = room.game.toTGN(); + // Get updated player info with new colors + const players = {}; + for (const [pid, player] of Object.entries(room.players)) { + players[pid] = { + nickname: player.nickname, + color: player.color + }; + } + io.to(room.id).emit("gameReset", { + currentPlayer, + boardShape: room.game.getShape(), + currentMoveIndex: 0, + capturedStones: { black: 0, white: 0 }, + players, + tgn + }); + if (responseCb) + responseCb({ success: true }); + } + else { + if (responseCb) + responseCb({ + success: false, + error: result.error || "Reset failed", + errorCode: result.error === "Only room admin can reset the game" ? "NOT_ADMIN" : "RESET_FAILED" + }); + } + }); + // Chat messages + socket.on("chatMessage", (data) => { + const room = gameManager.getPlayerRoom(socket.id); + if (room) { + const player = room.players[socket.id]; + io.to(room.id).emit("chatMessage", { + author: player?.nickname || "Unknown", + content: data.content, + playerId: socket.id + }); + } + }); + // Change nickname + socket.on("changeNickname", (data, callback) => { + const room = gameManager.getPlayerRoom(socket.id); + if (!room) { + const error = { success: false, error: "Not in a room" }; + if (callback) + callback(error); + return; + } + // Validate nickname + const validation = validateNickname(data.nickname); + if (!validation.valid) { + const error = { success: false, error: validation.error }; + if (callback) + callback(error); + return; + } + // Update player nickname + const player = room.players[socket.id]; + if (player) { + const oldNickname = player.nickname; + player.nickname = data.nickname; + // Broadcast to all players in room + io.to(room.id).emit("nicknameChanged", { + playerId: socket.id, + nickname: data.nickname, + oldNickname: oldNickname + }); + console.log(`Player ${socket.id} changed nickname: ${oldNickname} -> ${data.nickname}`); + if (callback) { + callback({ success: true, nickname: data.nickname }); + } + } + }); + // Handle disconnection + socket.on("disconnect", () => { + console.log(`Client disconnected: ${socket.id}`); + const room = gameManager.getPlayerRoom(socket.id); + if (room) { + gameManager.leaveRoom(room.id, socket.id); + socket.to(room.id).emit("playerDisconnected", { + playerId: socket.id + }); + } + }); +} +/** + * Validate nickname according to the rules: + * - Length: 3-20 characters + * - Characters: alphanumeric + spaces only + * - No leading/trailing whitespace + */ +function validateNickname(nickname) { + if (!nickname || typeof nickname !== "string") { + return { valid: false, error: "Invalid nickname" }; + } + const trimmed = nickname.trim(); + if (trimmed.length < 3) { + return { valid: false, error: "Nickname must be at least 3 characters" }; + } + if (trimmed.length > 20) { + return { valid: false, error: "Nickname must be 20 characters or less" }; + } + if (!/^[a-zA-Z0-9 ]+$/.test(trimmed)) { + return { valid: false, error: "Only letters, numbers, and spaces allowed" }; + } + if (trimmed !== nickname) { + return { valid: false, error: "No leading or trailing spaces allowed" }; + } + return { valid: true }; +} +//# sourceMappingURL=gameSocket.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/backend/src/sockets/gameSocket.js.map b/trigo-web/backend/dist/backend/src/sockets/gameSocket.js.map new file mode 100644 index 0000000000000000000000000000000000000000..dfbfd4c94747252df998f5db28268cc8bb670732 --- /dev/null +++ b/trigo-web/backend/dist/backend/src/sockets/gameSocket.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gameSocket.js","sourceRoot":"","sources":["../../../../src/sockets/gameSocket.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/config.d.ts b/trigo-web/backend/dist/inc/config.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e6ddfdde60d1b3fd00551118f9c14a0d73193598 --- /dev/null +++ b/trigo-web/backend/dist/inc/config.d.ts @@ -0,0 +1,49 @@ +/** + * Configuration Utilities + * + * Provides centralized access to environment variables for ONNX model paths + * and other configuration values. + * + * Works across different contexts: + * - Frontend (Vite): Uses import.meta.env.VITE_* variables + * - Backend/Tools (Node): Uses process.env.* variables with dotenv + */ +/** + * ONNX Session Options + */ +export interface OnnxSessionOptions { + executionProviders: string[]; + intraOpNumThreads?: number; + interOpNumThreads?: number; + graphOptimizationLevel?: "disabled" | "basic" | "extended" | "all"; + enableCpuMemArena?: boolean; + enableMemPattern?: boolean; +} +/** + * Get ONNX model paths + * Returns paths appropriate for the current environment + */ +export declare function getOnnxModelPaths(): { + evaluationModel: string; + treeModel: string; +}; +/** + * Get ONNX session options from environment variables + * Returns session options with threading and optimization configuration + */ +export declare function getOnnxSessionOptions(): OnnxSessionOptions; +/** + * Get absolute path to model file (Node.js only) + * Resolves relative paths to absolute paths from project root + */ +export declare function getAbsoluteModelPath(relativePath: string): string; +/** + * Load environment variables from .env file (Node.js only) + * Call this at the start of tool scripts + * + * Loading order: + * 1. .env (base configuration, committed to git) + * 2. .env.local (local overrides, not committed to git) + */ +export declare function loadEnvConfig(): Promise; +//# sourceMappingURL=config.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/config.d.ts.map b/trigo-web/backend/dist/inc/config.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..2c817f806e2f915e42274cbf48258710779c74c0 --- /dev/null +++ b/trigo-web/backend/dist/inc/config.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../inc/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,CAAC;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAGD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CAClB,CA2BA;AAGD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAoC1D;AAGD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAejE;AAGD;;;;;;;GAOG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqCnD"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/config.js b/trigo-web/backend/dist/inc/config.js new file mode 100644 index 0000000000000000000000000000000000000000..14e5c82f8a0970ebbf95d0caa9085cbcda866030 --- /dev/null +++ b/trigo-web/backend/dist/inc/config.js @@ -0,0 +1,185 @@ +"use strict"; +/** + * Configuration Utilities + * + * Provides centralized access to environment variables for ONNX model paths + * and other configuration values. + * + * Works across different contexts: + * - Frontend (Vite): Uses import.meta.env.VITE_* variables + * - Backend/Tools (Node): Uses process.env.* variables with dotenv + */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getOnnxModelPaths = getOnnxModelPaths; +exports.getOnnxSessionOptions = getOnnxSessionOptions; +exports.getAbsoluteModelPath = getAbsoluteModelPath; +exports.loadEnvConfig = loadEnvConfig; +const path = __importStar(require("path")); +const url_1 = require("url"); +// Environment detection +const isNode = typeof process !== "undefined" && process.versions?.node; +const isBrowser = typeof window !== "undefined"; +/** + * Get ONNX model paths + * Returns paths appropriate for the current environment + */ +function getOnnxModelPaths() { + // Frontend (Vite environment) + if (isBrowser && typeof import.meta.env !== "undefined") { + const evaluationModel = import.meta.env.VITE_ONNX_EVALUATION_MODEL; + const treeModel = import.meta.env.VITE_ONNX_TREE_MODEL; + if (!evaluationModel || !treeModel) { + throw new Error("ONNX model paths not configured. Check VITE_ONNX_EVALUATION_MODEL and VITE_ONNX_TREE_MODEL in .env"); + } + return { evaluationModel, treeModel }; + } + // Backend/Tools (Node environment) + if (isNode) { + const evaluationModel = process.env.ONNX_EVALUATION_MODEL; + const treeModel = process.env.ONNX_TREE_MODEL; + if (!evaluationModel || !treeModel) { + throw new Error("ONNX model paths not configured. Check ONNX_EVALUATION_MODEL and ONNX_TREE_MODEL in .env"); + } + return { evaluationModel, treeModel }; + } + // Should not reach here + throw new Error("Unknown environment - cannot determine model paths"); +} +/** + * Get ONNX session options from environment variables + * Returns session options with threading and optimization configuration + */ +function getOnnxSessionOptions() { + // Default values + const options = { + executionProviders: ["cpu"], + graphOptimizationLevel: "all", + enableCpuMemArena: true, + enableMemPattern: true + }; + // Frontend (Vite environment) + if (isBrowser && typeof import.meta.env !== "undefined") { + const intraThreadsEnv = import.meta.env.VITE_ONNX_INTRA_OP_NUM_THREADS; + const interThreadsEnv = import.meta.env.VITE_ONNX_INTER_OP_NUM_THREADS; + const graphOptEnv = import.meta.env.VITE_ONNX_GRAPH_OPTIMIZATION_LEVEL; + if (intraThreadsEnv) + options.intraOpNumThreads = parseInt(intraThreadsEnv, 10); + if (interThreadsEnv) + options.interOpNumThreads = parseInt(interThreadsEnv, 10); + if (graphOptEnv) + options.graphOptimizationLevel = graphOptEnv; + } + // Backend/Tools (Node environment) + if (isNode) { + const intraThreadsEnv = process.env.ONNX_INTRA_OP_NUM_THREADS; + const interThreadsEnv = process.env.ONNX_INTER_OP_NUM_THREADS; + const graphOptEnv = process.env.ONNX_GRAPH_OPTIMIZATION_LEVEL; + const cpuMemArenaEnv = process.env.ONNX_ENABLE_CPU_MEM_ARENA; + const memPatternEnv = process.env.ONNX_ENABLE_MEM_PATTERN; + if (intraThreadsEnv) + options.intraOpNumThreads = parseInt(intraThreadsEnv, 10); + if (interThreadsEnv) + options.interOpNumThreads = parseInt(interThreadsEnv, 10); + if (graphOptEnv) + options.graphOptimizationLevel = graphOptEnv; + if (cpuMemArenaEnv) + options.enableCpuMemArena = cpuMemArenaEnv === "true"; + if (memPatternEnv) + options.enableMemPattern = memPatternEnv === "true"; + } + return options; +} +/** + * Get absolute path to model file (Node.js only) + * Resolves relative paths to absolute paths from project root + */ +function getAbsoluteModelPath(relativePath) { + if (!isNode) { + return relativePath; // Browser environment - return as-is + } + // If already absolute, return as-is + if (path.isAbsolute(relativePath)) { + return relativePath; + } + // Resolve relative to project root + const __filename = (0, url_1.fileURLToPath)(import.meta.url); + const __dirname = path.dirname(__filename); + const rootDir = path.resolve(__dirname, ".."); + return path.resolve(rootDir, relativePath); +} +/** + * Load environment variables from .env file (Node.js only) + * Call this at the start of tool scripts + * + * Loading order: + * 1. .env (base configuration, committed to git) + * 2. .env.local (local overrides, not committed to git) + */ +async function loadEnvConfig() { + if (!isNode) { + console.warn("[Config] loadEnvConfig() called in non-Node environment"); + return; + } + try { + // Dynamically import dotenv (ESM-compatible) + const dotenv = (await Promise.resolve().then(() => __importStar(require("dotenv")))).default; + const __filename = (0, url_1.fileURLToPath)(import.meta.url); + const __dirname = path.dirname(__filename); + const rootDir = path.resolve(__dirname, ".."); + // Load base .env file + const baseResult = dotenv.config({ path: path.join(rootDir, ".env") }); + if (baseResult.error) { + console.warn("[Config] Failed to load .env:", baseResult.error.message); + } + else { + console.log("[Config] ✓ Base environment variables loaded from .env"); + } + // Load .env.local for local overrides (if exists) + // Use override: true to allow .env.local to override .env values + const localResult = dotenv.config({ + path: path.join(rootDir, ".env.local"), + override: true + }); + if (!localResult.error) { + console.log("[Config] ✓ Local overrides loaded from .env.local"); + } + // Silently ignore if .env.local doesn't exist (optional file) + } + catch (error) { + console.warn("[Config] dotenv not available:", error); + } +} +//# sourceMappingURL=config.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/config.js.map b/trigo-web/backend/dist/inc/config.js.map new file mode 100644 index 0000000000000000000000000000000000000000..c1609bb458a0b3517161c16cd98ec4c126f24929 --- /dev/null +++ b/trigo-web/backend/dist/inc/config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../inc/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BH,8CA8BC;AAOD,sDAoCC;AAOD,oDAeC;AAWD,sCAqCC;AAzKD,2CAA6B;AAC7B,6BAAoC;AAGpC,wBAAwB;AACxB,MAAM,MAAM,GAAG,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;AACxE,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAgBhD;;;GAGG;AACH,SAAgB,iBAAiB;IAIhC,8BAA8B;IAC9B,IAAI,SAAS,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,0BAA0B,CAAC;QACnE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAEvD,IAAI,CAAC,eAAe,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAC;QACvH,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;IACvC,CAAC;IAED,mCAAmC;IACnC,IAAI,MAAM,EAAE,CAAC;QACZ,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAE9C,IAAI,CAAC,eAAe,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;QAC7G,CAAC;QAED,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;IACvC,CAAC;IAED,wBAAwB;IACxB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;AACvE,CAAC;AAGD;;;GAGG;AACH,SAAgB,qBAAqB;IACpC,iBAAiB;IACjB,MAAM,OAAO,GAAuB;QACnC,kBAAkB,EAAE,CAAC,KAAK,CAAC;QAC3B,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,IAAI;KACtB,CAAC;IAEF,8BAA8B;IAC9B,IAAI,SAAS,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC;QACvE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC;QACvE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,kCAAkC,CAAC;QAEvE,IAAI,eAAe;YAAE,OAAO,CAAC,iBAAiB,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI,eAAe;YAAE,OAAO,CAAC,iBAAiB,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI,WAAW;YAAE,OAAO,CAAC,sBAAsB,GAAG,WAAkB,CAAC;IACtE,CAAC;IAED,mCAAmC;IACnC,IAAI,MAAM,EAAE,CAAC;QACZ,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC9D,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC9D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;QAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC7D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;QAE1D,IAAI,eAAe;YAAE,OAAO,CAAC,iBAAiB,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI,eAAe;YAAE,OAAO,CAAC,iBAAiB,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI,WAAW;YAAE,OAAO,CAAC,sBAAsB,GAAG,WAAkB,CAAC;QACrE,IAAI,cAAc;YAAE,OAAO,CAAC,iBAAiB,GAAG,cAAc,KAAK,MAAM,CAAC;QAC1E,IAAI,aAAa;YAAE,OAAO,CAAC,gBAAgB,GAAG,aAAa,KAAK,MAAM,CAAC;IACxE,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAGD;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,YAAoB;IACxD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,YAAY,CAAC,CAAC,qCAAqC;IAC3D,CAAC;IAED,oCAAoC;IACpC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,mCAAmC;IACnC,MAAM,UAAU,GAAG,IAAA,mBAAa,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAGD;;;;;;;GAOG;AACI,KAAK,UAAU,aAAa;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;QACxE,OAAO;IACR,CAAC;IAED,IAAI,CAAC;QACJ,6CAA6C;QAC7C,MAAM,MAAM,GAAG,CAAC,wDAAa,QAAQ,GAAC,CAAC,CAAC,OAAO,CAAC;QAChD,MAAM,UAAU,GAAG,IAAA,mBAAa,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAE9C,sBAAsB;QACtB,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAEvE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzE,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACvE,CAAC;QAED,kDAAkD;QAClD,iEAAiE;QACjE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC;YACtC,QAAQ,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QAClE,CAAC;QACD,8DAA8D;IAE/D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;IACvD,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/mctsAgent.d.ts b/trigo-web/backend/dist/inc/mctsAgent.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1df83243113c52745656148b283421ff1ad97307 --- /dev/null +++ b/trigo-web/backend/dist/inc/mctsAgent.d.ts @@ -0,0 +1,136 @@ +/** + * Monte Carlo Tree Search (MCTS) Agent for Trigo + * + * Implements AlphaGo Zero-style MCTS with: + * - PUCT (Polynomial Upper Confidence Trees) selection + * - Neural network guidance for policy and value + * - Visit count statistics for training data generation + * + * Based on: Silver et al., "Mastering the Game of Go without Human Knowledge" + */ +import { TrigoGame } from "./trigo/game"; +import type { Move } from "./trigo/types"; +import { TrigoTreeAgent } from "./trigoTreeAgent"; +import { TrigoEvaluationAgent } from "./trigoEvaluationAgent"; +/** + * MCTS Configuration + */ +export interface MCTSConfig { + numSimulations: number; + cPuct: number; + temperature: number; + dirichletAlpha: number; + dirichletEpsilon: number; +} +/** + * MCTS Agent + * Combines tree search with neural network evaluation + */ +export declare class MCTSAgent { + private treeAgent; + private evaluationAgent; + private config; + constructor(treeAgent: TrigoTreeAgent, evaluationAgent: TrigoEvaluationAgent, config?: Partial); + /** + * Select best move using MCTS + * + * @param game Current game state + * @param moveNumber Move number (for temperature schedule) + * @returns Selected move with visit count statistics + */ + selectMove(game: TrigoGame, moveNumber: number): Promise<{ + move: Move; + visitCounts: Map; + searchPolicy: Map; + rootValue: number; + }>; + /** + * Run a single MCTS simulation + * Select -> Expand & Evaluate -> Backup + */ + private runSimulation; + /** + * Selection phase: Traverse tree using PUCT + * + * @param root Root node to start selection from + * @returns Leaf node and path taken + */ + private select; + /** + * Expand and evaluate leaf node using neural networks + * + * @param node Leaf node to expand + * @returns Value estimate from evaluation network + */ + private expandAndEvaluate; + /** + * Backup phase: Propagate value up the tree + * + * @param path Path from root to leaf + * @param value Value to propagate (white-positive: positive = white winning) + */ + private backup; + /** + * Calculate PUCT value for action selection + * + * PUCT = Q(s,a) + U(s,a) [for White, who maximizes] + * PUCT = -Q(s,a) + U(s,a) [for Black, who minimizes] + * where U(s,a) = c_puct * P(s,a) * sqrt(Σ_b N(s,b)) / (1 + N(s,a)) + * + * @param node Current node + * @param actionKey Action to evaluate + * @param isWhite Whether current player is White + * @returns PUCT value + */ + private calculatePUCT; + /** + * Select action to play based on visit counts + * Uses temperature to control exploration vs exploitation + * + * @param node Root node + * @param temperature Selection temperature (τ=1 for exploration, τ→0 for greedy) + * @returns Selected move + */ + private selectPlayAction; + /** + * Compute search policy from visit counts + * π(a|s) = N(s,a)^(1/τ) / Σ_b N(s,b)^(1/τ) + * + * @param node Root node + * @param temperature Selection temperature + * @returns Normalized policy distribution + */ + private computeSearchPolicy; + /** + * Get root value estimate (weighted average of Q-values) + */ + private getRootValue; + /** + * Add Dirichlet noise to prior probabilities at root + * P(s,a) = (1 - ε) * p_a + ε * η_a + * where η ~ Dir(α) + */ + private addDirichletNoise; + /** + * Sample from Gamma distribution using Marsaglia and Tsang method (2000) + * Used for Dirichlet noise generation + */ + private sampleGamma; + /** + * Sample from standard normal distribution (Box-Muller transform) + */ + private randomNormal; + /** + * Create a new MCTS node + */ + private createNode; + /** + * Encode move to string key for storage in maps + */ + private encodeAction; + /** + * Decode string key back to move + */ + private decodeAction; +} +//# sourceMappingURL=mctsAgent.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/mctsAgent.d.ts.map b/trigo-web/backend/dist/inc/mctsAgent.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..57add01f43c5ed28fcae79fd4f391400cc55ad54 --- /dev/null +++ b/trigo-web/backend/dist/inc/mctsAgent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"mctsAgent.d.ts","sourceRoot":"","sources":["../../../inc/mctsAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAuBD;;;GAGG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAa;gBAI1B,SAAS,EAAE,cAAc,EACzB,eAAe,EAAE,oBAAoB,EACrC,MAAM,GAAE,OAAO,CAAC,UAAU,CAAM;IAgBjC;;;;;;OAMG;IACG,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAC9D,IAAI,EAAE,IAAI,CAAC;QACX,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAuGF;;;OAGG;YACW,aAAa;IAY3B;;;;;OAKG;IACH,OAAO,CAAC,MAAM;IAgEd;;;;;OAKG;YACW,iBAAiB;IAoI/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM;IAiBd;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAiBrB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IA8CxB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgCzB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAuCnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,YAAY;CAQpB"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/mctsAgent.js b/trigo-web/backend/dist/inc/mctsAgent.js new file mode 100644 index 0000000000000000000000000000000000000000..62bd1fe80d2488c7d0cccd176554ce4bfa8e9405 --- /dev/null +++ b/trigo-web/backend/dist/inc/mctsAgent.js @@ -0,0 +1,553 @@ +"use strict"; +/** + * Monte Carlo Tree Search (MCTS) Agent for Trigo + * + * Implements AlphaGo Zero-style MCTS with: + * - PUCT (Polynomial Upper Confidence Trees) selection + * - Neural network guidance for policy and value + * - Visit count statistics for training data generation + * + * Based on: Silver et al., "Mastering the Game of Go without Human Knowledge" + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MCTSAgent = void 0; +/** + * MCTS Agent + * Combines tree search with neural network evaluation + */ +class MCTSAgent { + constructor(treeAgent, evaluationAgent, config = {}) { + this.treeAgent = treeAgent; + this.evaluationAgent = evaluationAgent; + // Default configuration (AlphaGo Zero-inspired) + this.config = { + numSimulations: config.numSimulations ?? 600, + cPuct: config.cPuct ?? 1.0, + temperature: config.temperature ?? 1.0, + dirichletAlpha: config.dirichletAlpha ?? 0.03, + dirichletEpsilon: config.dirichletEpsilon ?? 0.25 + }; + } + /** + * Select best move using MCTS + * + * @param game Current game state + * @param moveNumber Move number (for temperature schedule) + * @returns Selected move with visit count statistics + */ + async selectMove(game, moveNumber) { + // Create root node + const root = this.createNode(game, null, null); + // Check if root is already terminal (game over) + // Terminal conditions (checked in order of cost): + // 1. Both players have stones (cheap) + // 2. Board coverage > 50% (cheap) + // 3. No neutral territory (EXPENSIVE - only check if above pass) + // Get board state (cheap) + const board = game.getBoard(); + const shape = game.getShape(); + const totalPositions = shape.x * shape.y * shape.z; + // Count stones (cheap) + let stoneCount = 0; + let hasBlack = false; + let hasWhite = false; + for (let x = 0; x < shape.x; x++) { + for (let y = 0; y < shape.y; y++) { + for (let z = 0; z < shape.z; z++) { + const stone = board[x][y][z]; + if (stone === 1) { // Black + hasBlack = true; + stoneCount++; + } + else if (stone === 2) { // White + hasWhite = true; + stoneCount++; + } + } + } + } + const coverageRatio = stoneCount / totalPositions; + // Early exit: Check cheap conditions first + let isRootTerminal = false; + let territory = null; + if (hasBlack && hasWhite && coverageRatio > 0.5) { + // Only calculate territory if cheap conditions pass (EXPENSIVE) + territory = game.getTerritory(); + isRootTerminal = territory.neutral === 0; + } + if (isRootTerminal) { + // Game is over - return Pass move with exact value from territory + // Using same formula as training code + const scoreDiff = territory.white - territory.black; + let rootValue; + if (Math.abs(scoreDiff) < 1e-6) { + // Draw/tie case + rootValue = 0.0; + } + else { + // Match training formula from valueCausalLoss.py:_expand_value_targets + // The log term incentivizes winning by larger margins (logarithmically) + const territory_value_factor = 1.0; // Default from training config + const signScore = Math.sign(scoreDiff); + rootValue = signScore * (1 + Math.log(Math.abs(scoreDiff))) * territory_value_factor; + } + const currentPlayer = game.getCurrentPlayer(); + return { + move: { player: currentPlayer === 1 ? "black" : "white", isPass: true }, + visitCounts: new Map(), + searchPolicy: new Map(), + rootValue + }; + } + // Run MCTS simulations + for (let i = 0; i < this.config.numSimulations; i++) { + await this.runSimulation(root); + } + // Temperature schedule: τ=1 for first 30 moves, τ→0 afterward + const temperature = moveNumber < 30 ? this.config.temperature : 0.01; + // Select move based on visit counts + const move = this.selectPlayAction(root, temperature); + // Set correct player for returned move + const currentPlayer = game.getCurrentPlayer(); + move.player = currentPlayer === 1 ? "black" : "white"; + // Compute search policy (normalized visit counts) + const searchPolicy = this.computeSearchPolicy(root, temperature); + // Get root value estimate (average Q-value weighted by visit counts) + const rootValue = this.getRootValue(root); + return { + move, + visitCounts: new Map(root.N), + searchPolicy, + rootValue + }; + } + /** + * Run a single MCTS simulation + * Select -> Expand & Evaluate -> Backup + */ + async runSimulation(root) { + // 1. Selection: Traverse tree using PUCT until reaching unexpanded node + const { node, path } = this.select(root); + // 2. Expand and Evaluate: Get value from neural network + const value = await this.expandAndEvaluate(node); + // 3. Backup: Propagate value up the tree + this.backup(path, value); + } + /** + * Selection phase: Traverse tree using PUCT + * + * @param root Root node to start selection from + * @returns Leaf node and path taken + */ + select(root) { + const path = []; + let node = root; + // Traverse until we reach an unexpanded node + while (node.expanded) { + // Get all legal actions + const actionKeys = Array.from(node.P.keys()); + // Terminal node check: if expanded but no actions, this is a terminal node + if (actionKeys.length === 0) { + break; // Return this terminal node as leaf + } + // Select action with best PUCT value + // Both players select HIGHEST PUCT value: + // - Black: PUCT = -Q + U, max PUCT = max(-Q) = min(Q) ✓ + // - White: PUCT = Q + U, max PUCT = max(Q) ✓ + const currentPlayer = node.state.getCurrentPlayer(); + const isWhite = currentPlayer === 2; + let bestActionKey = actionKeys[0]; + let bestPuct = this.calculatePUCT(node, bestActionKey, isWhite); + for (let i = 1; i < actionKeys.length; i++) { + const actionKey = actionKeys[i]; + const puct = this.calculatePUCT(node, actionKey, isWhite); + if (puct > bestPuct) { + bestPuct = puct; + bestActionKey = actionKey; + } + } + // Record path + path.push({ node, actionKey: bestActionKey }); + // Move to child (create if doesn't exist) + if (!node.children.has(bestActionKey)) { + // Decode action and apply to get child state + const action = this.decodeAction(bestActionKey); + const childState = node.state.clone(); + if (action.isPass) { + childState.pass(); + } + else if (action.x !== undefined && action.y !== undefined && action.z !== undefined) { + childState.drop({ x: action.x, y: action.y, z: action.z }); + } + // Create child node (unexpanded) + const childNode = this.createNode(childState, node, action); + node.children.set(bestActionKey, childNode); + } + node = node.children.get(bestActionKey); + } + return { node, path }; + } + /** + * Expand and evaluate leaf node using neural networks + * + * @param node Leaf node to expand + * @returns Value estimate from evaluation network + */ + async expandAndEvaluate(node) { + // Check if game is over (terminal state) + // Terminal conditions (checked in order of cost): + // 1. Both players have stones (cheap) + // 2. Board coverage > 50% (cheap) + // 3. No neutral territory (EXPENSIVE - only check if above pass) + // Get board state (cheap) + const board = node.state.getBoard(); + const shape = node.state.getShape(); + const totalPositions = shape.x * shape.y * shape.z; + // Count stones on board (cheap) + let stoneCount = 0; + let hasBlack = false; + let hasWhite = false; + for (let x = 0; x < shape.x; x++) { + for (let y = 0; y < shape.y; y++) { + for (let z = 0; z < shape.z; z++) { + const stone = board[x][y][z]; + if (stone === 1) { // Black + hasBlack = true; + stoneCount++; + } + else if (stone === 2) { // White + hasWhite = true; + stoneCount++; + } + } + } + } + const coverageRatio = stoneCount / totalPositions; + // Early exit: Check cheap conditions first + let isTerminal = false; + let territory = null; + if (hasBlack && hasWhite && coverageRatio > 0.5) { + // Only calculate territory if cheap conditions pass (EXPENSIVE) + territory = node.state.getTerritory(); + isTerminal = territory.neutral === 0; + } + if (isTerminal) { + // Game is over - return exact result from territory + // Using same formula as training code: target = sign(score) * (1 + log(|score|)) * factor + const scoreDiff = territory.white - territory.black; + let value; + if (Math.abs(scoreDiff) < 1e-6) { + // Draw/tie case + value = 0.0; + } + else { + // Match training formula from valueCausalLoss.py:_expand_value_targets + // target = sign(score) * (1 + log(|score|)) * territory_value_factor + // The log term incentivizes winning by larger margins (logarithmically) + // This balances winning incentive without overwhelming win/loss direction + const territory_value_factor = 1.0; // Default from training config + const signScore = Math.sign(scoreDiff); + value = signScore * (1 + Math.log(Math.abs(scoreDiff))) * territory_value_factor; + } + // Mark terminal node as expanded with empty action set to prevent revisits + // This caches the terminal value and avoids repeated getTerritory() calls + node.expanded = true; + node.P = new Map(); // No actions available (terminal) + node.N = new Map(); + node.W = new Map(); + node.Q = new Map(); + node.children = new Map(); + return value; + } + // Non-terminal state: expand with policy network and evaluate + // Get all valid moves + const currentPlayer = node.state.getCurrentPlayer() === 1 ? "black" : "white"; + const validPositions = node.state.validMovePositions(); + const moves = validPositions.map(pos => ({ + x: pos.x, + y: pos.y, + z: pos.z, + player: currentPlayer + })); + moves.push({ player: currentPlayer, isPass: true }); + // Get policy priors from tree agent + const scoredMoves = await this.treeAgent.scoreMoves(node.state, moves); + // Convert log probabilities to probabilities and normalize (stable softmax) + const maxScore = Math.max(...scoredMoves.map(m => m.score)); + const expScores = scoredMoves.map(m => Math.exp(m.score - maxScore)); + const sumExp = expScores.reduce((sum, exp) => sum + exp, 0); + // Initialize priors P(s,a) + node.P = new Map(); + node.N = new Map(); + node.W = new Map(); + node.Q = new Map(); + // Handle edge case: if all scores are -Infinity or sumExp is 0/NaN + const useFallback = !isFinite(sumExp) || sumExp < 1e-10; + for (let i = 0; i < scoredMoves.length; i++) { + const actionKey = this.encodeAction(scoredMoves[i].move); + // Use uniform distribution as fallback if normalization fails + const prior = useFallback ? (1.0 / scoredMoves.length) : (expScores[i] / sumExp); + node.P.set(actionKey, prior); + node.N.set(actionKey, 0); + node.W.set(actionKey, 0); + node.Q.set(actionKey, 0); + } + // Add Dirichlet noise at root + if (node.parent === null) { + this.addDirichletNoise(node.P); + } + // Mark as expanded + node.expanded = true; + // Get value estimate from evaluation agent + const evaluation = await this.evaluationAgent.evaluatePosition(node.state); + // Return value directly (value model returns white-positive by design) + return evaluation.value; + } + /** + * Backup phase: Propagate value up the tree + * + * @param path Path from root to leaf + * @param value Value to propagate (white-positive: positive = white winning) + */ + backup(path, value) { + // Propagate value up the tree (white-positive throughout) + // No sign flipping needed - Q values are always white-positive + for (let i = path.length - 1; i >= 0; i--) { + const { node, actionKey } = path[i]; + // Update statistics + const n = node.N.get(actionKey) ?? 0; + const w = node.W.get(actionKey) ?? 0; + node.N.set(actionKey, n + 1); + node.W.set(actionKey, w + value); + node.Q.set(actionKey, (w + value) / (n + 1)); + } + } + /** + * Calculate PUCT value for action selection + * + * PUCT = Q(s,a) + U(s,a) [for White, who maximizes] + * PUCT = -Q(s,a) + U(s,a) [for Black, who minimizes] + * where U(s,a) = c_puct * P(s,a) * sqrt(Σ_b N(s,b)) / (1 + N(s,a)) + * + * @param node Current node + * @param actionKey Action to evaluate + * @param isWhite Whether current player is White + * @returns PUCT value + */ + calculatePUCT(node, actionKey, isWhite) { + const Q = node.Q.get(actionKey) ?? 0; + const N = node.N.get(actionKey) ?? 0; + const P = node.P.get(actionKey) ?? 0; + // Sum of all visit counts at this node + const totalN = Array.from(node.N.values()).reduce((sum, n) => sum + n, 0); + // Exploration term: U(s,a) = c_puct * P(s,a) * sqrt(Σ_b N(s,b) + 1) / (1 + N(s,a)) + // +1 in sqrt to avoid zero exploration when node first expanded + const U = this.config.cPuct * P * Math.sqrt(totalN + 1) / (1 + N); + // Black minimizes Q (flips sign), White maximizes Q + return (isWhite ? Q : -Q) + U; + } + /** + * Select action to play based on visit counts + * Uses temperature to control exploration vs exploitation + * + * @param node Root node + * @param temperature Selection temperature (τ=1 for exploration, τ→0 for greedy) + * @returns Selected move + */ + selectPlayAction(node, temperature) { + const actionKeys = Array.from(node.N.keys()); + if (temperature < 0.01) { + // Greedy: Select action with highest visit count + let bestActionKey = actionKeys[0]; + let bestN = node.N.get(bestActionKey) ?? 0; + for (let i = 1; i < actionKeys.length; i++) { + const actionKey = actionKeys[i]; + const n = node.N.get(actionKey) ?? 0; + if (n > bestN) { + bestN = n; + bestActionKey = actionKey; + } + } + return this.decodeAction(bestActionKey); + } + else { + // Temperature-based sampling: π(a|s) ∝ N(s,a)^(1/τ) + const nValues = actionKeys.map(key => node.N.get(key) ?? 0); + const nPowered = nValues.map(n => Math.pow(n, 1 / temperature)); + const sumN = nPowered.reduce((sum, n) => sum + n, 0); + // Handle edge case: if all visits are 0 or sum is invalid + if (!isFinite(sumN) || sumN <= 0) { + // Fallback to uniform random selection (or use priors) + const randomIndex = Math.floor(Math.random() * actionKeys.length); + return this.decodeAction(actionKeys[randomIndex]); + } + // Sample from distribution + let rand = Math.random() * sumN; + for (let i = 0; i < actionKeys.length; i++) { + rand -= nPowered[i]; + if (rand <= 0) { + return this.decodeAction(actionKeys[i]); + } + } + // Fallback (shouldn't reach here due to floating point precision) + return this.decodeAction(actionKeys[actionKeys.length - 1]); + } + } + /** + * Compute search policy from visit counts + * π(a|s) = N(s,a)^(1/τ) / Σ_b N(s,b)^(1/τ) + * + * @param node Root node + * @param temperature Selection temperature + * @returns Normalized policy distribution + */ + computeSearchPolicy(node, temperature) { + const policy = new Map(); + const actionKeys = Array.from(node.N.keys()); + // Compute π(a|s) ∝ N(s,a)^(1/τ) + const nPowered = actionKeys.map(key => Math.pow(node.N.get(key) ?? 0, 1 / temperature)); + const sumN = nPowered.reduce((sum, n) => sum + n, 0); + // Handle edge case: if all visits are 0 or sum is invalid + if (!isFinite(sumN) || sumN <= 0) { + // Fallback to uniform distribution + const uniform = 1 / actionKeys.length; + for (const key of actionKeys) { + policy.set(key, uniform); + } + return policy; + } + for (let i = 0; i < actionKeys.length; i++) { + const actionKey = actionKeys[i]; + policy.set(actionKey, nPowered[i] / sumN); + } + return policy; + } + /** + * Get root value estimate (weighted average of Q-values) + */ + getRootValue(node) { + const actionKeys = Array.from(node.N.keys()); + const totalN = Array.from(node.N.values()).reduce((sum, n) => sum + n, 0); + if (totalN === 0) { + return 0; + } + let weightedSum = 0; + for (const actionKey of actionKeys) { + const q = node.Q.get(actionKey) ?? 0; + const n = node.N.get(actionKey) ?? 0; + weightedSum += q * n; + } + return weightedSum / totalN; + } + /** + * Add Dirichlet noise to prior probabilities at root + * P(s,a) = (1 - ε) * p_a + ε * η_a + * where η ~ Dir(α) + */ + addDirichletNoise(priors) { + const actionKeys = Array.from(priors.keys()); + const alpha = this.config.dirichletAlpha; + const epsilon = this.config.dirichletEpsilon; + // Generate Dirichlet noise (simplified using Gamma distribution) + const noise = []; + let noiseSum = 0; + for (let i = 0; i < actionKeys.length; i++) { + // Gamma(α, 1) approximation using rejection sampling + const sample = this.sampleGamma(alpha); + noise.push(sample); + noiseSum += sample; + } + // Handle edge case: if all Gamma samples are 0 (extremely unlikely but possible) + if (!isFinite(noiseSum) || noiseSum <= 0) { + // Fallback: use uniform noise (no mixing, keep original priors) + return; + } + // Normalize and mix with priors + for (let i = 0; i < actionKeys.length; i++) { + const actionKey = actionKeys[i]; + const prior = priors.get(actionKey) ?? 0; + const noiseFraction = noise[i] / noiseSum; + priors.set(actionKey, (1 - epsilon) * prior + epsilon * noiseFraction); + } + } + /** + * Sample from Gamma distribution using Marsaglia and Tsang method (2000) + * Used for Dirichlet noise generation + */ + sampleGamma(alpha) { + if (alpha <= 0) { + throw new Error("Gamma distribution alpha must be > 0"); + } + // For alpha < 1, use transformation: sample Gamma(alpha+1) then multiply by U^(1/alpha) + if (alpha < 1) { + const u = Math.random(); + const g = this.sampleGamma(alpha + 1); + return g * Math.pow(u, 1 / alpha); + } + // For alpha >= 1, use Marsaglia and Tsang's method + const d = alpha - 1 / 3; + const c = 1 / Math.sqrt(9 * d); + while (true) { + let x, v; + do { + x = this.randomNormal(); + v = 1 + c * x; + } while (v <= 0); + v = v * v * v; + const u = Math.random(); + // Fast acceptance check + if (u < 1 - 0.0331 * x * x * x * x) { + return d * v; + } + // Fallback acceptance check + if (Math.log(u) < 0.5 * x * x + d * (1 - v + Math.log(v))) { + return d * v; + } + } + } + /** + * Sample from standard normal distribution (Box-Muller transform) + */ + randomNormal() { + const u1 = Math.random(); + const u2 = Math.random(); + return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); + } + /** + * Create a new MCTS node + */ + createNode(state, parent, action) { + return { + state, + parent, + action, + N: new Map(), + W: new Map(), + Q: new Map(), + P: new Map(), + children: new Map(), + expanded: false + }; + } + /** + * Encode move to string key for storage in maps + */ + encodeAction(move) { + if (move.isPass) { + return "pass"; + } + return `${move.x},${move.y},${move.z}`; + } + /** + * Decode string key back to move + */ + decodeAction(key) { + if (key === "pass") { + return { player: "black", isPass: true }; // Player will be updated when applied + } + const [x, y, z] = key.split(",").map(Number); + return { player: "black", x, y, z }; // Player will be updated when applied + } +} +exports.MCTSAgent = MCTSAgent; +//# sourceMappingURL=mctsAgent.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/mctsAgent.js.map b/trigo-web/backend/dist/inc/mctsAgent.js.map new file mode 100644 index 0000000000000000000000000000000000000000..08dbd166f9428389276e691af198bbdc80f08d86 --- /dev/null +++ b/trigo-web/backend/dist/inc/mctsAgent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mctsAgent.js","sourceRoot":"","sources":["../../../inc/mctsAgent.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/modelInferencer.d.ts b/trigo-web/backend/dist/inc/modelInferencer.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b53e7d95286c5e546bba8e50c9707e37ea833cb7 --- /dev/null +++ b/trigo-web/backend/dist/inc/modelInferencer.d.ts @@ -0,0 +1,149 @@ +/** + * ONNX Model Inferencer (Frontend/Backend Common) + * + * Platform-agnostic inference logic that accepts ONNX session from platform-specific code. + * No direct dependency on onnxruntime packages - uses dependency injection pattern. + * + * Adapted from Node.js test_inference.js for cross-platform use + * Provides causal language model inference using GPT-2 ONNX model + * + * Vocabulary Design (128 tokens): + * 0-3: Special tokens (PAD=0, START=1, END=2, VALUE=3) + * 4-7: Reserved for future use + * 10: LF (newline) for multi-line game records + * 32-127: ASCII printable characters (direct identity mapping) + * + * This design uses direct identity mapping: token_id = ascii_value + * No complex formulas needed - simple and efficient. + */ +/** + * Minimal ONNX Tensor interface (platform-agnostic) + */ +export interface OnnxTensor { + readonly data: number[] | Float32Array | Int32Array | BigInt64Array | Uint8Array; + readonly dims: readonly number[]; + readonly type: string; +} +/** + * Minimal ONNX Session interface (platform-agnostic) + */ +export interface OnnxSession { + readonly inputNames: readonly string[]; + readonly outputNames: readonly string[]; + run(feeds: Record): Promise>; +} +/** + * Tensor constructor interface (platform-specific) + */ +export interface TensorConstructor { + new (type: string, data: BigInt64Array | Float32Array | Int32Array | Uint8Array, dims: number[]): OnnxTensor; +} +/** + * Configuration for the inferencer + */ +export interface InferencerConfig { + vocabSize: number; + seqLen: number; + modelPath?: string; +} +/** + * Inference result containing generated tokens and metadata + */ +export interface InferenceResult { + tokens: number[]; + text: string; + logits: Float32Array; + inferenceTime: number; +} +/** + * Evaluation mode inputs for tree attention + */ +export interface EvaluationInputs { + prefixIds: number[]; + evaluatedIds: number[]; + evaluatedMask: number[]; +} +/** + * Evaluation mode output + */ +export interface EvaluationOutput { + logits: Float32Array; + numEvaluated: number; +} +/** + * Model Inferencer for Causal Language Model + * Compatible with both frontend (onnxruntime-web) and backend (onnxruntime-node) + */ +export declare class ModelInferencer { + private session; + private config; + private TensorClass; + private readonly PAD_TOKEN; + private readonly START_TOKEN; + private readonly END_TOKEN; + private readonly VALUE_TOKEN; + constructor(TensorClass: TensorConstructor, config?: Partial); + /** + * Set the inference session (created by platform-specific code) + */ + setSession(session: OnnxSession): void; + /** + * Run basic inference test + */ + testBasicInference(): Promise; + /** + * Generate tokens autoregressively from a prompt + */ + generateText(prompt: string, numTokens?: number): Promise; + /** + * Get model information + */ + getModelInfo(): { + inputs: string[]; + outputs: string[]; + } | null; + /** + * Get configuration + */ + getConfig(): InferencerConfig; + /** + * Run inference with token array input + * Returns raw logits as Float32Array + */ + runInference(tokens: number[]): Promise; + /** + * Run tree attention inference (evaluation mode) + * For models exported with --evaluation flag + * @param inputs - Prefix, evaluated tokens, and attention mask + * @returns Logits for each evaluated position + */ + runEvaluationInference(inputs: EvaluationInputs): Promise; + /** + * Run value prediction inference (for evaluation mode models) + * For models exported with --evaluation-mode flag + * @param tokens - Token IDs (already includes START/END tokens and padding) + * @returns Predicted game outcome value in range [-1, 1] + */ + runValuePrediction(tokens: number[]): Promise; + /** + * Compute softmax for a single position's logits + * @param logits - Full logits array + * @param position - Which evaluated position (0 = last prefix, 1-m = evaluated tokens) + * @returns Probability distribution over vocabulary + */ + softmax(logits: Float32Array, position: number): Float32Array; + /** + * Check if inferencer is ready + */ + isReady(): boolean; + /** + * Destroy the session and free resources + */ + destroy(): void; + private printModelInfo; + private createRandomInput; + private padSequence; + private validateOutput; + private getPredictions; +} +//# sourceMappingURL=modelInferencer.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/modelInferencer.d.ts.map b/trigo-web/backend/dist/inc/modelInferencer.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..90de114248388e727cb74630abb3f318ece0d74b --- /dev/null +++ b/trigo-web/backend/dist/inc/modelInferencer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"modelInferencer.d.ts","sourceRoot":"","sources":["../../../inc/modelInferencer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/modelInferencer.js b/trigo-web/backend/dist/inc/modelInferencer.js new file mode 100644 index 0000000000000000000000000000000000000000..d77530d1ca889c6b8bdc333674d8c5b981b7835d --- /dev/null +++ b/trigo-web/backend/dist/inc/modelInferencer.js @@ -0,0 +1,377 @@ +"use strict"; +/** + * ONNX Model Inferencer (Frontend/Backend Common) + * + * Platform-agnostic inference logic that accepts ONNX session from platform-specific code. + * No direct dependency on onnxruntime packages - uses dependency injection pattern. + * + * Adapted from Node.js test_inference.js for cross-platform use + * Provides causal language model inference using GPT-2 ONNX model + * + * Vocabulary Design (128 tokens): + * 0-3: Special tokens (PAD=0, START=1, END=2, VALUE=3) + * 4-7: Reserved for future use + * 10: LF (newline) for multi-line game records + * 32-127: ASCII printable characters (direct identity mapping) + * + * This design uses direct identity mapping: token_id = ascii_value + * No complex formulas needed - simple and efficient. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ModelInferencer = void 0; +/** + * Model Inferencer for Causal Language Model + * Compatible with both frontend (onnxruntime-web) and backend (onnxruntime-node) + */ +class ModelInferencer { + constructor(TensorClass, config = {}) { + this.session = null; + // TGN tokenizer: Compact 128-token vocabulary with direct ASCII mapping + // 0-3: Special tokens (PAD, START, END, VALUE) + // 4-7: Reserved for future use + // 10: Newline (LF) + // 32-127: ASCII printable characters (direct identity mapping) + this.PAD_TOKEN = 0; + this.START_TOKEN = 1; + this.END_TOKEN = 2; + this.VALUE_TOKEN = 3; + this.TensorClass = TensorClass; + this.config = { + vocabSize: config.vocabSize || 128, // Allow override via config + seqLen: 256, + ...config + }; + } + /** + * Set the inference session (created by platform-specific code) + */ + setSession(session) { + this.session = session; + console.log("[ModelInferencer] ✓ Session set successfully"); + this.printModelInfo(); + } + /** + * Run basic inference test + */ + async testBasicInference() { + if (!this.session) { + throw new Error("Inferencer not initialized. Call setSession() first."); + } + console.log("[ModelInferencer] Running basic inference test..."); + const batchSize = 1; + const seqLen = this.config.seqLen; + // Create random input + const inputIds = this.createRandomInput(batchSize, seqLen); + const inputTensor = new this.TensorClass("int64", inputIds, [batchSize, seqLen]); + // Run inference + const startTime = performance.now(); + const results = await this.session.run({ input_ids: inputTensor }); + const inferenceTime = performance.now() - startTime; + // Get logits + const logits = results.logits; + // Validate output + this.validateOutput(logits, batchSize, seqLen); + // Get predictions + const predictions = this.getPredictions(logits.data, batchSize * seqLen); + // Convert tokens to text + const text = String.fromCharCode(...predictions.slice(0, 100)); + console.log("[ModelInferencer] Inference completed:"); + console.log(` Input shape: [${inputTensor.dims.join(", ")}]`); + console.log(` Output shape: [${logits.dims.join(", ")}]`); + console.log(` Output dtype: ${logits.type}`); + console.log(` Inference time: ${inferenceTime.toFixed(2)}ms`); + console.log(` Sample predictions: [${predictions.slice(0, 10).join(", ")}]`); + const logitsArray = Array.from(logits.data); + console.log(` Logits range: [${Math.min(...logitsArray).toFixed(3)}, ${Math.max(...logitsArray).toFixed(3)}]`); + return { + tokens: predictions, + text, + logits: logits.data, + inferenceTime + }; + } + /** + * Generate tokens autoregressively from a prompt + */ + async generateText(prompt, numTokens = 10) { + if (!this.session) { + throw new Error("Inferencer not initialized. Call setSession() first."); + } + console.log(`[ModelInferencer] Generating ${numTokens} tokens from prompt: "${prompt}"`); + // Convert prompt to token IDs (byte values) + const promptTokens = Array.from(prompt).map((c) => c.charCodeAt(0)); + console.log(` Prompt tokens (${promptTokens.length}): [${promptTokens.join(", ")}]`); + // Start with prompt tokens + const sequence = [...promptTokens]; + const times = []; + // Generate tokens + for (let i = 0; i < numTokens; i++) { + // Pad sequence to fixed length + const paddedSequence = this.padSequence(sequence, this.config.seqLen); + // Create input tensor + const inputIds = new BigInt64Array(paddedSequence.map((t) => BigInt(t))); + const inputTensor = new this.TensorClass("int64", inputIds, [1, this.config.seqLen]); + // Run inference + const startTime = performance.now(); + const results = await this.session.run({ input_ids: inputTensor }); + times.push(performance.now() - startTime); + // Get prediction at the last non-padded position + const logits = results.logits.data; + const lastPos = sequence.length - 1; // Position before padding + const offset = lastPos * this.config.vocabSize; + // Find token with highest logit + let maxIdx = 0; + let maxVal = logits[offset]; + for (let j = 1; j < this.config.vocabSize; j++) { + if (logits[offset + j] > maxVal) { + maxVal = logits[offset + j]; + maxIdx = j; + } + } + sequence.push(maxIdx); + // Stop if END token is generated + if (maxIdx === this.END_TOKEN) { + console.log(" Generated END token, stopping..."); + break; + } + } + // Convert generated tokens to text + const generatedText = String.fromCharCode(...sequence); + const avgTime = times.reduce((a, b) => a + b, 0) / times.length; + console.log(`[ModelInferencer] Generation complete:`); + console.log(` Generated text: "${generatedText}"`); + console.log(` Token sequence (${sequence.length}): [${sequence.join(", ")}]`); + console.log(` Avg inference time: ${avgTime.toFixed(2)}ms`); + console.log(` Tokens/sec: ${(1000 / avgTime).toFixed(2)}`); + return { + tokens: sequence, + text: generatedText, + logits: new Float32Array(), // Not returning full logits for generation + inferenceTime: avgTime + }; + } + /** + * Get model information + */ + getModelInfo() { + if (!this.session) + return null; + return { + inputs: [...this.session.inputNames], + outputs: [...this.session.outputNames] + }; + } + /** + * Get configuration + */ + getConfig() { + return this.config; + } + /** + * Run inference with token array input + * Returns raw logits as Float32Array + */ + async runInference(tokens) { + if (!this.session) { + throw new Error("Inferencer not initialized. Call setSession() first."); + } + const seqLen = this.config.seqLen; + // Prepend START_TOKEN to input + const tokensWithStart = [this.START_TOKEN, ...tokens]; + // Pad to fixed length + const paddedTokens = new BigInt64Array(seqLen); + for (let i = 0; i < seqLen; i++) { + paddedTokens[i] = + i < tokensWithStart.length ? BigInt(tokensWithStart[i]) : BigInt(this.PAD_TOKEN); + } + // Create input tensor + const inputTensor = new this.TensorClass("int64", paddedTokens, [1, seqLen]); + // Run inference + const results = await this.session.run({ input_ids: inputTensor }); + return results.logits.data; + } + /** + * Run tree attention inference (evaluation mode) + * For models exported with --evaluation flag + * @param inputs - Prefix, evaluated tokens, and attention mask + * @returns Logits for each evaluated position + */ + async runEvaluationInference(inputs) { + if (!this.session) { + throw new Error("Inferencer not initialized. Call setSession() first."); + } + const { prefixIds, evaluatedIds, evaluatedMask } = inputs; + const batchSize = 1; + const prefixLen = prefixIds.length; + const m = evaluatedIds.length; + // Convert to BigInt64Array for ONNX int64 tensors + const prefixIdsArray = new BigInt64Array(batchSize * prefixLen); + for (let i = 0; i < prefixLen; i++) { + prefixIdsArray[i] = BigInt(prefixIds[i]); + } + const evaluatedIdsArray = new BigInt64Array(batchSize * m); + for (let i = 0; i < m; i++) { + evaluatedIdsArray[i] = BigInt(evaluatedIds[i]); + } + // Mask is Float32Array + const maskArray = new Float32Array(m * m); + for (let i = 0; i < m * m; i++) { + maskArray[i] = evaluatedMask[i]; + } + // Create ONNX tensors + const prefixIdsTensor = new this.TensorClass("int64", prefixIdsArray, [ + batchSize, + prefixLen + ]); + const evaluatedIdsTensor = new this.TensorClass("int64", evaluatedIdsArray, [batchSize, m]); + const evaluatedMaskTensor = new this.TensorClass("float32", maskArray, [1, m, m]); + // Run inference + const results = await this.session.run({ + prefix_ids: prefixIdsTensor, + evaluated_ids: evaluatedIdsTensor, + evaluated_mask: evaluatedMaskTensor + }); + // Extract logits + const logits = results.logits.data; + // Output shape: [batch, m+1, vocab_size] + // We return flattened array and num_evaluated for reshaping + return { + logits, + numEvaluated: m + }; + } + /** + * Run value prediction inference (for evaluation mode models) + * For models exported with --evaluation-mode flag + * @param tokens - Token IDs (already includes START/END tokens and padding) + * @returns Predicted game outcome value in range [-1, 1] + */ + async runValuePrediction(tokens) { + if (!this.session) { + throw new Error("Inferencer not initialized. Call setSession() first."); + } + const seqLen = tokens.length; + // Convert to BigInt64Array for ONNX int64 tensors + const inputIds = new BigInt64Array(seqLen); + for (let i = 0; i < seqLen; i++) { + inputIds[i] = BigInt(tokens[i]); + } + // Create input tensor [1, seq_len] + const inputTensor = new this.TensorClass("int64", inputIds, [1, seqLen]); + // Run inference + const results = await this.session.run({ + input_ids: inputTensor + }); + // Extract value + // Output shape: [batch_size] = [1] + // For evaluation models, output name is "values" not "logits" + const values = results.values; + if (!values) { + throw new Error("Evaluation model did not return 'values' output. Check model export."); + } + const predictedValue = values.data[0]; + return predictedValue; + } + /** + * Compute softmax for a single position's logits + * @param logits - Full logits array + * @param position - Which evaluated position (0 = last prefix, 1-m = evaluated tokens) + * @returns Probability distribution over vocabulary + */ + softmax(logits, position) { + const vocabSize = this.config.vocabSize; + const offset = position * vocabSize; + const probs = new Float32Array(vocabSize); + // Find max for numerical stability + let maxLogit = -Infinity; + for (let i = 0; i < vocabSize; i++) { + maxLogit = Math.max(maxLogit, logits[offset + i]); + } + // Compute exp and sum + let sumExp = 0; + for (let i = 0; i < vocabSize; i++) { + probs[i] = Math.exp(logits[offset + i] - maxLogit); + sumExp += probs[i]; + } + // Normalize + for (let i = 0; i < vocabSize; i++) { + probs[i] /= sumExp; + } + return probs; + } + /** + * Check if inferencer is ready + */ + isReady() { + return this.session !== null; + } + /** + * Destroy the session and free resources + */ + destroy() { + this.session = null; + console.log("[ModelInferencer] Session destroyed"); + } + // Private helper methods + printModelInfo() { + if (!this.session) + return; + console.log("[ModelInferencer] Model Information:"); + console.log(" Inputs:"); + this.session.inputNames.forEach((name, i) => { + console.log(` [${i}] ${name}`); + }); + console.log(" Outputs:"); + this.session.outputNames.forEach((name, i) => { + console.log(` [${i}] ${name}`); + }); + } + createRandomInput(batchSize, seqLen) { + const size = batchSize * seqLen; + const data = new BigInt64Array(size); + for (let i = 0; i < size; i++) { + data[i] = BigInt(Math.floor(Math.random() * this.config.vocabSize)); + } + return data; + } + padSequence(tokens, targetLen) { + const padded = [...tokens]; + while (padded.length < targetLen) { + padded.push(this.PAD_TOKEN); + } + return padded.slice(0, targetLen); // Truncate if too long + } + validateOutput(logits, batchSize, seqLen) { + const expectedShape = [batchSize, seqLen, this.config.vocabSize]; + if (logits.dims.length !== 3) { + throw new Error(`Expected 3D output, got ${logits.dims.length}D`); + } + if (logits.dims[0] !== expectedShape[0] || + logits.dims[1] !== expectedShape[1] || + logits.dims[2] !== expectedShape[2]) { + throw new Error(`Shape mismatch! Expected [${expectedShape.join(", ")}], ` + + `got [${logits.dims.join(", ")}]`); + } + if (logits.type !== "float32") { + throw new Error(`Expected float32 output, got ${logits.type}`); + } + } + getPredictions(logitsData, numPositions) { + const predictions = []; + for (let i = 0; i < numPositions; i++) { + let maxIdx = 0; + let maxVal = logitsData[i * this.config.vocabSize]; + for (let j = 1; j < this.config.vocabSize; j++) { + const val = logitsData[i * this.config.vocabSize + j]; + if (val > maxVal) { + maxVal = val; + maxIdx = j; + } + } + predictions.push(maxIdx); + } + return predictions; + } +} +exports.ModelInferencer = ModelInferencer; +//# sourceMappingURL=modelInferencer.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/modelInferencer.js.map b/trigo-web/backend/dist/inc/modelInferencer.js.map new file mode 100644 index 0000000000000000000000000000000000000000..9215d33d5a39aedc90052d5c8f11fa477ec80d3c --- /dev/null +++ b/trigo-web/backend/dist/inc/modelInferencer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"modelInferencer.js","sourceRoot":"","sources":["../../../inc/modelInferencer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs b/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs new file mode 100644 index 0000000000000000000000000000000000000000..4f53012d63a06abc4433c363600eb31a8d680a3f --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs @@ -0,0 +1,793 @@ +"use strict"; +/* parser generated by jison 0.4.18 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var tgn = (function () { + var o = function (k, v, o, l) { for (o = o || {}, l = k.length; l--; o[k[l]] = v) + ; return o; }, $V0 = [1, 7], $V1 = [2, 25], $V2 = [6, 8, 49], $V3 = [1, 32], $V4 = [6, 49], $V5 = [11, 49], $V6 = [11, 48], $V7 = [1, 51], $V8 = [1, 52], $V9 = [1, 53], $Va = [6, 36, 37, 38, 49]; + var parser = { trace: function trace() { }, + yy: {}, + symbols_: { "error": 2, "game": 3, "tag_section": 4, "move_section": 5, "EOF": 6, "tag_pair": 7, "[": 8, "tag_name": 9, "STRING": 10, "]": 11, "TAG_RESULT": 12, "game_result": 13, "TAG_BOARD": 14, "board_shape": 15, "TAG_EVENT": 16, "TAG_SITE": 17, "TAG_DATE": 18, "TAG_ROUND": 19, "TAG_BLACK": 20, "TAG_WHITE": 21, "TAG_HANDICAP": 22, "TAG_RULES": 23, "TAG_TIMECONTROL": 24, "TAG_ANNOTATOR": 25, "TAG_APPLICATION": 26, "TAG_NAME": 27, "move_sequence": 28, "move_sequence_intact": 29, "move_sequence_truncated": 30, "move_round": 31, "move_round_half": 32, "number": 33, "DOT": 34, "move_action": 35, "PASS": 36, "RESIGN": 37, "COORDINATE": 38, "win": 39, "conquer": 40, "=": 41, "*": 42, "RESULT_BLACK": 43, "RESULT_WHITE": 44, "conquer_unit": 45, "POINTS": 46, "STONES": 47, "TIMES": 48, "NUMBER": 49, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 6: "EOF", 8: "[", 10: "STRING", 11: "]", 12: "TAG_RESULT", 14: "TAG_BOARD", 16: "TAG_EVENT", 17: "TAG_SITE", 18: "TAG_DATE", 19: "TAG_ROUND", 20: "TAG_BLACK", 21: "TAG_WHITE", 22: "TAG_HANDICAP", 23: "TAG_RULES", 24: "TAG_TIMECONTROL", 25: "TAG_ANNOTATOR", 26: "TAG_APPLICATION", 27: "TAG_NAME", 34: "DOT", 36: "PASS", 37: "RESIGN", 38: "COORDINATE", 41: "=", 42: "*", 43: "RESULT_BLACK", 44: "RESULT_WHITE", 46: "POINTS", 47: "STONES", 48: "TIMES", 49: "NUMBER" }, + productions_: [0, [3, 3], [3, 2], [3, 2], [3, 1], [4, 1], [4, 2], [7, 4], [7, 4], [7, 4], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [5, 1], [28, 1], [28, 1], [29, 0], [29, 2], [30, 2], [31, 4], [32, 3], [35, 1], [35, 1], [35, 1], [13, 1], [13, 2], [13, 1], [13, 1], [39, 1], [39, 1], [40, 2], [45, 1], [45, 1], [15, 1], [15, 3], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { + /* this == yyval */ + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return { + tags: $$[$0 - 2], + moves: $$[$0 - 1], + success: true + }; + break; + case 2: + return { + tags: $$[$0 - 1], + moves: null, + success: true + }; + break; + case 3: + return { + tags: {}, + moves: $$[$0 - 1], + success: true + }; + break; + case 4: + return { + tags: {}, + moves: null, + success: true + }; + break; + case 5: + case 23: + case 24: + this.$ = $$[$0]; + break; + case 6: + this.$ = Object.assign({}, $$[$0 - 1], $$[$0]); + break; + case 7: + const tagName = $$[$0 - 2]; + const tagValue = $$[$0 - 1].slice(1, -1); // Remove quotes + this.$ = { [tagName]: tagValue }; + break; + case 8: + this.$ = $$[$0 - 1]; + break; + case 9: + this.$ = ({ [$$[$0 - 2]]: $$[$0 - 1] }); + break; + case 21: + this.$ = yytext; + break; + case 25: + this.$ = []; + break; + case 26: + case 27: + this.$ = $$[$0 - 1].concat([$$[$0]]); + break; + case 28: + this.$ = ({ round: $$[$0 - 3], action_black: $$[$0 - 1], action_white: $$[$0] }); + break; + case 29: + this.$ = ({ round: $$[$0 - 2], action_black: $$[$0] }); + break; + case 30: + this.$ = ({ type: 'pass' }); + break; + case 31: + this.$ = ({ type: 'resign' }); + break; + case 32: + // Placeholder: Parse coordinate notation + this.$ = { + type: 'move', + position: yytext + }; + break; + case 33: + this.$ = ({ Result: $$[$0] }); + break; + case 34: + this.$ = ({ Result: $$[$0 - 1], Conquer: $$[$0] }); + break; + case 35: + this.$ = ({ Result: "draw" }); + break; + case 36: + this.$ = ({ Result: "unknown" }); + break; + case 37: + this.$ = "black win"; + break; + case 38: + this.$ = "white win"; + break; + case 39: + this.$ = ({ n: $$[$0 - 1], unit: $$[$0] }); + break; + case 42: + this.$ = [$$[$0]]; + break; + case 43: + this.$ = $$[$0 - 2].concat($$[$0]); + break; + case 44: + this.$ = parseInt($$[$0]); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 4], 7: 5, 8: $V0, 28: 6, 29: 8, 30: 9, 49: $V1 }, { 1: [3] }, { 5: 10, 6: [1, 11], 7: 12, 8: $V0, 28: 6, 29: 8, 30: 9, 49: $V1 }, { 6: [1, 13] }, { 1: [2, 4] }, o($V2, [2, 5]), { 6: [2, 22] }, { 9: 14, 12: [1, 15], 14: [1, 16], 16: [1, 17], 17: [1, 18], 18: [1, 19], 19: [1, 20], 20: [1, 21], 21: [1, 22], 22: [1, 23], 23: [1, 24], 24: [1, 25], 25: [1, 26], 26: [1, 27], 27: [1, 28] }, { 6: [2, 23], 31: 29, 32: 30, 33: 31, 49: $V3 }, { 6: [2, 24] }, { 6: [1, 33] }, { 1: [2, 2] }, o($V2, [2, 6]), { 1: [2, 3] }, { 10: [1, 34] }, { 13: 35, 39: 36, 41: [1, 37], 42: [1, 38], 43: [1, 39], 44: [1, 40] }, { 15: 41, 33: 42, 49: $V3 }, { 10: [2, 10] }, { 10: [2, 11] }, { 10: [2, 12] }, { 10: [2, 13] }, { 10: [2, 14] }, { 10: [2, 15] }, { 10: [2, 16] }, { 10: [2, 17] }, { 10: [2, 18] }, { 10: [2, 19] }, { 10: [2, 20] }, { 10: [2, 21] }, o($V4, [2, 26]), { 6: [2, 27] }, { 34: [1, 43] }, o([11, 34, 46, 47, 48], [2, 44]), { 1: [2, 1] }, { 11: [1, 44] }, { 11: [1, 45] }, { 11: [2, 33], 33: 47, 40: 46, 49: $V3 }, { 11: [2, 35] }, { 11: [2, 36] }, o($V5, [2, 37]), o($V5, [2, 38]), { 11: [1, 48], 48: [1, 49] }, o($V6, [2, 42]), { 35: 50, 36: $V7, 37: $V8, 38: $V9 }, o($V2, [2, 7]), o($V2, [2, 8]), { 11: [2, 34] }, { 45: 54, 46: [1, 55], 47: [1, 56] }, o($V2, [2, 9]), { 33: 57, 49: $V3 }, { 6: [2, 29], 35: 58, 36: $V7, 37: $V8, 38: $V9 }, o($Va, [2, 30]), o($Va, [2, 31]), o($Va, [2, 32]), { 11: [2, 39] }, { 11: [2, 40] }, { 11: [2, 41] }, o($V6, [2, 43]), o($V4, [2, 28])], + defaultActions: { 4: [2, 4], 6: [2, 22], 9: [2, 24], 11: [2, 2], 13: [2, 3], 17: [2, 10], 18: [2, 11], 19: [2, 12], 20: [2, 13], 21: [2, 14], 22: [2, 15], 23: [2, 16], 24: [2, 17], 25: [2, 18], 26: [2, 19], 27: [2, 20], 28: [2, 21], 30: [2, 27], 33: [2, 1], 37: [2, 35], 38: [2, 36], 46: [2, 34], 54: [2, 39], 55: [2, 40], 56: [2, 41] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } + else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } + else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: var lex = function () { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } + else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } + else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } + else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } }; + /* ========== Additional JavaScript Code ========== */ + // Parser configuration + parser.yy = { + // Helper functions can be added here + parseError: function (str, hash) { + throw new Error('Parse error: ' + str); + } + }; + /* generated by jison-lex 0.3.4 */ + var lexer = (function () { + var lexer = ({ + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } + else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function (input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } + else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function () { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } + else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function (n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function (match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? + lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } + else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, + // return next match in input + next: function () { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } + else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } + else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } + else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } + else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } + else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } + else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } + else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } + else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + var YYSTATE = YY_START; + switch ($avoiding_name_collisions) { + case 0: /* skip whitespace */ + break; + case 1: /* skip newlines */ + break; + case 2: /* skip line comments */ + break; + case 3: /* skip block comments */ + break; + case 4: + return 8; + break; + case 5: + return 11; + break; + case 6: + return 10; + break; + case 7: + return 16; + break; + case 8: + return 17; + break; + case 9: + return 18; + break; + case 10: + return 19; + break; + case 11: + return 20; + break; + case 12: + return 21; + break; + case 13: + return 12; + break; + case 14: + return 14; + break; + case 15: + return 22; + break; + case 16: + return 23; + break; + case 17: + return 24; + break; + case 18: + return 25; + break; + case 19: + return 26; + break; + case 20: + return 43; + break; + case 21: + return 44; + break; + case 22: + return 41; /* draw */ + break; + case 23: + return 42; /* unknown */ + break; + case 24: + return 49; + break; + case 25: + return 34; + break; + case 26: + return 36; + break; + case 27: + return 37; + break; + case 28: + return 46; + break; + case 29: + return 47; + break; + case 30: + return 48; + break; + case 31: + return 38; + break; + case 32: + return 27; + break; + case 33: + return 6; + break; + case 34: + return 'INVALID'; + break; + } + }, + rules: [/^(?:\s+)/, /^(?:\n)/, /^(?:;[^\n]*)/, /^(?:\{[^}]*\})/, /^(?:\[)/, /^(?:\])/, /^(?:"([^\\\"]|\\.)*")/, /^(?:Event\b)/, /^(?:Site\b)/, /^(?:Date\b)/, /^(?:Round\b)/, /^(?:Black\b)/, /^(?:White\b)/, /^(?:Result\b)/, /^(?:Board\b)/, /^(?:Handicap\b)/, /^(?:Rules\b)/, /^(?:TimeControl\b)/, /^(?:Annotator\b)/, /^(?:Application\b)/, /^(?:B\+)/, /^(?:W\+)/, /^(?:=)/, /^(?:\*)/, /^(?:[1-9][0-9]*)/, /^(?:\.)/, /^(?:pass\b)/, /^(?:resign\b)/, /^(?:points\b)/, /^(?:stones\b)/, /^(?:[x](?=[1-9]))/, /^(?:[a-z0]+)/, /^(?:[A-Z][A-Za-z0-9_]*)/, /^(?:$)/, /^(?:.)/], + conditions: { "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34], "inclusive": true } } + }); + return lexer; + })(); + parser.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser; + parser.Parser = Parser; + return new Parser; +})(); +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { + exports.parser = tgn; + exports.Parser = tgn.Parser; + exports.parse = function () { return tgn.parse.apply(tgn, arguments); }; + exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: ' + args[0] + ' FILE'); + process.exit(1); + } + var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); + return exports.parser.parse(source); + }; + if (typeof module !== 'undefined' && require.main === module) { + exports.main(process.argv.slice(1)); + } +} +//# sourceMappingURL=tgn.jison.cjs.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs.map b/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs.map new file mode 100644 index 0000000000000000000000000000000000000000..dd5d0dfca8d2ccba9566b0fb3020ac2509ba71ba --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgn.jison.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"tgn.jison.cjs","sourceRoot":"","sources":["../../../../inc/tgn/tgn.jison.cjs"],"names":[],"mappings":";AAAA,sCAAsC;AACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuEE;AACF,IAAI,GAAG,GAAG,CAAC;IACX,IAAI,CAAC,GAAC,UAAS,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,IAAE,KAAI,CAAC,GAAC,CAAC,IAAE,EAAE,EAAC,CAAC,GAAC,CAAC,CAAC,MAAM,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC;QAAC,CAAC,CAAA,OAAO,CAAC,CAAA,CAAA,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,EAAE,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,EAAE,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAG,GAAC,CAAC,CAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,CAAC,CAAC;IAC7M,IAAI,MAAM,GAAG,EAAC,KAAK,EAAE,SAAS,KAAK,KAAM,CAAC;QAC1C,EAAE,EAAE,EAAE;QACN,QAAQ,EAAE,EAAC,OAAO,EAAC,CAAC,EAAC,MAAM,EAAC,CAAC,EAAC,aAAa,EAAC,CAAC,EAAC,cAAc,EAAC,CAAC,EAAC,KAAK,EAAC,CAAC,EAAC,UAAU,EAAC,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,UAAU,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,YAAY,EAAC,EAAE,EAAC,aAAa,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,aAAa,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,iBAAiB,EAAC,EAAE,EAAC,eAAe,EAAC,EAAE,EAAC,iBAAiB,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,eAAe,EAAC,EAAE,EAAC,sBAAsB,EAAC,EAAE,EAAC,yBAAyB,EAAC,EAAE,EAAC,YAAY,EAAC,EAAE,EAAC,iBAAiB,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,KAAK,EAAC,EAAE,EAAC,aAAa,EAAC,EAAE,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,YAAY,EAAC,EAAE,EAAC,KAAK,EAAC,EAAE,EAAC,SAAS,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,SAAS,EAAC,CAAC,EAAC,MAAM,EAAC,CAAC,EAAC;QACxtB,UAAU,EAAE,EAAC,CAAC,EAAC,OAAO,EAAC,CAAC,EAAC,KAAK,EAAC,CAAC,EAAC,GAAG,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,YAAY,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,WAAW,EAAC,EAAE,EAAC,iBAAiB,EAAC,EAAE,EAAC,eAAe,EAAC,EAAE,EAAC,iBAAiB,EAAC,EAAE,EAAC,UAAU,EAAC,EAAE,EAAC,KAAK,EAAC,EAAE,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,YAAY,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,cAAc,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,QAAQ,EAAC;QAC3a,YAAY,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAC,CAAC,C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AC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,CAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAE,EAAC,EAAE,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,EAAC,EAAE,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,GAAG,EAAC,CAAC,CAAC,EAAC,EAAE,CAAC,CAAC,CAAC;QAC7lC,cAAc,EAAE,EAAC,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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts b/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..770c68a3ee1587b7d70e6ad98b75bbf402b22bc7 --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts @@ -0,0 +1,98 @@ +/** + * TGN Parser TypeScript Wrapper + * + * Wraps the jison-generated parser with TypeScript types + * + * Based on lotus project architecture: + * - Use jison npm package for grammar compilation at build time + * - Generate parser to .js file in build phase + * - Use synchronous parsing (no async needed) + * - Works in both browser and Node.js environments + */ +/** + * Parsed move action - represents a single player's action in a round + */ +export interface ParsedMoveAction { + type: "move" | "pass" | "resign"; + position?: string; +} +/** + * Parsed move round - contains both black and white moves + */ +export interface ParsedMoveRound { + round: number; + action_black: ParsedMoveAction; + action_white?: ParsedMoveAction; +} +/** + * Parsed game result + */ +export interface ParsedGameResult { + Result: string; + Conquer?: { + n: number; + unit: string; + }; +} +/** + * Parsed TGN tags (metadata) + */ +export interface ParsedTags { + Event?: string; + Site?: string; + Date?: string; + Round?: string; + Black?: string; + White?: string; + Result?: string; + Board?: number[]; + Handicap?: string; + Rules?: string; + TimeControl?: string; + Annotator?: string; + Application?: string; + [key: string]: string | number[] | ParsedGameResult | undefined; +} +/** + * Parser output structure + */ +export interface TGNParseResult { + tags: ParsedTags; + moves: ParsedMoveRound[] | null; + success: boolean; +} +/** + * Parser error with position information + */ +export declare class TGNParseError extends Error { + line?: number; + column?: number; + hash?: any; + constructor(message: string, line?: number, column?: number, hash?: any); +} +/** + * Set the parser module (called by initialization code) + * This allows the pre-built parser to be used + */ +export declare function setParserModule(module: any): void; +/** + * Parse TGN string and return structured data + * Synchronous parsing (no async needed) + * + * @param tgnString - TGN formatted game notation + * @returns Parsed game data with tags and moves + * @throws TGNParseError if parsing fails + */ +export declare function parseTGN(tgnString: string): TGNParseResult; +/** + * Validate TGN string without fully parsing + * Synchronous validation (no async needed) + * + * @param tgnString - TGN formatted game notation + * @returns Object with valid flag and error message if invalid + */ +export declare function validateTGN(tgnString: string): { + valid: boolean; + error?: string; +}; +//# sourceMappingURL=tgnParser.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts.map b/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..e10a30968e79ac15d474942a3d5fa110b5696ecb --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgnParser.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tgnParser.d.ts","sourceRoot":"","sources":["../../../../inc/tgn/tgnParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,gBAAgB,CAAC;IAC/B,YAAY,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACT,CAAC,EAAE,MAAM,CAAC;QACV,IAAI,EAAE,MAAM,CAAC;KACb,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAAC;CAChE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAG/B,IAAI,CAAC,EAAE,MAAM;IACb,MAAM,CAAC,EAAE,MAAM;IACf,IAAI,CAAC,EAAE,GAAG;gBAHjB,OAAO,EAAE,MAAM,EACR,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,GAAG;CAKlB;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAEjD;AAgBD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAmB1D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAUjF"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgnParser.js b/trigo-web/backend/dist/inc/tgn/tgnParser.js new file mode 100644 index 0000000000000000000000000000000000000000..8f0bdbc993357dbea92071c5f686e46378a46d9d --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgnParser.js @@ -0,0 +1,92 @@ +"use strict"; +/** + * TGN Parser TypeScript Wrapper + * + * Wraps the jison-generated parser with TypeScript types + * + * Based on lotus project architecture: + * - Use jison npm package for grammar compilation at build time + * - Generate parser to .js file in build phase + * - Use synchronous parsing (no async needed) + * - Works in both browser and Node.js environments + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TGNParseError = void 0; +exports.setParserModule = setParserModule; +exports.parseTGN = parseTGN; +exports.validateTGN = validateTGN; +/** + * Parser error with position information + */ +class TGNParseError extends Error { + constructor(message, line, column, hash) { + super(message); + this.line = line; + this.column = column; + this.hash = hash; + this.name = "TGNParseError"; + } +} +exports.TGNParseError = TGNParseError; +// Will be set by initialization code or build process +let parserModule = null; +/** + * Set the parser module (called by initialization code) + * This allows the pre-built parser to be used + */ +function setParserModule(module) { + parserModule = module; +} +/** + * Get the parser module + * Throws error if parser not loaded + */ +function getParser() { + if (!parserModule) { + throw new Error("TGN parser not loaded. Please ensure the parser has been built.\n" + + "Run: npm run build:parsers"); + } + return parserModule; +} +/** + * Parse TGN string and return structured data + * Synchronous parsing (no async needed) + * + * @param tgnString - TGN formatted game notation + * @returns Parsed game data with tags and moves + * @throws TGNParseError if parsing fails + */ +function parseTGN(tgnString) { + const parser = getParser(); + if (!parser.parse) { + throw new Error("TGN parser parse method not available"); + } + try { + const result = parser.parse(tgnString); + return result; + } + catch (error) { + // Wrap jison errors with our custom error type + throw new TGNParseError(error.message || "Unknown parse error", error.hash?.line, error.hash?.loc?.first_column, error.hash); + } +} +/** + * Validate TGN string without fully parsing + * Synchronous validation (no async needed) + * + * @param tgnString - TGN formatted game notation + * @returns Object with valid flag and error message if invalid + */ +function validateTGN(tgnString) { + try { + parseTGN(tgnString); + return { valid: true }; + } + catch (error) { + return { + valid: false, + error: error.message || "Unknown validation error" + }; + } +} +//# sourceMappingURL=tgnParser.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/tgn/tgnParser.js.map b/trigo-web/backend/dist/inc/tgn/tgnParser.js.map new file mode 100644 index 0000000000000000000000000000000000000000..ea5c92e0e5997eed155fcd739f6a1c237497814b --- /dev/null +++ b/trigo-web/backend/dist/inc/tgn/tgnParser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tgnParser.js","sourceRoot":"","sources":["../../../../inc/tgn/tgnParser.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAiFH,0CAEC;AAwBD,4BAmBC;AASD,kCAUC;AAtFD;;GAEG;AACH,MAAa,aAAc,SAAQ,KAAK;IACvC,YACC,OAAe,EACR,IAAa,EACb,MAAe,EACf,IAAU;QAEjB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,SAAI,GAAJ,IAAI,CAAS;QACb,WAAM,GAAN,MAAM,CAAS;QACf,SAAI,GAAJ,IAAI,CAAM;QAGjB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC7B,CAAC;CACD;AAVD,sCAUC;AAED,sDAAsD;AACtD,IAAI,YAAY,GAAQ,IAAI,CAAC;AAE7B;;;GAGG;AACH,SAAgB,eAAe,CAAC,MAAW;IAC1C,YAAY,GAAG,MAAM,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS;IACjB,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACd,mEAAmE;YAClE,4BAA4B,CAC7B,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,QAAQ,CAAC,SAAiB;IACzC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,MAAwB,CAAC;IACjC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACrB,+CAA+C;QAC/C,MAAM,IAAI,aAAa,CACtB,KAAK,CAAC,OAAO,IAAI,qBAAqB,EACtC,KAAK,CAAC,IAAI,EAAE,IAAI,EAChB,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAC7B,KAAK,CAAC,IAAI,CACV,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,SAAiB;IAC5C,IAAI,CAAC;QACJ,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACrB,OAAO;YACN,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,0BAA0B;SAClD,CAAC;IACH,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts b/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..d67596c409842afbdc32e17463aeaf38419b878e --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts @@ -0,0 +1,35 @@ +/** + * Encode a position to TGN coordinate string. + * + * Coordinate system: + * - '0' represents the center position on an axis + * - 'a', 'b', 'c', ... from one edge toward center + * - 'z', 'y', 'x', ... from opposite edge toward center + * + * @param pos - Position array [x, y, z, ...] with 0-based indices + * @param boardShape - Board dimensions [sizeX, sizeY, sizeZ, ...] + * @returns TGN coordinate string (e.g., "000", "aa0", "bzz", "aa", "0") + * + * @example + * encodeAb0yz([2, 2, 2], [5, 5, 5]) // "000" - center of 5x5x5 board + * encodeAb0yz([0, 0, 2], [5, 5, 5]) // "aa0" - corner + * encodeAb0yz([4, 2, 2], [5, 5, 5]) // "z00" + * encodeAb0yz([0, 0, 0], [19, 19, 1]) // "aa" - 2D board (trailing 1 ignored) + */ +declare const encodeAb0yz: (pos: number[], boardShape: number[]) => string; +/** + * Decode a TGN coordinate string to position array. + * + * @param code - TGN coordinate string (e.g., "000", "aa0", "bzz", "aa", "0") + * @param boardShape - Board dimensions [sizeX, sizeY, sizeZ, ...] + * @returns Position array [x, y, z, ...] with 0-based indices + * + * @example + * decodeAb0yz("000", [5, 5, 5]) // [2, 2, 2] - center + * decodeAb0yz("aa0", [5, 5, 5]) // [0, 0, 2] + * decodeAb0yz("z00", [5, 5, 5]) // [4, 2, 2] + * decodeAb0yz("aa", [19, 19, 1]) // [0, 0, 0] - 2D board + */ +declare const decodeAb0yz: (code: string, boardShape: number[]) => number[]; +export { encodeAb0yz, decodeAb0yz }; +//# sourceMappingURL=ab0yz.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts.map b/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..8d8dadf44bd38f3f40112303300bf6b50cff0b81 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/ab0yz.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ab0yz.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/ab0yz.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,EAAE,YAAY,MAAM,EAAE,KAAG,MAuB1D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,YAAY,MAAM,EAAE,KAAG,MAAM,EA+D/D,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/ab0yz.js b/trigo-web/backend/dist/inc/trigo/ab0yz.js new file mode 100644 index 0000000000000000000000000000000000000000..dae2fcc9a629722467fd033bb1e031a6e5f2be0e --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/ab0yz.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeAb0yz = exports.encodeAb0yz = void 0; +// remove ones at tail +const compactShape = (shape) => shape[shape.length - 1] === 1 ? compactShape(shape.slice(0, shape.length - 1)) : shape; +/** + * Encode a position to TGN coordinate string. + * + * Coordinate system: + * - '0' represents the center position on an axis + * - 'a', 'b', 'c', ... from one edge toward center + * - 'z', 'y', 'x', ... from opposite edge toward center + * + * @param pos - Position array [x, y, z, ...] with 0-based indices + * @param boardShape - Board dimensions [sizeX, sizeY, sizeZ, ...] + * @returns TGN coordinate string (e.g., "000", "aa0", "bzz", "aa", "0") + * + * @example + * encodeAb0yz([2, 2, 2], [5, 5, 5]) // "000" - center of 5x5x5 board + * encodeAb0yz([0, 0, 2], [5, 5, 5]) // "aa0" - corner + * encodeAb0yz([4, 2, 2], [5, 5, 5]) // "z00" + * encodeAb0yz([0, 0, 0], [19, 19, 1]) // "aa" - 2D board (trailing 1 ignored) + */ +const encodeAb0yz = (pos, boardShape) => { + const compactedShape = compactShape(boardShape); + const result = []; + for (let i = 0; i < compactedShape.length; i++) { + const size = compactedShape[i]; + const center = (size - 1) / 2; + const index = pos[i]; + if (index === center) { + // Center position + result.push("0"); + } + else if (index < center) { + // Left side: a, b, c, ... + result.push(String.fromCharCode(97 + index)); // 'a' = 97 + } + else { + // Right side: z, y, x, ... + const offset = size - 1 - index; + result.push(String.fromCharCode(122 - offset)); // 'z' = 122 + } + } + return result.join(""); +}; +exports.encodeAb0yz = encodeAb0yz; +/** + * Decode a TGN coordinate string to position array. + * + * @param code - TGN coordinate string (e.g., "000", "aa0", "bzz", "aa", "0") + * @param boardShape - Board dimensions [sizeX, sizeY, sizeZ, ...] + * @returns Position array [x, y, z, ...] with 0-based indices + * + * @example + * decodeAb0yz("000", [5, 5, 5]) // [2, 2, 2] - center + * decodeAb0yz("aa0", [5, 5, 5]) // [0, 0, 2] + * decodeAb0yz("z00", [5, 5, 5]) // [4, 2, 2] + * decodeAb0yz("aa", [19, 19, 1]) // [0, 0, 0] - 2D board + */ +const decodeAb0yz = (code, boardShape) => { + const compactedShape = compactShape(boardShape); + if (code.length !== compactedShape.length) { + throw new Error(`Invalid TGN coordinate: "${code}" (must be ${compactedShape.length} characters for board shape ${boardShape.join("x")})`); + } + const result = []; + for (let i = 0; i < compactedShape.length; i++) { + const char = code[i]; + const size = compactedShape[i]; + const center = (size - 1) / 2; + if (char === "0") { + // Center position + console.assert(Number.isInteger(center)); + result.push(center); + } + else { + const charCode = char.charCodeAt(0); + if (charCode >= 97 && charCode <= 122) { + // 'a' to 'z' + // Calculate distance from 'a' and 'z' + const distFromA = charCode - 97; + const distFromZ = 122 - charCode; + // Determine if it's left side (closer to 'a') or right side (closer to 'z') + if (distFromA < distFromZ) { + // Left side: a=0, b=1, c=2, ... + const index = distFromA; + if (index >= center) { + throw new Error(`Invalid TGN coordinate: "${code}" (position ${index} >= center ${center} on axis ${i})`); + } + result.push(index); + } + else { + // Right side: z=size-1, y=size-2, x=size-3, ... + const index = size - 1 - distFromZ; + if (index <= center) { + throw new Error(`Invalid TGN coordinate: "${code}" (position ${index} <= center ${center} on axis ${i})`); + } + result.push(index); + } + } + else { + throw new Error(`Invalid TGN coordinate: "${code}" (character '${char}' at position ${i} must be '0' or a-z)`); + } + } + } + // Fill remaining dimensions with 0 if boardShape has trailing 1s + while (result.length < boardShape.length) { + result.push(0); + } + return result; +}; +exports.decodeAb0yz = decodeAb0yz; +//# sourceMappingURL=ab0yz.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/ab0yz.js.map b/trigo-web/backend/dist/inc/trigo/ab0yz.js.map new file mode 100644 index 0000000000000000000000000000000000000000..aa5bc7d2dbfdc8d3c813cf0e4769250eaca7cb8c --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/ab0yz.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ab0yz.js","sourceRoot":"","sources":["../../../../inc/trigo/ab0yz.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/game.d.ts b/trigo-web/backend/dist/inc/trigo/game.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e188ffa28912b44e15b2a9a2e5b4ee779679a0c --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/game.d.ts @@ -0,0 +1,357 @@ +/** + * TrigoGame Class - Main Game State Management + * + * Modern reimplementation of prototype's trigo.Game + * Integrates game state, move history, and game logic in a single class + * + * Equivalent to: third_party/klstrigo/Source/static/js/trigo.game.js:75-601 + */ +import type { Position, Stone, BoardShape } from "./types"; +import { type TerritoryResult } from "./gameUtils"; +export { StoneType } from "./gameUtils"; +/** + * Step Types - Different types of moves in the game + * Equivalent to trigo.Game.StepType in prototype + */ +export declare enum StepType { + DROP = 0,// Place a stone + PASS = 1,// Pass turn + SURRENDER = 2,// Resign/surrender + UNDO = 3 +} +/** + * Game Status enumeration + */ +export type GameStatus = "idle" | "playing" | "paused" | "finished"; +/** + * Game Result information + */ +export interface GameResult { + winner: "black" | "white" | "draw"; + reason: "resignation" | "timeout" | "completion" | "double-pass"; + score?: TerritoryResult; +} +/** + * Step - Represents a single move in the game + * Equivalent to step objects in prototype's StepHistory + */ +export interface Step { + type: StepType; + position?: Position; + player: Stone; + capturedPositions?: Position[]; + timestamp: number; +} +/** + * Game Callbacks - Event handlers for game state changes + * Equivalent to Callbacks in prototype's trigo.Game constructor + */ +export interface GameCallbacks { + onStepAdvance?: (step: Step, history: Step[]) => void; + onStepBack?: (step: Step, history: Step[]) => void; + onCapture?: (capturedPositions: Position[]) => void; + onWin?: (winner: Stone) => void; + onTerritoryChange?: (territory: TerritoryResult) => void; +} +/** + * TrigoGame - Main game class managing state, history, and logic + * + * Equivalent to trigo.Game in prototype (lines 75-395) + * + * Key features: + * - Maintains game board state + * - Tracks complete move history + * - Implements Go rules (capture, Ko, suicide) + * - Supports undo/redo functionality + * - Territory calculation + */ +export declare class TrigoGame { + private shape; + private callbacks; + private board; + private currentPlayer; + private stepHistory; + private currentStepIndex; + private gameStatus; + private gameResult?; + private passCount; + private lastCapturedPositions; + private territoryDirty; + private cachedTerritory; + /** + * Constructor + * Equivalent to trigo.Game constructor (lines 75-85) + */ + constructor(shape?: BoardShape, callbacks?: GameCallbacks); + /** + * Create an empty board + */ + private createEmptyBoard; + /** + * Reset the game to initial state + * Equivalent to Game.reset() (lines 153-163) + */ + reset(): void; + /** + * Clone the game state (deep copy) + * Creates an independent copy with all state preserved + */ + clone(): TrigoGame; + /** + * Get current board state (read-only) + */ + getBoard(): Stone[][][]; + /** + * Get stone at specific position + * Equivalent to Game.stone() (lines 95-97) + */ + getStone(pos: Position): Stone; + /** + * Get current player + */ + getCurrentPlayer(): Stone; + /** + * Get current step number + * Equivalent to Game.currentStep() (lines 99-101) + */ + getCurrentStep(): number; + /** + * Get move history + * Equivalent to Game.routine() (lines 103-105) + */ + getHistory(): Step[]; + /** + * Get last move + * Equivalent to Game.lastStep() (lines 107-110) + */ + getLastStep(): Step | null; + /** + * Get board shape + * Equivalent to Game.shape() (lines 87-89) + */ + getShape(): BoardShape; + /** + * Get game status + */ + getGameStatus(): GameStatus; + /** + * Set game status + */ + setGameStatus(status: GameStatus): void; + /** + * Get game result + */ + getGameResult(): GameResult | undefined; + /** + * Get consecutive pass count + */ + getPassCount(): number; + /** + * Recalculate consecutive pass count based on current history + * Counts consecutive PASS steps from the end of current history + */ + private recalculatePassCount; + /** + * Start the game + */ + startGame(): void; + /** + * Check if game is active + */ + isGameActive(): boolean; + /** + * Check if a move is valid + * Equivalent to Game.isDropable() and Game.isValidStep() (lines 112-151) + */ + isValidMove(pos: Position, player?: Stone): { + valid: boolean; + reason?: string; + }; + /** + * Get all valid move positions for current player (efficient batch query) + * + * This method is optimized to avoid repeated validation checks by: + * 1. Only checking empty positions + * 2. Skipping bounds checking (iterator is already within bounds) + * 3. Using low-level validation functions directly + * 4. Batching board state access + * + * @param player - Optional player color (defaults to current player) + * @returns Array of all valid move positions + */ + validMovePositions(player?: Stone): Position[]; + /** + * Reset pass count (called when a stone is placed) + */ + private resetPassCount; + /** + * Place a stone (drop move) + * Equivalent to Game.drop() and Game.appendStone() (lines 181-273) + * + * @returns true if move was successful, false otherwise + */ + drop(pos: Position): boolean; + /** + * Pass turn + * Equivalent to PASS step type in prototype + */ + pass(): boolean; + /** + * Surrender/resign + * Equivalent to Game.step() with SURRENDER type (lines 176-178) + */ + surrender(): boolean; + /** + * Undo last move + * Equivalent to Game.repent() (lines 197-230) + * + * @returns true if undo was successful, false if no moves to undo + */ + undo(): boolean; + /** + * Redo next move (after undo) + * + * @returns true if redo was successful, false if no moves to redo + */ + redo(): boolean; + /** + * Check if redo is available + */ + canRedo(): boolean; + /** + * Jump to specific step in history + * Rebuilds board state after applying the first 'index' moves + * + * @param index Number of moves to apply from history (0 for initial state, 1 for after first move, etc.) + * @returns true if jump was successful + */ + jumpToStep(index: number): boolean; + /** + * Advance to next step + * Equivalent to Game.stepAdvance() (lines 279-287) + */ + private advanceStep; + /** + * Get territory calculation + * Equivalent to Game.blackDomain() and Game.whiteDomain() (lines 232-244) + * + * Returns cached result if territory hasn't changed + */ + getTerritory(): TerritoryResult; + /** + * Get captured stone counts up to current position in history + * Only counts captures that have been played (up to currentStepIndex) + */ + getCapturedCounts(): { + black: number; + white: number; + }; + /** + * Serialize game state to JSON + * Equivalent to Game.serialize() (lines 250-252) + */ + toJSON(): object; + /** + * Load game state from JSON + */ + fromJSON(data: any): boolean; + /** + * Get game statistics + */ + getStats(): { + totalMoves: number; + blackMoves: number; + whiteMoves: number; + capturedByBlack: number; + capturedByWhite: number; + territory: TerritoryResult; + }; + /** + * Save game state to sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if save was successful + */ + saveToSessionStorage(key?: string): boolean; + /** + * Load game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if load was successful + */ + loadFromSessionStorage(key?: string): boolean; + /** + * Clear saved game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + */ + clearSessionStorage(key?: string): void; + /** + * Export game to TGN (Trigo Game Notation) format + * + * TGN format is similar to PGN (Portable Game Notation) for chess. + * It includes metadata tags and move sequence using ab0yz coordinate notation. + * + * @param metadata Optional metadata for the game (Event, Site, Date, Players, etc.) + * @returns TGN-formatted string + * + * @example + * const tgn = game.toTGN({ + * event: "World Championship", + * site: "Tokyo", + * date: "2025.10.31", + * black: "Alice", + * white: "Bob" + * }); + */ + toTGN(metadata?: { + event?: string; + site?: string; + date?: string; + round?: string; + black?: string; + white?: string; + rules?: string; + timeControl?: string; + application?: string; + [key: string]: string | undefined; + }, { markResult }?: { + markResult?: boolean; + }): string; + /** + * Import game from TGN (Trigo Game Notation) format + * + * Static factory method that parses a TGN string and creates a new TrigoGame instance + * with the board configuration and moves from the TGN file. + * + * Synchronous operation - requires parser to be loaded via setParserModule() + * + * @param tgnString TGN-formatted game notation string + * @param callbacks Optional game callbacks + * @returns New TrigoGame instance with the imported game state + * @throws TGNParseError if the TGN string is invalid + * + * @example + * const tgnString = ` + * [Event "World Championship"] + * [Board "5x5x5"] + * [Black "Alice"] + * [White "Bob"] + * + * 1. 000 y00 + * 2. 0y0 pass + * `; + * const game = TrigoGame.fromTGN(tgnString); + */ + static fromTGN(tgnString: string, callbacks?: GameCallbacks): TrigoGame; + /** + * Apply a parsed move action to the game + * Private helper method for fromTGN + * + * @param action Parsed move action from TGN parser + * @param boardShape Board dimensions for coordinate decoding + */ + private _applyParsedMove; +} +export { validateTGN, TGNParseError } from "../tgn/tgnParser"; +//# sourceMappingURL=game.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/game.d.ts.map b/trigo-web/backend/dist/inc/trigo/game.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..052a671a814faf21f04a01b12c1393232e2806a1 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/game.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/game.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/game.js b/trigo-web/backend/dist/inc/trigo/game.js new file mode 100644 index 0000000000000000000000000000000000000000..7646f75f3f16e3996ae8fb975ab2e7e60660cd4b --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/game.js @@ -0,0 +1,1002 @@ +"use strict"; +/** + * TrigoGame Class - Main Game State Management + * + * Modern reimplementation of prototype's trigo.Game + * Integrates game state, move history, and game logic in a single class + * + * Equivalent to: third_party/klstrigo/Source/static/js/trigo.game.js:75-601 + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TGNParseError = exports.validateTGN = exports.TrigoGame = exports.StepType = exports.StoneType = void 0; +const gameUtils_1 = require("./gameUtils"); +const ab0yz_1 = require("./ab0yz"); +const tgnParser_1 = require("../tgn/tgnParser"); +// Re-export StoneType for convenient access with TrigoGame +var gameUtils_2 = require("./gameUtils"); +Object.defineProperty(exports, "StoneType", { enumerable: true, get: function () { return gameUtils_2.StoneType; } }); +/** + * Step Types - Different types of moves in the game + * Equivalent to trigo.Game.StepType in prototype + */ +var StepType; +(function (StepType) { + StepType[StepType["DROP"] = 0] = "DROP"; + StepType[StepType["PASS"] = 1] = "PASS"; + StepType[StepType["SURRENDER"] = 2] = "SURRENDER"; + StepType[StepType["UNDO"] = 3] = "UNDO"; // Undo last move (called "REPENT" in prototype) +})(StepType || (exports.StepType = StepType = {})); +/** + * TrigoGame - Main game class managing state, history, and logic + * + * Equivalent to trigo.Game in prototype (lines 75-395) + * + * Key features: + * - Maintains game board state + * - Tracks complete move history + * - Implements Go rules (capture, Ko, suicide) + * - Supports undo/redo functionality + * - Territory calculation + */ +class TrigoGame { + /** + * Constructor + * Equivalent to trigo.Game constructor (lines 75-85) + */ + constructor(shape = { x: 5, y: 5, z: 5 }, callbacks = {}) { + // Last captured stones for Ko rule detection + this.lastCapturedPositions = null; + // Territory cache + this.territoryDirty = true; + this.cachedTerritory = null; + this.shape = shape; + this.callbacks = callbacks; + this.board = this.createEmptyBoard(); + this.currentPlayer = gameUtils_1.StoneType.BLACK; + this.stepHistory = []; + this.currentStepIndex = 0; + this.gameStatus = "idle"; + this.gameResult = undefined; + this.passCount = 0; + } + /** + * Create an empty board + */ + createEmptyBoard() { + const board = []; + for (let x = 0; x < this.shape.x; x++) { + board[x] = []; + for (let y = 0; y < this.shape.y; y++) { + board[x][y] = []; + for (let z = 0; z < this.shape.z; z++) { + board[x][y][z] = gameUtils_1.StoneType.EMPTY; + } + } + } + return board; + } + /** + * Reset the game to initial state + * Equivalent to Game.reset() (lines 153-163) + */ + reset() { + this.board = this.createEmptyBoard(); + this.currentPlayer = gameUtils_1.StoneType.BLACK; + this.stepHistory = []; + this.currentStepIndex = 0; + this.lastCapturedPositions = null; + this.territoryDirty = true; + this.cachedTerritory = null; + this.gameStatus = "idle"; + this.gameResult = undefined; + this.passCount = 0; + } + /** + * Clone the game state (deep copy) + * Creates an independent copy with all state preserved + */ + clone() { + const cloned = new TrigoGame(this.shape, {}); + // Deep copy board + cloned.board = this.board.map((plane) => plane.map((row) => [...row])); + // Copy game state + cloned.currentPlayer = this.currentPlayer; + cloned.currentStepIndex = this.currentStepIndex; + cloned.gameStatus = this.gameStatus; + cloned.passCount = this.passCount; + // Deep copy step history + cloned.stepHistory = this.stepHistory.map((step) => ({ + ...step, + position: step.position ? { ...step.position } : undefined, + capturedPositions: step.capturedPositions + ? step.capturedPositions.map((pos) => ({ ...pos })) + : [] + })); + // Deep copy last captured positions + cloned.lastCapturedPositions = this.lastCapturedPositions + ? this.lastCapturedPositions.map((pos) => ({ ...pos })) + : null; + // Copy game result + if (this.gameResult) { + cloned.gameResult = { + ...this.gameResult, + score: this.gameResult.score ? { ...this.gameResult.score } : undefined + }; + } + // Territory cache will be recalculated on demand + cloned.territoryDirty = true; + cloned.cachedTerritory = null; + return cloned; + } + /** + * Get current board state (read-only) + */ + getBoard() { + // Return a deep copy to prevent external modification + return this.board.map((plane) => plane.map((row) => [...row])); + } + /** + * Get stone at specific position + * Equivalent to Game.stone() (lines 95-97) + */ + getStone(pos) { + return this.board[pos.x][pos.y][pos.z]; + } + /** + * Get current player + */ + getCurrentPlayer() { + return this.currentPlayer; + } + /** + * Get current step number + * Equivalent to Game.currentStep() (lines 99-101) + */ + getCurrentStep() { + return this.currentStepIndex; + } + /** + * Get move history + * Equivalent to Game.routine() (lines 103-105) + */ + getHistory() { + return [...this.stepHistory]; + } + /** + * Get last move + * Equivalent to Game.lastStep() (lines 107-110) + */ + getLastStep() { + if (this.currentStepIndex > 0) { + return this.stepHistory[this.currentStepIndex - 1]; + } + return null; + } + /** + * Get board shape + * Equivalent to Game.shape() (lines 87-89) + */ + getShape() { + return { ...this.shape }; + } + /** + * Get game status + */ + getGameStatus() { + return this.gameStatus; + } + /** + * Set game status + */ + setGameStatus(status) { + this.gameStatus = status; + } + /** + * Get game result + */ + getGameResult() { + return this.gameResult; + } + /** + * Get consecutive pass count + */ + getPassCount() { + return this.passCount; + } + /** + * Recalculate consecutive pass count based on current history + * Counts consecutive PASS steps from the end of current history + */ + recalculatePassCount() { + this.passCount = 0; + // Count backwards from current position to find consecutive passes + for (let i = this.currentStepIndex - 1; i >= 0; i--) { + if (this.stepHistory[i].type === StepType.PASS) { + this.passCount++; + } + else { + break; // Stop at first non-pass move + } + } + } + /** + * Start the game + */ + startGame() { + if (this.gameStatus === "idle") { + this.gameStatus = "playing"; + } + } + /** + * Check if game is active + */ + isGameActive() { + return this.gameStatus === "playing"; + } + /** + * Check if a move is valid + * Equivalent to Game.isDropable() and Game.isValidStep() (lines 112-151) + */ + isValidMove(pos, player) { + const playerColor = player || this.currentPlayer; + return (0, gameUtils_1.validateMove)(pos, playerColor, this.board, this.shape, this.lastCapturedPositions); + } + /** + * Get all valid move positions for current player (efficient batch query) + * + * This method is optimized to avoid repeated validation checks by: + * 1. Only checking empty positions + * 2. Skipping bounds checking (iterator is already within bounds) + * 3. Using low-level validation functions directly + * 4. Batching board state access + * + * @param player - Optional player color (defaults to current player) + * @returns Array of all valid move positions + */ + validMovePositions(player) { + const playerColor = player || this.currentPlayer; + const validPositions = []; + // Iterate through all board positions (bounds are guaranteed) + for (let x = 0; x < this.shape.x; x++) { + for (let y = 0; y < this.shape.y; y++) { + for (let z = 0; z < this.shape.z; z++) { + // Skip occupied positions (quick filter) + if (this.board[x][y][z] !== gameUtils_1.StoneType.EMPTY) { + continue; + } + const pos = { x, y, z }; + // Check Ko violation (using low-level function) + if ((0, gameUtils_1.isKoViolation)(pos, playerColor, this.board, this.shape, this.lastCapturedPositions)) { + continue; + } + // Check suicide rule (using low-level function) + if ((0, gameUtils_1.isSuicideMove)(pos, playerColor, this.board, this.shape)) { + continue; + } + // Position is valid + validPositions.push(pos); + } + } + } + return validPositions; + } + /** + * Reset pass count (called when a stone is placed) + */ + resetPassCount() { + this.passCount = 0; + } + /** + * Place a stone (drop move) + * Equivalent to Game.drop() and Game.appendStone() (lines 181-273) + * + * @returns true if move was successful, false otherwise + */ + drop(pos) { + // Validate the move + const validation = this.isValidMove(pos); + if (!validation.valid) { + console.warn(`Invalid move at (${pos.x}, ${pos.y}, ${pos.z}): ${validation.reason}`); + return false; + } + // Find captured groups BEFORE placing the stone + const capturedGroups = (0, gameUtils_1.findCapturedGroups)(pos, this.currentPlayer, this.board, this.shape); + // Place the stone on the board + this.board[pos.x][pos.y][pos.z] = this.currentPlayer; + // Execute captures + const capturedPositions = (0, gameUtils_1.executeCaptures)(capturedGroups, this.board); + // Store captured positions for Ko rule + this.lastCapturedPositions = capturedPositions.length > 0 ? capturedPositions : null; + // Mark territory as dirty + this.territoryDirty = true; + // Reset pass count when a stone is placed + this.resetPassCount(); + // Create step record + const step = { + type: StepType.DROP, + position: pos, + player: this.currentPlayer, + capturedPositions: capturedPositions.length > 0 ? capturedPositions : undefined, + timestamp: Date.now() + }; + // Advance to next step + this.advanceStep(step); + // Trigger callbacks + if (capturedPositions.length > 0 && this.callbacks.onCapture) { + this.callbacks.onCapture(capturedPositions); + } + if (this.territoryDirty && this.callbacks.onTerritoryChange) { + this.callbacks.onTerritoryChange(this.getTerritory()); + } + return true; + } + /** + * Pass turn + * Equivalent to PASS step type in prototype + */ + pass() { + const step = { + type: StepType.PASS, + player: this.currentPlayer, + timestamp: Date.now() + }; + this.lastCapturedPositions = null; + // Increment pass count + this.passCount++; + // Advance step + this.advanceStep(step); + // Check for double pass (game end condition) + if (this.passCount >= 2) { + // Calculate territory to determine winner + const territory = this.getTerritory(); + const capturedCounts = this.getCapturedCounts(); + const blackTotal = territory.black + capturedCounts.white; // black's territory + white stones captured + const whiteTotal = territory.white + capturedCounts.black; // white's territory + black stones captured + let winner; + if (blackTotal > whiteTotal) { + winner = "black"; + } + else if (whiteTotal > blackTotal) { + winner = "white"; + } + else { + winner = "draw"; + } + this.gameResult = { + winner, + reason: "double-pass", + score: territory + }; + this.gameStatus = "finished"; + // Trigger win callback + if (this.callbacks.onWin) { + const winnerStone = winner === "black" + ? gameUtils_1.StoneType.BLACK + : winner === "white" + ? gameUtils_1.StoneType.WHITE + : gameUtils_1.StoneType.EMPTY; + this.callbacks.onWin(winnerStone); + } + } + return true; + } + /** + * Surrender/resign + * Equivalent to Game.step() with SURRENDER type (lines 176-178) + */ + surrender() { + const surrenderingPlayer = this.currentPlayer; // Remember who surrendered + const step = { + type: StepType.SURRENDER, + player: this.currentPlayer, + timestamp: Date.now() + }; + this.advanceStep(step); + // Set game result - opponent of surrendering player wins + const winner = surrenderingPlayer === gameUtils_1.StoneType.BLACK ? "white" : "black"; + this.gameResult = { + winner, + reason: "resignation" + }; + this.gameStatus = "finished"; + // Trigger win callback for the opponent + const winnerStone = (0, gameUtils_1.getEnemyColor)(surrenderingPlayer); + if (this.callbacks.onWin) { + this.callbacks.onWin(winnerStone); + } + return true; + } + /** + * Undo last move + * Equivalent to Game.repent() (lines 197-230) + * + * @returns true if undo was successful, false if no moves to undo + */ + undo() { + if (this.currentStepIndex === 0 || this.stepHistory.length === 0) { + return false; + } + const lastStep = this.stepHistory[this.currentStepIndex - 1]; + // Revert the move + if (lastStep.type === StepType.DROP && lastStep.position) { + // Remove the placed stone + this.board[lastStep.position.x][lastStep.position.y][lastStep.position.z] = + gameUtils_1.StoneType.EMPTY; + // Restore captured stones + if (lastStep.capturedPositions) { + const enemyColor = (0, gameUtils_1.getEnemyColor)(lastStep.player); + for (const pos of lastStep.capturedPositions) { + this.board[pos.x][pos.y][pos.z] = enemyColor; + } + } + } + // Move back in history + this.currentStepIndex--; + this.currentPlayer = lastStep.player; // Restore player who made that move + // Recalculate pass count based on new history position + this.recalculatePassCount(); + // Update last captured positions for Ko rule + // Need to check the step before this one + if (this.currentStepIndex > 0) { + const previousStep = this.stepHistory[this.currentStepIndex - 1]; + this.lastCapturedPositions = previousStep.capturedPositions || null; + } + else { + this.lastCapturedPositions = null; + } + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback + if (this.callbacks.onStepBack) { + this.callbacks.onStepBack(lastStep, this.stepHistory.slice(0, this.currentStepIndex)); + } + return true; + } + /** + * Redo next move (after undo) + * + * @returns true if redo was successful, false if no moves to redo + */ + redo() { + // Check if we can redo (not at the end of history) + if (this.currentStepIndex >= this.stepHistory.length) { + return false; + } + const nextStep = this.stepHistory[this.currentStepIndex]; + // Re-apply the move + if (nextStep.type === StepType.DROP && nextStep.position) { + // Place the stone + this.board[nextStep.position.x][nextStep.position.y][nextStep.position.z] = + nextStep.player; + // Re-execute captures if there were any + if (nextStep.capturedPositions) { + for (const pos of nextStep.capturedPositions) { + this.board[pos.x][pos.y][pos.z] = gameUtils_1.StoneType.EMPTY; + } + } + // Update last captured positions + this.lastCapturedPositions = nextStep.capturedPositions || null; + } + else if (nextStep.type === StepType.PASS) { + this.lastCapturedPositions = null; + } + // Move forward in history + this.currentStepIndex++; + this.currentPlayer = (0, gameUtils_1.getEnemyColor)(nextStep.player); // Switch to next player + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback + if (this.callbacks.onStepAdvance) { + this.callbacks.onStepAdvance(nextStep, this.stepHistory.slice(0, this.currentStepIndex)); + } + return true; + } + /** + * Check if redo is available + */ + canRedo() { + return this.currentStepIndex < this.stepHistory.length; + } + /** + * Jump to specific step in history + * Rebuilds board state after applying the first 'index' moves + * + * @param index Number of moves to apply from history (0 for initial state, 1 for after first move, etc.) + * @returns true if jump was successful + */ + jumpToStep(index) { + // Validate index: allow 0 (initial state) up to stepHistory.length (all moves applied) + if (index < 0 || index > this.stepHistory.length) { + return false; + } + // If already at target index, return false (no change made) + if (index === this.currentStepIndex) { + return false; + } + // Rebuild board from scratch + this.board = this.createEmptyBoard(); + this.lastCapturedPositions = null; + // Replay all moves up to (but not including) target index + // After this loop, we'll have applied 'index' number of moves + for (let i = 0; i < index; i++) { + const step = this.stepHistory[i]; + if (step.type === StepType.DROP && step.position) { + const pos = step.position; + // Place the stone + this.board[pos.x][pos.y][pos.z] = step.player; + // Re-execute captures + if (step.capturedPositions) { + for (const capturedPos of step.capturedPositions) { + this.board[capturedPos.x][capturedPos.y][capturedPos.z] = gameUtils_1.StoneType.EMPTY; + } + } + } + } + // Set last captured positions from the last applied move (if any) + if (index > 0) { + const lastAppliedStep = this.stepHistory[index - 1]; + if (lastAppliedStep.type === StepType.DROP) { + this.lastCapturedPositions = lastAppliedStep.capturedPositions || null; + } + else if (lastAppliedStep.type === StepType.PASS) { + this.lastCapturedPositions = null; + } + } + else { + this.lastCapturedPositions = null; + } + // Update current index + const oldStepIndex = this.currentStepIndex; + this.currentStepIndex = index; + // Set current player based on number of moves played + // currentStepIndex represents the number of moves applied + const movesPlayed = index; + this.currentPlayer = movesPlayed % 2 === 0 ? gameUtils_1.StoneType.BLACK : gameUtils_1.StoneType.WHITE; + // Recalculate pass count based on new history position + this.recalculatePassCount(); + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback based on direction + if (index < oldStepIndex && this.callbacks.onStepBack) { + const currentStep = this.stepHistory[index]; + this.callbacks.onStepBack(currentStep, this.stepHistory.slice(0, index + 1)); + } + else if (index > oldStepIndex && this.callbacks.onStepAdvance) { + const currentStep = this.stepHistory[index]; + this.callbacks.onStepAdvance(currentStep, this.stepHistory.slice(0, index + 1)); + } + return true; + } + /** + * Advance to next step + * Equivalent to Game.stepAdvance() (lines 279-287) + */ + advanceStep(step) { + // If we're not at the end of history, truncate future steps + if (this.currentStepIndex < this.stepHistory.length) { + this.stepHistory = this.stepHistory.slice(0, this.currentStepIndex); + } + // Add the new step + this.stepHistory.push(step); + this.currentStepIndex++; + // Switch player + this.currentPlayer = (0, gameUtils_1.getEnemyColor)(this.currentPlayer); + // Trigger callback + if (this.callbacks.onStepAdvance) { + this.callbacks.onStepAdvance(step, this.stepHistory); + } + } + /** + * Get territory calculation + * Equivalent to Game.blackDomain() and Game.whiteDomain() (lines 232-244) + * + * Returns cached result if territory hasn't changed + */ + getTerritory() { + if (this.territoryDirty || !this.cachedTerritory) { + this.cachedTerritory = (0, gameUtils_1.calculateTerritory)(this.board, this.shape); + this.territoryDirty = false; + } + return this.cachedTerritory; + } + /** + * Get captured stone counts up to current position in history + * Only counts captures that have been played (up to currentStepIndex) + */ + getCapturedCounts() { + const counts = { black: 0, white: 0 }; + // Only count captures up to current step index + for (let i = 0; i < this.currentStepIndex; i++) { + const step = this.stepHistory[i]; + if (step.capturedPositions && step.capturedPositions.length > 0) { + // Captured stones belong to the enemy of the player who made the move + const enemyColor = (0, gameUtils_1.getEnemyColor)(step.player); + if (enemyColor === gameUtils_1.StoneType.BLACK) { + counts.black += step.capturedPositions.length; + } + else if (enemyColor === gameUtils_1.StoneType.WHITE) { + counts.white += step.capturedPositions.length; + } + } + } + return counts; + } + /** + * Serialize game state to JSON + * Equivalent to Game.serialize() (lines 250-252) + */ + toJSON() { + return { + shape: this.shape, + currentPlayer: this.currentPlayer, + currentStepIndex: this.currentStepIndex, + history: this.stepHistory, + board: this.board, + gameStatus: this.gameStatus, + gameResult: this.gameResult, + passCount: this.passCount + }; + } + /** + * Load game state from JSON + */ + fromJSON(data) { + try { + // Validate required fields + if (!data || typeof data !== "object") { + return false; + } + if (!data.shape || !data.board || !Array.isArray(data.history)) { + return false; + } + this.shape = data.shape; + this.currentPlayer = data.currentPlayer; + this.currentStepIndex = data.currentStepIndex; + this.stepHistory = data.history || []; + this.board = data.board; + this.gameStatus = data.gameStatus || "idle"; + this.gameResult = data.gameResult; + this.passCount = data.passCount || 0; + // Recalculate last captured positions + if (this.currentStepIndex > 0) { + const lastStep = this.stepHistory[this.currentStepIndex - 1]; + this.lastCapturedPositions = lastStep.capturedPositions || null; + } + else { + this.lastCapturedPositions = null; + } + this.territoryDirty = true; + this.cachedTerritory = null; + return true; + } + catch (error) { + console.error("Failed to load game state:", error); + return false; + } + } + /** + * Get game statistics + */ + getStats() { + const captured = this.getCapturedCounts(); + const territory = this.getTerritory(); + let blackMoves = 0; + let whiteMoves = 0; + for (const step of this.stepHistory.slice(0, this.currentStepIndex)) { + if (step.type === StepType.DROP) { + if (step.player === gameUtils_1.StoneType.BLACK) { + blackMoves++; + } + else if (step.player === gameUtils_1.StoneType.WHITE) { + whiteMoves++; + } + } + } + return { + totalMoves: this.currentStepIndex, + blackMoves, + whiteMoves, + capturedByBlack: captured.white, // Black captures white stones + capturedByWhite: captured.black, // White captures black stones + territory + }; + } + /** + * Save game state to sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if save was successful + */ + saveToSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + const gameState = this.toJSON(); + globalThis.sessionStorage.setItem(key, JSON.stringify(gameState)); + return true; + } + catch (error) { + console.error("Failed to save game state to sessionStorage:", error); + return false; + } + } + console.warn("sessionStorage is not available"); + return false; + } + /** + * Load game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if load was successful + */ + loadFromSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + const savedState = globalThis.sessionStorage.getItem(key); + if (!savedState) { + console.log("No saved game state found"); + return false; + } + const data = JSON.parse(savedState); + return this.fromJSON(data); + } + catch (error) { + console.error("Failed to load game state from sessionStorage:", error); + return false; + } + } + console.warn("sessionStorage is not available"); + return false; + } + /** + * Clear saved game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + */ + clearSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + globalThis.sessionStorage.removeItem(key); + } + catch (error) { + console.error("Failed to clear sessionStorage:", error); + } + } + else { + console.warn("sessionStorage is not available"); + } + } + /** + * Export game to TGN (Trigo Game Notation) format + * + * TGN format is similar to PGN (Portable Game Notation) for chess. + * It includes metadata tags and move sequence using ab0yz coordinate notation. + * + * @param metadata Optional metadata for the game (Event, Site, Date, Players, etc.) + * @returns TGN-formatted string + * + * @example + * const tgn = game.toTGN({ + * event: "World Championship", + * site: "Tokyo", + * date: "2025.10.31", + * black: "Alice", + * white: "Bob" + * }); + */ + toTGN(metadata, { markResult } = {}) { + const lines = []; + // Add metadata tags + if (metadata) { + if (metadata.event) + lines.push(`[Event "${metadata.event}"]`); + if (metadata.site) + lines.push(`[Site "${metadata.site}"]`); + if (metadata.date) + lines.push(`[Date "${metadata.date}"]`); + if (metadata.round) + lines.push(`[Round "${metadata.round}"]`); + if (metadata.black) + lines.push(`[Black "${metadata.black}"]`); + if (metadata.white) + lines.push(`[White "${metadata.white}"]`); + } + // Add result if game is finished + if (this.gameStatus === "finished" && this.gameResult) { + let resultStr = ""; + if (this.gameResult.winner === "black") { + resultStr = "B+"; + } + else if (this.gameResult.winner === "white") { + resultStr = "W+"; + } + else { + resultStr = "="; + } + // Add score information if available + if (this.gameResult.score) { + const { black, white } = this.gameResult.score; + const diff = Math.abs(black - white); + resultStr += `${diff}points`; + } + else if (this.gameResult.reason === "resignation") { + resultStr += "Resign"; + } + //lines.push(`[Result "${resultStr}"]`); + } + // Add board size (without quotes - parser expects unquoted board shape) + const boardStr = this.shape.z === 1 + ? `${this.shape.x}x${this.shape.y}` // 2D board + : `${this.shape.x}x${this.shape.y}x${this.shape.z}`; // 3D board + lines.push(`[Board ${boardStr}]`); + // Add optional metadata + if (metadata) { + if (metadata.rules) + lines.push(`[Rules "${metadata.rules}"]`); + if (metadata.timeControl) + lines.push(`[TimeControl "${metadata.timeControl}"]`); + if (metadata.application) + lines.push(`[Application "${metadata.application}"]`); + } + // Add empty line after metadata + lines.push(""); + // Generate move sequence + const moves = []; + let moveNumber = 1; + for (let i = 0; i < this.stepHistory.length; i++) { + const step = this.stepHistory[i]; + let moveStr = ""; + // Add move number at the start of each round (black's move) + if (step.player === gameUtils_1.StoneType.BLACK) { + moveStr = `${moveNumber}. `; + } + // Format the move + if (step.type === StepType.DROP && step.position) { + // Convert position to TGN coordinate + const pos = [step.position.x, step.position.y, step.position.z]; + const boardShape = [this.shape.x, this.shape.y, this.shape.z]; + const coord = (0, ab0yz_1.encodeAb0yz)(pos, boardShape); + moveStr += coord; + } + else if (step.type === StepType.PASS) { + moveStr += "Pass"; + } + else if (step.type === StepType.SURRENDER) { + moveStr += "Resign"; + } + moves.push(moveStr); + // Increment move number after white's move + if (step.player === gameUtils_1.StoneType.WHITE) { + moveNumber++; + } + } + // Format moves with proper line breaks + // Group moves in pairs (black, white) on the same line + let currentLine = ""; + for (let i = 0; i < moves.length; i++) { + const move = moves[i]; + if (move.match(/^\d+\./)) { + // Start of a new round (black's move) + if (currentLine) { + lines.push(currentLine); + } + currentLine = move; + } + else { + // White's move - add to current line + currentLine += " " + move; + } + } + // Add the last line if it exists + if (currentLine) { + lines.push(currentLine); + } + // Add score result if game has finished + if (markResult) { + // Calculate territory to get final score + const territory = this.getTerritory(); + const scoreDiff = territory.black - territory.white; + // Add score comment: negative means black wins, positive means white wins + lines.push(`; ${scoreDiff > 0 ? '-' : scoreDiff < 0 ? '+' : ''}${Math.abs(scoreDiff)}`); + } + // Add empty line at the end + lines.push(""); + return lines.join("\n"); + } + /** + * Import game from TGN (Trigo Game Notation) format + * + * Static factory method that parses a TGN string and creates a new TrigoGame instance + * with the board configuration and moves from the TGN file. + * + * Synchronous operation - requires parser to be loaded via setParserModule() + * + * @param tgnString TGN-formatted game notation string + * @param callbacks Optional game callbacks + * @returns New TrigoGame instance with the imported game state + * @throws TGNParseError if the TGN string is invalid + * + * @example + * const tgnString = ` + * [Event "World Championship"] + * [Board "5x5x5"] + * [Black "Alice"] + * [White "Bob"] + * + * 1. 000 y00 + * 2. 0y0 pass + * `; + * const game = TrigoGame.fromTGN(tgnString); + */ + static fromTGN(tgnString, callbacks) { + // Parse the TGN string (synchronous) + const parsed = (0, tgnParser_1.parseTGN)(tgnString); + // Extract board shape from tags + let boardShape; + if (parsed.tags.Board && Array.isArray(parsed.tags.Board)) { + const shape = parsed.tags.Board; + // Ensure we have at least 2 dimensions, default to 1 for z if not 3D + boardShape = { + x: shape[0] || 5, + y: shape[1] || 5, + z: shape[2] || 1 + }; + } + else { + // Default to 5x5x5 if no board shape specified + boardShape = { x: 5, y: 5, z: 5 }; + } + // Create new game instance using 'this' constructor + // This allows subclasses to automatically get their own type + const game = new this(boardShape, callbacks); + game.startGame(); + // Replay all moves from the parsed data + if (parsed.moves && parsed.moves.length > 0) { + for (const round of parsed.moves) { + // Play black's move + if (round.action_black) { + game._applyParsedMove(round.action_black, boardShape); + } + // Play white's move if it exists + if (round.action_white) { + game._applyParsedMove(round.action_white, boardShape); + } + } + } + return game; + } + /** + * Apply a parsed move action to the game + * Private helper method for fromTGN + * + * @param action Parsed move action from TGN parser + * @param boardShape Board dimensions for coordinate decoding + */ + _applyParsedMove(action, boardShape) { + if (action.type === "pass") { + this.pass(); + } + else if (action.type === "resign") { + this.surrender(); + } + else if (action.type === "move" && action.position) { + // Decode ab0yz coordinate to Position + const coords = (0, ab0yz_1.decodeAb0yz)(action.position, [boardShape.x, boardShape.y, boardShape.z]); + const position = { + x: coords[0], + y: coords[1], + z: coords[2] + }; + // Make the move + this.drop(position); + } + } +} +exports.TrigoGame = TrigoGame; +// Re-export parser utilities for convenience +var tgnParser_2 = require("../tgn/tgnParser"); +Object.defineProperty(exports, "validateTGN", { enumerable: true, get: function () { return tgnParser_2.validateTGN; } }); +Object.defineProperty(exports, "TGNParseError", { enumerable: true, get: function () { return tgnParser_2.TGNParseError; } }); +//# sourceMappingURL=game.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/game.js.map b/trigo-web/backend/dist/inc/trigo/game.js.map new file mode 100644 index 0000000000000000000000000000000000000000..24b20ebb8da453ef7bd55171ead4118f0523fa1d --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/game.js.map @@ -0,0 +1 @@ +{"version":3,"file":"game.js","sourceRoot":"","sources":["../../../../inc/trigo/game.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts b/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a58df8e49a02f92457d6df07c9cd947cdd5a1f5d --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts @@ -0,0 +1,149 @@ +/** + * Game Logic Service - Core Go Rules Implementation + * + * Implements capture detection, Ko rule, and territory counting + * Ported from prototype trigo.game.js to modern TypeScript + */ +import type { Position, Stone, BoardShape } from "./types"; +export declare const StoneType: { + EMPTY: Stone; + BLACK: Stone; + WHITE: Stone; +}; +/** + * Get the enemy color of a given stone + * + * Equivalent to trigo.enemyColor() in prototype + */ +export declare function getEnemyColor(color: Stone): Stone; +/** + * Check if a position is within board bounds + */ +export declare function isInBounds(pos: Position, shape: BoardShape): boolean; +/** + * Get all neighboring positions (up to 6 in 3D: ±x, ±y, ±z) + * + * Equivalent to StoneArray.stoneNeighbors() in prototype + */ +export declare function getNeighbors(pos: Position, shape: BoardShape): Position[]; +/** + * Compare two positions for equality + */ +export declare function positionsEqual(p1: Position, p2: Position): boolean; +/** + * Coordinate Set - manages a set of positions (stones in a group or liberties) + */ +export declare class CoordSet { + private positions; + has(pos: Position): boolean; + insert(pos: Position): boolean; + remove(pos: Position): void; + size(): number; + empty(): boolean; + forEach(callback: (pos: Position, index: number) => void): void; + toArray(): Position[]; + clear(): void; +} +/** + * Patch - represents a connected group of same-colored stones + * + * Note: Called "Patch" in the original prototype (trigo.game.js) + * Equivalent to trigo.Game.Patch which extends trigo.CoordSet + */ +export declare class Patch { + positions: CoordSet; + color: Stone; + constructor(color?: Stone); + addStone(pos: Position): void; + size(): number; + /** + * Get all liberties (empty adjacent positions) for this group + * + * Equivalent to StoneArray.patchAir() in prototype + * Returns a CoordSet of empty positions adjacent to this patch + */ + getLiberties(board: Stone[][][], shape: BoardShape): CoordSet; +} +/** + * Find the connected group of stones at a given position + */ +export declare function findGroup(pos: Position, board: Stone[][][], shape: BoardShape): Patch; +/** + * Get all neighboring groups (different from current position's color) + */ +export declare function getNeighborGroups(pos: Position, board: Stone[][][], shape: BoardShape, excludeEmpty?: boolean): Patch[]; +/** + * Check if a group would be captured (has no liberties) + */ +export declare function isGroupCaptured(group: Patch, board: Stone[][][], shape: BoardShape): boolean; +/** + * Find all groups that would be captured by placing a stone at position + * + * Equivalent to Game.killedPatches() in prototype + * + * Note: Prototype checks patchAir <= 1 BEFORE placement. + * We create a temp board with stone placed, then check for 0 liberties AFTER. + * Both approaches produce the same result. + */ +export declare function findCapturedGroups(pos: Position, playerColor: Stone, board: Stone[][][], shape: BoardShape): Patch[]; +/** + * Check if placing a stone at position would result in self-capture (suicide) + * + * Equivalent to Game.isDeadStone() in prototype + * + * Exception: Move is allowed if it captures enemy stones first + */ +export declare function isSuicideMove(pos: Position, playerColor: Stone, board: Stone[][][], shape: BoardShape): boolean; +/** + * Ko Detection - check if move would recreate previous board state + * + * Equivalent to "rob" check in Game.isDropable() (lines 127-132) + * Note: Ko rule is called "rob" (打劫 dǎjié) in the prototype + * + * Ko rule: Cannot immediately recapture a single stone if it would + * return the board to the previous position + */ +export declare function isKoViolation(pos: Position, playerColor: Stone, board: Stone[][][], shape: BoardShape, lastCapturedPositions: Position[] | null): boolean; +/** + * Execute captures on the board + * Returns the positions of captured stones + */ +export declare function executeCaptures(capturedGroups: Patch[], board: Stone[][][]): Position[]; +/** + * Territory Calculation + * + * Determines which empty regions belong to which player + * An empty region belongs to a player if it's completely surrounded + * by that player's stones + */ +export interface TerritoryResult { + black: number; + white: number; + neutral: number; + blackTerritory: Position[]; + whiteTerritory: Position[]; + neutralTerritory: Position[]; +} +/** + * Calculate territory for both players + * + * Equivalent to Game.calculateDomainSize() in prototype (lines 305-343) + * Uses PatchList.spaceDomain() logic to determine region ownership + * + * Algorithm: + * 1. First pass: Add all stones to their player's territory, collect empty regions + * 2. Second pass: Determine ownership of each empty region + */ +export declare function calculateTerritory(board: Stone[][][], shape: BoardShape): TerritoryResult; +/** + * Validate if a move is legal + * + * Equivalent to Game.isDropable() in prototype + * Checks: bounds, occupation, Ko rule ("rob"), suicide rule + */ +export interface MoveValidation { + valid: boolean; + reason?: string; +} +export declare function validateMove(pos: Position, playerColor: Stone, board: Stone[][][], shape: BoardShape, lastCapturedPositions?: Position[] | null): MoveValidation; +//# sourceMappingURL=gameUtils.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts.map b/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..90e7bf90d712f2166a5531fcd23a6f42aa6a45c2 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/gameUtils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"gameUtils.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/gameUtils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/gameUtils.js b/trigo-web/backend/dist/inc/trigo/gameUtils.js new file mode 100644 index 0000000000000000000000000000000000000000..ac74dfde88056ae0339fd77601473501f1606e5d --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/gameUtils.js @@ -0,0 +1,448 @@ +"use strict"; +/** + * Game Logic Service - Core Go Rules Implementation + * + * Implements capture detection, Ko rule, and territory counting + * Ported from prototype trigo.game.js to modern TypeScript + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Patch = exports.CoordSet = exports.StoneType = void 0; +exports.getEnemyColor = getEnemyColor; +exports.isInBounds = isInBounds; +exports.getNeighbors = getNeighbors; +exports.positionsEqual = positionsEqual; +exports.findGroup = findGroup; +exports.getNeighborGroups = getNeighborGroups; +exports.isGroupCaptured = isGroupCaptured; +exports.findCapturedGroups = findCapturedGroups; +exports.isSuicideMove = isSuicideMove; +exports.isKoViolation = isKoViolation; +exports.executeCaptures = executeCaptures; +exports.calculateTerritory = calculateTerritory; +exports.validateMove = validateMove; +exports.StoneType = { + EMPTY: 0, + BLACK: 1, + WHITE: 2 +}; +/** + * Get the enemy color of a given stone + * + * Equivalent to trigo.enemyColor() in prototype + */ +function getEnemyColor(color) { + if (color === exports.StoneType.BLACK) + return exports.StoneType.WHITE; + if (color === exports.StoneType.WHITE) + return exports.StoneType.BLACK; + return exports.StoneType.EMPTY; +} +/** + * Check if a position is within board bounds + */ +function isInBounds(pos, shape) { + return (pos.x >= 0 && + pos.x < shape.x && + pos.y >= 0 && + pos.y < shape.y && + pos.z >= 0 && + pos.z < shape.z); +} +/** + * Get all neighboring positions (up to 6 in 3D: ±x, ±y, ±z) + * + * Equivalent to StoneArray.stoneNeighbors() in prototype + */ +function getNeighbors(pos, shape) { + const neighbors = []; + // Check all 6 directions in 3D space + const directions = [ + { x: 1, y: 0, z: 0 }, + { x: -1, y: 0, z: 0 }, + { x: 0, y: 1, z: 0 }, + { x: 0, y: -1, z: 0 }, + { x: 0, y: 0, z: 1 }, + { x: 0, y: 0, z: -1 } + ]; + for (const dir of directions) { + const neighbor = { + x: pos.x + dir.x, + y: pos.y + dir.y, + z: pos.z + dir.z + }; + if (isInBounds(neighbor, shape)) { + neighbors.push(neighbor); + } + } + return neighbors; +} +/** + * Compare two positions for equality + */ +function positionsEqual(p1, p2) { + return p1.x === p2.x && p1.y === p2.y && p1.z === p2.z; +} +/** + * Coordinate Set - manages a set of positions (stones in a group or liberties) + */ +class CoordSet { + constructor() { + this.positions = []; + } + has(pos) { + return this.positions.some((p) => positionsEqual(p, pos)); + } + insert(pos) { + if (!this.has(pos)) { + this.positions.push(pos); + return true; + } + return false; + } + remove(pos) { + this.positions = this.positions.filter((p) => !positionsEqual(p, pos)); + } + size() { + return this.positions.length; + } + empty() { + return this.positions.length === 0; + } + forEach(callback) { + this.positions.forEach(callback); + } + toArray() { + return [...this.positions]; + } + clear() { + this.positions = []; + } +} +exports.CoordSet = CoordSet; +/** + * Patch - represents a connected group of same-colored stones + * + * Note: Called "Patch" in the original prototype (trigo.game.js) + * Equivalent to trigo.Game.Patch which extends trigo.CoordSet + */ +class Patch { + constructor(color = exports.StoneType.EMPTY) { + this.positions = new CoordSet(); + this.color = exports.StoneType.EMPTY; + this.color = color; + } + addStone(pos) { + this.positions.insert(pos); + } + size() { + return this.positions.size(); + } + /** + * Get all liberties (empty adjacent positions) for this group + * + * Equivalent to StoneArray.patchAir() in prototype + * Returns a CoordSet of empty positions adjacent to this patch + */ + getLiberties(board, shape) { + const liberties = new CoordSet(); + this.positions.forEach((stonePos) => { + const neighbors = getNeighbors(stonePos, shape); + for (const neighbor of neighbors) { + if (board[neighbor.x][neighbor.y][neighbor.z] === exports.StoneType.EMPTY) { + liberties.insert(neighbor); + } + } + }); + return liberties; + } +} +exports.Patch = Patch; +/** + * Find the connected group of stones at a given position + */ +function findGroup(pos, board, shape) { + const color = board[pos.x][pos.y][pos.z]; + const group = new Patch(color); + if (color === exports.StoneType.EMPTY) { + return group; + } + // Flood fill to find all connected stones of the same color + const visited = new CoordSet(); + const stack = [pos]; + while (stack.length > 0) { + const current = stack.pop(); + if (visited.has(current)) { + continue; + } + visited.insert(current); + if (board[current.x][current.y][current.z] === color) { + group.addStone(current); + const neighbors = getNeighbors(current, shape); + for (const neighbor of neighbors) { + if (!visited.has(neighbor)) { + stack.push(neighbor); + } + } + } + } + return group; +} +/** + * Get all neighboring groups (different from current position's color) + */ +function getNeighborGroups(pos, board, shape, excludeEmpty = false) { + const neighbors = getNeighbors(pos, shape); + const groups = []; + const processedPositions = new CoordSet(); + for (const neighbor of neighbors) { + if (processedPositions.has(neighbor)) { + continue; + } + const stone = board[neighbor.x][neighbor.y][neighbor.z]; + if (excludeEmpty && stone === exports.StoneType.EMPTY) { + continue; + } + if (stone !== exports.StoneType.EMPTY) { + const group = findGroup(neighbor, board, shape); + group.positions.forEach((p) => processedPositions.insert(p)); + groups.push(group); + } + } + return groups; +} +/** + * Check if a group would be captured (has no liberties) + */ +function isGroupCaptured(group, board, shape) { + const liberties = group.getLiberties(board, shape); + return liberties.size() === 0; +} +/** + * Find all groups that would be captured by placing a stone at position + * + * Equivalent to Game.killedPatches() in prototype + * + * Note: Prototype checks patchAir <= 1 BEFORE placement. + * We create a temp board with stone placed, then check for 0 liberties AFTER. + * Both approaches produce the same result. + */ +function findCapturedGroups(pos, playerColor, board, shape) { + const enemyColor = getEnemyColor(playerColor); + const captured = []; + // Create a temporary board with the new stone placed + const tempBoard = board.map((plane) => plane.map((row) => [...row])); + tempBoard[pos.x][pos.y][pos.z] = playerColor; + // Check all neighboring enemy groups + const neighborGroups = getNeighborGroups(pos, tempBoard, shape, true); + for (const group of neighborGroups) { + if (group.color === enemyColor) { + if (isGroupCaptured(group, tempBoard, shape)) { + captured.push(group); + } + } + } + return captured; +} +/** + * Check if placing a stone at position would result in self-capture (suicide) + * + * Equivalent to Game.isDeadStone() in prototype + * + * Exception: Move is allowed if it captures enemy stones first + */ +function isSuicideMove(pos, playerColor, board, shape) { + // Create temporary board with the new stone + const tempBoard = board.map((plane) => plane.map((row) => [...row])); + tempBoard[pos.x][pos.y][pos.z] = playerColor; + // If this move captures enemy stones, it's not suicide + const capturedGroups = findCapturedGroups(pos, playerColor, board, shape); + if (capturedGroups.length > 0) { + return false; + } + // Check if the placed stone's group has any liberties + const placedGroup = findGroup(pos, tempBoard, shape); + const liberties = placedGroup.getLiberties(tempBoard, shape); + return liberties.size() === 0; +} +/** + * Ko Detection - check if move would recreate previous board state + * + * Equivalent to "rob" check in Game.isDropable() (lines 127-132) + * Note: Ko rule is called "rob" (打劫 dǎjié) in the prototype + * + * Ko rule: Cannot immediately recapture a single stone if it would + * return the board to the previous position + */ +function isKoViolation(pos, playerColor, board, shape, lastCapturedPositions) { + // Ko only applies when: + // 1. We would capture exactly one stone + // 2. The previous move also captured exactly one stone + // 3. We're placing at the position of the previously captured stone + if (!lastCapturedPositions || lastCapturedPositions.length !== 1) { + return false; + } + const capturedGroups = findCapturedGroups(pos, playerColor, board, shape); + // Check if this move would capture exactly one stone + if (capturedGroups.length !== 1 || capturedGroups[0].size() !== 1) { + return false; + } + // Check if we're placing at the position that was just captured + const previouslyCaptured = lastCapturedPositions[0]; + if (positionsEqual(pos, previouslyCaptured)) { + return true; + } + return false; +} +/** + * Execute captures on the board + * Returns the positions of captured stones + */ +function executeCaptures(capturedGroups, board) { + const capturedPositions = []; + for (const group of capturedGroups) { + group.positions.forEach((pos) => { + board[pos.x][pos.y][pos.z] = exports.StoneType.EMPTY; + capturedPositions.push(pos); + }); + } + return capturedPositions; +} +/** + * Find all connected empty positions starting from a position + */ +function findEmptyRegion(startPos, board, shape, visited) { + const region = new CoordSet(); + const stack = [startPos]; + while (stack.length > 0) { + const pos = stack.pop(); + if (visited.has(pos)) { + continue; + } + visited.insert(pos); + if (board[pos.x][pos.y][pos.z] === exports.StoneType.EMPTY) { + region.insert(pos); + const neighbors = getNeighbors(pos, shape); + for (const neighbor of neighbors) { + if (!visited.has(neighbor)) { + stack.push(neighbor); + } + } + } + } + return region; +} +/** + * Determine which player owns an empty region + * Returns BLACK, WHITE, or EMPTY (neutral/dame) + * + * Equivalent to PatchList.spaceDomain() in prototype (lines 561-585) + * An empty region belongs to a player if ALL bordering stones are that color + */ +function determineRegionOwner(region, board, shape) { + let owner = exports.StoneType.EMPTY; + let solved = false; // Flag to break out when we find mixed colors + region.forEach((pos) => { + if (solved) + return; // Skip if already determined to be neutral + const neighbors = getNeighbors(pos, shape); + for (const neighbor of neighbors) { + if (solved) + break; // Skip if already determined to be neutral + const stone = board[neighbor.x][neighbor.y][neighbor.z]; + if (stone !== exports.StoneType.EMPTY) { + if (owner === exports.StoneType.EMPTY) { + // First colored stone we've found + owner = stone; + } + else if (owner !== stone) { + // Found a different colored stone - region is neutral + owner = exports.StoneType.EMPTY; + solved = true; // Mark as solved so we stop checking + } + } + } + }); + return owner; +} +/** + * Calculate territory for both players + * + * Equivalent to Game.calculateDomainSize() in prototype (lines 305-343) + * Uses PatchList.spaceDomain() logic to determine region ownership + * + * Algorithm: + * 1. First pass: Add all stones to their player's territory, collect empty regions + * 2. Second pass: Determine ownership of each empty region + */ +function calculateTerritory(board, shape) { + const result = { + black: 0, + white: 0, + neutral: 0, + blackTerritory: [], + whiteTerritory: [], + neutralTerritory: [] + }; + const visited = new CoordSet(); + const emptyRegions = []; + // FIRST PASS: Count all stones and find all empty regions + for (let x = 0; x < shape.x; x++) { + for (let y = 0; y < shape.y; y++) { + for (let z = 0; z < shape.z; z++) { + const pos = { x, y, z }; + const stone = board[x][y][z]; + if (stone === exports.StoneType.BLACK) { + result.black++; + result.blackTerritory.push(pos); + } + else if (stone === exports.StoneType.WHITE) { + result.white++; + result.whiteTerritory.push(pos); + } + else if (!visited.has(pos)) { + // Found an empty position - explore the region and save it + const region = findEmptyRegion(pos, board, shape, visited); + emptyRegions.push(region); + } + } + } + } + // SECOND PASS: Determine ownership of each empty region + for (const region of emptyRegions) { + const owner = determineRegionOwner(region, board, shape); + const regionArray = region.toArray(); + if (owner === exports.StoneType.BLACK) { + result.black += region.size(); + result.blackTerritory.push(...regionArray); + } + else if (owner === exports.StoneType.WHITE) { + result.white += region.size(); + result.whiteTerritory.push(...regionArray); + } + else { + result.neutral += region.size(); + result.neutralTerritory.push(...regionArray); + } + } + return result; +} +function validateMove(pos, playerColor, board, shape, lastCapturedPositions = null) { + // Check bounds + if (!isInBounds(pos, shape)) { + return { valid: false, reason: "Position out of bounds" }; + } + // Check if position is empty + if (board[pos.x][pos.y][pos.z] !== exports.StoneType.EMPTY) { + return { valid: false, reason: "Position already occupied" }; + } + // Check for Ko violation + if (isKoViolation(pos, playerColor, board, shape, lastCapturedPositions)) { + return { valid: false, reason: "Ko rule violation" }; + } + // Check for suicide (self-capture) + if (isSuicideMove(pos, playerColor, board, shape)) { + return { valid: false, reason: "suicide move not allowed" }; + } + return { valid: true }; +} +//# sourceMappingURL=gameUtils.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/gameUtils.js.map b/trigo-web/backend/dist/inc/trigo/gameUtils.js.map new file mode 100644 index 0000000000000000000000000000000000000000..8de95fae1276f38b6809c293305c823ad1267ebe --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/gameUtils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gameUtils.js","sourceRoot":"","sources":["../../../../inc/trigo/gameUtils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/index.d.ts b/trigo-web/backend/dist/inc/trigo/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b68c4f3e23dbffd271f69c0e5a582d1ba6bdb88a --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/index.d.ts @@ -0,0 +1,5 @@ +export * from "./types"; +export * from "./gameUtils"; +export * from "./game"; +export * from "./typeAdapters"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/index.d.ts.map b/trigo-web/backend/dist/inc/trigo/index.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..7989672f360adc2d6c523cb091d2b4e09eaf919f --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/index.js b/trigo-web/backend/dist/inc/trigo/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cd5c95f26ecf58dc614828455ba8cbcc7cc5a8e2 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/index.js @@ -0,0 +1,21 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./types"), exports); +__exportStar(require("./gameUtils"), exports); +__exportStar(require("./game"), exports); +__exportStar(require("./typeAdapters"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/index.js.map b/trigo-web/backend/dist/inc/trigo/index.js.map new file mode 100644 index 0000000000000000000000000000000000000000..a8802f4ef56efeee4f1ac384e394922a675b15ca --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../inc/trigo/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,8CAA4B;AAC5B,yCAAuB;AACvB,iDAA+B"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/parserInit.d.ts b/trigo-web/backend/dist/inc/trigo/parserInit.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a785f9e94f0ec1032eb6fa0ce35bbe549da9acbb --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/parserInit.d.ts @@ -0,0 +1,9 @@ +/** + * Initialize all parsers for use in the application + * Should be called once at application startup + * + * In browser: Dynamically imports from /lib/ + * In Node.js: Loads from project's public/lib directory + */ +export function initializeParsers(): Promise; +//# sourceMappingURL=parserInit.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/parserInit.d.ts.map b/trigo-web/backend/dist/inc/trigo/parserInit.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..911e74e6ab4ddec147e2ab7b1eb154a0bf188941 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/parserInit.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"parserInit.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/parserInit.js"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,mDAgBC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/parserInit.js b/trigo-web/backend/dist/inc/trigo/parserInit.js new file mode 100644 index 0000000000000000000000000000000000000000..cd15d9d10c4cb69e898aa36d80029e457cdf6649 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/parserInit.js @@ -0,0 +1,154 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.initializeParsers = initializeParsers; +/** + * Parser Initialization Module + * + * Loads pre-built parsers from public/lib and injects them into parser wrappers + * This allows the same synchronous API to work in both browser and Node.js + * + * Usage in Node.js tests: + * ``` + * import { initializeParsers } from "@inc/trigo/parserInit" + * await initializeParsers() + * ``` + * + * Usage in Vue app: + * Add to main.ts before using any game functionality + */ +const tgnParser_1 = require("../tgn/tgnParser"); +/** + * Check if we're in a browser environment + */ +function isBrowser() { + return typeof window !== "undefined" && typeof document !== "undefined"; +} +/** + * Check if we're in a Node.js environment + */ +function isNode() { + return typeof process !== "undefined" && !!process.versions && !!process.versions.node; +} +/** + * Initialize all parsers for use in the application + * Should be called once at application startup + * + * In browser: Dynamically imports from /lib/ + * In Node.js: Loads from project's public/lib directory + */ +async function initializeParsers() { + try { + if (isBrowser()) { + await initializeParsersForBrowser(); + } + else if (isNode()) { + await initializeParsersForNode(); + } + else { + throw new Error("Unable to determine runtime environment"); + } + } + catch (error) { + console.error("❌ Failed to initialize parsers:", error); + throw error; + } +} +/** + * Initialize parsers for browser environment + * Loads parsers from /lib/ which is served by Vite in dev and included in build + */ +async function initializeParsersForBrowser() { + try { + // In browser, fetch the parser from the public directory + // Vite serves /public as / so /lib/tgnParser.cjs maps to public/lib/tgnParser.cjs + const libPath = "/" + "lib/tgnParser.cjs"; + const response = await fetch(libPath); + if (!response.ok) { + throw new Error(`Failed to fetch parser: ${response.status} ${response.statusText}`); + } + const code = await response.text(); + // Create a CommonJS module environment + // The jison parser checks: if (typeof require !== 'undefined' && typeof exports !== 'undefined') + // So we need to make these available as variables in the eval scope + const module = { exports: {} }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const exports = module.exports; + // We need 'require' to be defined (but can be a dummy) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const require = function () { throw new Error("require not available in browser"); }; + // Eval in a scope where module, exports, and require are defined + // eslint-disable-next-line no-eval + eval(code); + // The jison parser exports: exports.parser = tgnParser + // So module.exports.parser is the actual parser instance + const parser = module.exports.parser; + if (!parser || typeof parser.parse !== 'function') { + throw new Error("Parser loaded but parse method not available"); + } + (0, tgnParser_1.setParserModule)(parser); + } + catch (error) { + console.error("✗ Failed to load TGN parser:", error); + throw error; + } +} +/** + * Initialize parsers for Node.js environment + * Loads parsers from project's public/lib directory + */ +async function initializeParsersForNode() { + try { + // Import Node.js modules dynamically + const pathModule = await Promise.resolve().then(() => __importStar(require("path"))); + const urlModule = await Promise.resolve().then(() => __importStar(require("url"))); + const path = pathModule.default; + const { fileURLToPath, pathToFileURL } = urlModule; + // Get project root directory + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const projectRoot = path.resolve(__dirname, "../.."); + const libPath = path.resolve(projectRoot, "public/lib"); + // Load TGN parser + const tgnParserPath = path.resolve(libPath, "tgnParser.cjs"); + const tgnParserModule = await Promise.resolve(`${pathToFileURL(tgnParserPath).href}`).then(s => __importStar(require(s))); + const tgnParser = tgnParserModule.parser; + (0, tgnParser_1.setParserModule)(tgnParser); + } + catch (error) { + console.error("✗ Failed to load TGN parser:", error); + throw error; + } +} +//# sourceMappingURL=parserInit.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/parserInit.js.map b/trigo-web/backend/dist/inc/trigo/parserInit.js.map new file mode 100644 index 0000000000000000000000000000000000000000..3ef1c50074578c9d51a7562f460bc0fe5f5bbc4b --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/parserInit.js.map @@ -0,0 +1 @@ +{"version":3,"file":"parserInit.js","sourceRoot":"","sources":["../../../../inc/trigo/parserInit.js"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts b/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..67c93101a34a89be4796e8d63ae18f4dfbd62532 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts @@ -0,0 +1,265 @@ +/** + * TrigoGame Class - Main Game State Management + * + * Modern reimplementation of prototype's trigo.Game + * Integrates game state, move history, and game logic in a single class + * + * Equivalent to: third_party/klstrigo/Source/static/js/trigo.game.js:75-601 + */ +import type { Position, Stone, BoardShape } from "./types"; +import { type TerritoryResult } from "./game"; +/** + * Step Types - Different types of moves in the game + * Equivalent to trigo.Game.StepType in prototype + */ +export declare enum StepType { + DROP = 0,// Place a stone + PASS = 1,// Pass turn + SURRENDER = 2,// Resign/surrender + UNDO = 3 +} +/** + * Game Status enumeration + */ +export type GameStatus = "idle" | "playing" | "paused" | "finished"; +/** + * Game Result information + */ +export interface GameResult { + winner: "black" | "white" | "draw"; + reason: "resignation" | "timeout" | "completion" | "double-pass"; + score?: TerritoryResult; +} +/** + * Step - Represents a single move in the game + * Equivalent to step objects in prototype's StepHistory + */ +export interface Step { + type: StepType; + position?: Position; + player: Stone; + capturedPositions?: Position[]; + timestamp: number; +} +/** + * Game Callbacks - Event handlers for game state changes + * Equivalent to Callbacks in prototype's trigo.Game constructor + */ +export interface GameCallbacks { + onStepAdvance?: (step: Step, history: Step[]) => void; + onStepBack?: (step: Step, history: Step[]) => void; + onCapture?: (capturedPositions: Position[]) => void; + onWin?: (winner: Stone) => void; + onTerritoryChange?: (territory: TerritoryResult) => void; +} +/** + * TrigoGame - Main game class managing state, history, and logic + * + * Equivalent to trigo.Game in prototype (lines 75-395) + * + * Key features: + * - Maintains game board state + * - Tracks complete move history + * - Implements Go rules (capture, Ko, suicide) + * - Supports undo/redo functionality + * - Territory calculation + */ +export declare class TrigoGame { + private shape; + private callbacks; + private board; + private currentPlayer; + private stepHistory; + private currentStepIndex; + private gameStatus; + private gameResult?; + private passCount; + private lastCapturedPositions; + private territoryDirty; + private cachedTerritory; + /** + * Constructor + * Equivalent to trigo.Game constructor (lines 75-85) + */ + constructor(shape?: BoardShape, callbacks?: GameCallbacks); + /** + * Create an empty board + */ + private createEmptyBoard; + /** + * Reset the game to initial state + * Equivalent to Game.reset() (lines 153-163) + */ + reset(): void; + /** + * Get current board state (read-only) + */ + getBoard(): Stone[][][]; + /** + * Get stone at specific position + * Equivalent to Game.stone() (lines 95-97) + */ + getStone(pos: Position): Stone; + /** + * Get current player + */ + getCurrentPlayer(): Stone; + /** + * Get current step number + * Equivalent to Game.currentStep() (lines 99-101) + */ + getCurrentStep(): number; + /** + * Get move history + * Equivalent to Game.routine() (lines 103-105) + */ + getHistory(): Step[]; + /** + * Get last move + * Equivalent to Game.lastStep() (lines 107-110) + */ + getLastStep(): Step | null; + /** + * Get board shape + * Equivalent to Game.shape() (lines 87-89) + */ + getShape(): BoardShape; + /** + * Get game status + */ + getGameStatus(): GameStatus; + /** + * Set game status + */ + setGameStatus(status: GameStatus): void; + /** + * Get game result + */ + getGameResult(): GameResult | undefined; + /** + * Get consecutive pass count + */ + getPassCount(): number; + /** + * Start the game + */ + startGame(): void; + /** + * Check if game is active + */ + isGameActive(): boolean; + /** + * Check if a move is valid + * Equivalent to Game.isDropable() and Game.isValidStep() (lines 112-151) + */ + isValidMove(pos: Position, player?: Stone): { + valid: boolean; + reason?: string; + }; + /** + * Reset pass count (called when a stone is placed) + */ + private resetPassCount; + /** + * Place a stone (drop move) + * Equivalent to Game.drop() and Game.appendStone() (lines 181-273) + * + * @returns true if move was successful, false otherwise + */ + drop(pos: Position): boolean; + /** + * Pass turn + * Equivalent to PASS step type in prototype + */ + pass(): boolean; + /** + * Surrender/resign + * Equivalent to Game.step() with SURRENDER type (lines 176-178) + */ + surrender(): boolean; + /** + * Undo last move + * Equivalent to Game.repent() (lines 197-230) + * + * @returns true if undo was successful, false if no moves to undo + */ + undo(): boolean; + /** + * Redo next move (after undo) + * + * @returns true if redo was successful, false if no moves to redo + */ + redo(): boolean; + /** + * Check if redo is available + */ + canRedo(): boolean; + /** + * Jump to specific step in history + * Rebuilds board state up to the target index + * + * @param index Target step index (-1 for initial state, 0 for first move, etc.) + * @returns true if jump was successful + */ + jumpToStep(index: number): boolean; + /** + * Advance to next step + * Equivalent to Game.stepAdvance() (lines 279-287) + */ + private advanceStep; + /** + * Get territory calculation + * Equivalent to Game.blackDomain() and Game.whiteDomain() (lines 232-244) + * + * Returns cached result if territory hasn't changed + */ + getTerritory(): TerritoryResult; + /** + * Get captured stone counts + */ + getCapturedCounts(): { + black: number; + white: number; + }; + /** + * Serialize game state to JSON + * Equivalent to Game.serialize() (lines 250-252) + */ + toJSON(): object; + /** + * Load game state from JSON + */ + fromJSON(data: any): boolean; + /** + * Get game statistics + */ + getStats(): { + totalMoves: number; + blackMoves: number; + whiteMoves: number; + capturedByBlack: number; + capturedByWhite: number; + territory: TerritoryResult; + }; + /** + * Save game state to sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if save was successful + */ + saveToSessionStorage(key?: string): boolean; + /** + * Load game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if load was successful + */ + loadFromSessionStorage(key?: string): boolean; + /** + * Clear saved game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + */ + clearSessionStorage(key?: string): void; +} +//# sourceMappingURL=trigoGame.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts.map b/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..0a374ae8b472ad12da01cbcc062d50ca2c9c0b25 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/trigoGame.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoGame.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/trigoGame.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/trigoGame.js b/trigo-web/backend/dist/inc/trigo/trigoGame.js new file mode 100644 index 0000000000000000000000000000000000000000..b2a5149fa15537d3503e00d259fe72c5254a8881 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/trigoGame.js @@ -0,0 +1,647 @@ +"use strict"; +/** + * TrigoGame Class - Main Game State Management + * + * Modern reimplementation of prototype's trigo.Game + * Integrates game state, move history, and game logic in a single class + * + * Equivalent to: third_party/klstrigo/Source/static/js/trigo.game.js:75-601 + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TrigoGame = exports.StepType = void 0; +const game_1 = require("./game"); +/** + * Step Types - Different types of moves in the game + * Equivalent to trigo.Game.StepType in prototype + */ +var StepType; +(function (StepType) { + StepType[StepType["DROP"] = 0] = "DROP"; + StepType[StepType["PASS"] = 1] = "PASS"; + StepType[StepType["SURRENDER"] = 2] = "SURRENDER"; + StepType[StepType["UNDO"] = 3] = "UNDO"; // Undo last move (called "REPENT" in prototype) +})(StepType || (exports.StepType = StepType = {})); +/** + * TrigoGame - Main game class managing state, history, and logic + * + * Equivalent to trigo.Game in prototype (lines 75-395) + * + * Key features: + * - Maintains game board state + * - Tracks complete move history + * - Implements Go rules (capture, Ko, suicide) + * - Supports undo/redo functionality + * - Territory calculation + */ +class TrigoGame { + /** + * Constructor + * Equivalent to trigo.Game constructor (lines 75-85) + */ + constructor(shape = { x: 5, y: 5, z: 5 }, callbacks = {}) { + // Last captured stones for Ko rule detection + this.lastCapturedPositions = null; + // Territory cache + this.territoryDirty = true; + this.cachedTerritory = null; + this.shape = shape; + this.callbacks = callbacks; + this.board = this.createEmptyBoard(); + this.currentPlayer = game_1.StoneType.BLACK; + this.stepHistory = []; + this.currentStepIndex = 0; + this.gameStatus = "idle"; + this.gameResult = undefined; + this.passCount = 0; + } + /** + * Create an empty board + */ + createEmptyBoard() { + const board = []; + for (let x = 0; x < this.shape.x; x++) { + board[x] = []; + for (let y = 0; y < this.shape.y; y++) { + board[x][y] = []; + for (let z = 0; z < this.shape.z; z++) { + board[x][y][z] = game_1.StoneType.EMPTY; + } + } + } + return board; + } + /** + * Reset the game to initial state + * Equivalent to Game.reset() (lines 153-163) + */ + reset() { + this.board = this.createEmptyBoard(); + this.currentPlayer = game_1.StoneType.BLACK; + this.stepHistory = []; + this.currentStepIndex = 0; + this.lastCapturedPositions = null; + this.territoryDirty = true; + this.cachedTerritory = null; + this.gameStatus = "idle"; + this.gameResult = undefined; + this.passCount = 0; + } + /** + * Get current board state (read-only) + */ + getBoard() { + // Return a deep copy to prevent external modification + return this.board.map(plane => plane.map(row => [...row])); + } + /** + * Get stone at specific position + * Equivalent to Game.stone() (lines 95-97) + */ + getStone(pos) { + return this.board[pos.x][pos.y][pos.z]; + } + /** + * Get current player + */ + getCurrentPlayer() { + return this.currentPlayer; + } + /** + * Get current step number + * Equivalent to Game.currentStep() (lines 99-101) + */ + getCurrentStep() { + return this.currentStepIndex; + } + /** + * Get move history + * Equivalent to Game.routine() (lines 103-105) + */ + getHistory() { + return [...this.stepHistory]; + } + /** + * Get last move + * Equivalent to Game.lastStep() (lines 107-110) + */ + getLastStep() { + if (this.currentStepIndex > 0) { + return this.stepHistory[this.currentStepIndex - 1]; + } + return null; + } + /** + * Get board shape + * Equivalent to Game.shape() (lines 87-89) + */ + getShape() { + return { ...this.shape }; + } + /** + * Get game status + */ + getGameStatus() { + return this.gameStatus; + } + /** + * Set game status + */ + setGameStatus(status) { + this.gameStatus = status; + } + /** + * Get game result + */ + getGameResult() { + return this.gameResult; + } + /** + * Get consecutive pass count + */ + getPassCount() { + return this.passCount; + } + /** + * Start the game + */ + startGame() { + if (this.gameStatus === "idle") { + this.gameStatus = "playing"; + } + } + /** + * Check if game is active + */ + isGameActive() { + return this.gameStatus === "playing"; + } + /** + * Check if a move is valid + * Equivalent to Game.isDropable() and Game.isValidStep() (lines 112-151) + */ + isValidMove(pos, player) { + const playerColor = player || this.currentPlayer; + return (0, game_1.validateMove)(pos, playerColor, this.board, this.shape, this.lastCapturedPositions); + } + /** + * Reset pass count (called when a stone is placed) + */ + resetPassCount() { + this.passCount = 0; + } + /** + * Place a stone (drop move) + * Equivalent to Game.drop() and Game.appendStone() (lines 181-273) + * + * @returns true if move was successful, false otherwise + */ + drop(pos) { + // Validate the move + const validation = this.isValidMove(pos); + if (!validation.valid) { + console.warn(`Invalid move at (${pos.x}, ${pos.y}, ${pos.z}): ${validation.reason}`); + return false; + } + // Find captured groups BEFORE placing the stone + const capturedGroups = (0, game_1.findCapturedGroups)(pos, this.currentPlayer, this.board, this.shape); + // Place the stone on the board + this.board[pos.x][pos.y][pos.z] = this.currentPlayer; + // Execute captures + const capturedPositions = (0, game_1.executeCaptures)(capturedGroups, this.board); + // Store captured positions for Ko rule + this.lastCapturedPositions = capturedPositions.length > 0 ? capturedPositions : null; + // Mark territory as dirty + this.territoryDirty = true; + // Reset pass count when a stone is placed + this.resetPassCount(); + // Create step record + const step = { + type: StepType.DROP, + position: pos, + player: this.currentPlayer, + capturedPositions: capturedPositions.length > 0 ? capturedPositions : undefined, + timestamp: Date.now() + }; + // Advance to next step + this.advanceStep(step); + // Trigger callbacks + if (capturedPositions.length > 0 && this.callbacks.onCapture) { + this.callbacks.onCapture(capturedPositions); + } + if (this.territoryDirty && this.callbacks.onTerritoryChange) { + this.callbacks.onTerritoryChange(this.getTerritory()); + } + return true; + } + /** + * Pass turn + * Equivalent to PASS step type in prototype + */ + pass() { + const step = { + type: StepType.PASS, + player: this.currentPlayer, + timestamp: Date.now() + }; + this.lastCapturedPositions = null; + // Increment pass count + this.passCount++; + // Advance step + this.advanceStep(step); + // Check for double pass (game end condition) + if (this.passCount >= 2) { + // Calculate territory to determine winner + const territory = this.getTerritory(); + const capturedCounts = this.getCapturedCounts(); + const blackTotal = territory.black + capturedCounts.white; // black's territory + white stones captured + const whiteTotal = territory.white + capturedCounts.black; // white's territory + black stones captured + let winner; + if (blackTotal > whiteTotal) { + winner = "black"; + } + else if (whiteTotal > blackTotal) { + winner = "white"; + } + else { + winner = "draw"; + } + this.gameResult = { + winner, + reason: "double-pass", + score: territory + }; + this.gameStatus = "finished"; + // Trigger win callback + if (this.callbacks.onWin) { + const winnerStone = winner === "black" ? game_1.StoneType.BLACK : + winner === "white" ? game_1.StoneType.WHITE : game_1.StoneType.EMPTY; + this.callbacks.onWin(winnerStone); + } + } + return true; + } + /** + * Surrender/resign + * Equivalent to Game.step() with SURRENDER type (lines 176-178) + */ + surrender() { + const step = { + type: StepType.SURRENDER, + player: this.currentPlayer, + timestamp: Date.now() + }; + this.advanceStep(step); + // Set game result + const winner = this.currentPlayer === game_1.StoneType.BLACK ? "white" : "black"; + this.gameResult = { + winner, + reason: "resignation" + }; + this.gameStatus = "finished"; + // Trigger win callback for the opponent + const winnerStone = (0, game_1.getEnemyColor)(this.currentPlayer); + if (this.callbacks.onWin) { + this.callbacks.onWin(winnerStone); + } + return true; + } + /** + * Undo last move + * Equivalent to Game.repent() (lines 197-230) + * + * @returns true if undo was successful, false if no moves to undo + */ + undo() { + if (this.currentStepIndex === 0 || this.stepHistory.length === 0) { + return false; + } + const lastStep = this.stepHistory[this.currentStepIndex - 1]; + // Revert the move + if (lastStep.type === StepType.DROP && lastStep.position) { + // Remove the placed stone + this.board[lastStep.position.x][lastStep.position.y][lastStep.position.z] = game_1.StoneType.EMPTY; + // Restore captured stones + if (lastStep.capturedPositions) { + const enemyColor = (0, game_1.getEnemyColor)(lastStep.player); + for (const pos of lastStep.capturedPositions) { + this.board[pos.x][pos.y][pos.z] = enemyColor; + } + } + } + // Move back in history + this.currentStepIndex--; + this.currentPlayer = lastStep.player; // Restore player who made that move + // Update last captured positions for Ko rule + // Need to check the step before this one + if (this.currentStepIndex > 0) { + const previousStep = this.stepHistory[this.currentStepIndex - 1]; + this.lastCapturedPositions = previousStep.capturedPositions || null; + } + else { + this.lastCapturedPositions = null; + } + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback + if (this.callbacks.onStepBack) { + this.callbacks.onStepBack(lastStep, this.stepHistory.slice(0, this.currentStepIndex)); + } + return true; + } + /** + * Redo next move (after undo) + * + * @returns true if redo was successful, false if no moves to redo + */ + redo() { + // Check if we can redo (not at the end of history) + if (this.currentStepIndex >= this.stepHistory.length) { + return false; + } + const nextStep = this.stepHistory[this.currentStepIndex]; + // Re-apply the move + if (nextStep.type === StepType.DROP && nextStep.position) { + // Place the stone + this.board[nextStep.position.x][nextStep.position.y][nextStep.position.z] = nextStep.player; + // Re-execute captures if there were any + if (nextStep.capturedPositions) { + for (const pos of nextStep.capturedPositions) { + this.board[pos.x][pos.y][pos.z] = game_1.StoneType.EMPTY; + } + } + // Update last captured positions + this.lastCapturedPositions = nextStep.capturedPositions || null; + } + else if (nextStep.type === StepType.PASS) { + this.lastCapturedPositions = null; + } + // Move forward in history + this.currentStepIndex++; + this.currentPlayer = (0, game_1.getEnemyColor)(nextStep.player); // Switch to next player + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback + if (this.callbacks.onStepAdvance) { + this.callbacks.onStepAdvance(nextStep, this.stepHistory.slice(0, this.currentStepIndex)); + } + return true; + } + /** + * Check if redo is available + */ + canRedo() { + return this.currentStepIndex < this.stepHistory.length; + } + /** + * Jump to specific step in history + * Rebuilds board state up to the target index + * + * @param index Target step index (-1 for initial state, 0 for first move, etc.) + * @returns true if jump was successful + */ + jumpToStep(index) { + // Validate index + if (index < -1 || index >= this.stepHistory.length) { + return false; + } + // If already at target index, do nothing + if (index === this.currentStepIndex) { + return true; + } + // Rebuild board from scratch + this.board = this.createEmptyBoard(); + this.lastCapturedPositions = null; + // Replay all moves up to target index + for (let i = 0; i <= index; i++) { + const step = this.stepHistory[i]; + if (step.type === StepType.DROP && step.position) { + const pos = step.position; + // Place the stone + this.board[pos.x][pos.y][pos.z] = step.player; + // Re-execute captures + if (step.capturedPositions) { + for (const capturedPos of step.capturedPositions) { + this.board[capturedPos.x][capturedPos.y][capturedPos.z] = game_1.StoneType.EMPTY; + } + } + // Update last captured for Ko rule (only for the last move) + if (i === index) { + this.lastCapturedPositions = step.capturedPositions || null; + } + } + else if (step.type === StepType.PASS && i === index) { + this.lastCapturedPositions = null; + } + } + // Update current index + this.currentStepIndex = index; + // Set current player based on number of moves played + const movesPlayed = index + 1; + this.currentPlayer = movesPlayed % 2 === 0 ? game_1.StoneType.BLACK : game_1.StoneType.WHITE; + // Mark territory as dirty + this.territoryDirty = true; + // Trigger callback based on direction + if (index < this.currentStepIndex && this.callbacks.onStepBack) { + const currentStep = this.stepHistory[index]; + this.callbacks.onStepBack(currentStep, this.stepHistory.slice(0, index + 1)); + } + else if (index > this.currentStepIndex && this.callbacks.onStepAdvance) { + const currentStep = this.stepHistory[index]; + this.callbacks.onStepAdvance(currentStep, this.stepHistory.slice(0, index + 1)); + } + return true; + } + /** + * Advance to next step + * Equivalent to Game.stepAdvance() (lines 279-287) + */ + advanceStep(step) { + // If we're not at the end of history, truncate future steps + if (this.currentStepIndex < this.stepHistory.length) { + this.stepHistory = this.stepHistory.slice(0, this.currentStepIndex); + } + // Add the new step + this.stepHistory.push(step); + this.currentStepIndex++; + // Switch player + this.currentPlayer = (0, game_1.getEnemyColor)(this.currentPlayer); + // Trigger callback + if (this.callbacks.onStepAdvance) { + this.callbacks.onStepAdvance(step, this.stepHistory); + } + } + /** + * Get territory calculation + * Equivalent to Game.blackDomain() and Game.whiteDomain() (lines 232-244) + * + * Returns cached result if territory hasn't changed + */ + getTerritory() { + if (this.territoryDirty || !this.cachedTerritory) { + this.cachedTerritory = (0, game_1.calculateTerritory)(this.board, this.shape); + this.territoryDirty = false; + } + return this.cachedTerritory; + } + /** + * Get captured stone counts + */ + getCapturedCounts() { + const counts = { black: 0, white: 0 }; + for (const step of this.stepHistory) { + if (step.capturedPositions && step.capturedPositions.length > 0) { + // Captured stones belong to the enemy of the player who made the move + const enemyColor = (0, game_1.getEnemyColor)(step.player); + if (enemyColor === game_1.StoneType.BLACK) { + counts.black += step.capturedPositions.length; + } + else if (enemyColor === game_1.StoneType.WHITE) { + counts.white += step.capturedPositions.length; + } + } + } + return counts; + } + /** + * Serialize game state to JSON + * Equivalent to Game.serialize() (lines 250-252) + */ + toJSON() { + return { + shape: this.shape, + currentPlayer: this.currentPlayer, + currentStepIndex: this.currentStepIndex, + history: this.stepHistory, + board: this.board, + gameStatus: this.gameStatus, + gameResult: this.gameResult, + passCount: this.passCount + }; + } + /** + * Load game state from JSON + */ + fromJSON(data) { + try { + this.shape = data.shape; + this.currentPlayer = data.currentPlayer; + this.currentStepIndex = data.currentStepIndex; + this.stepHistory = data.history || []; + this.board = data.board; + this.gameStatus = data.gameStatus || "idle"; + this.gameResult = data.gameResult; + this.passCount = data.passCount || 0; + // Recalculate last captured positions + if (this.currentStepIndex > 0) { + const lastStep = this.stepHistory[this.currentStepIndex - 1]; + this.lastCapturedPositions = lastStep.capturedPositions || null; + } + else { + this.lastCapturedPositions = null; + } + this.territoryDirty = true; + this.cachedTerritory = null; + return true; + } + catch (error) { + console.error("Failed to load game state:", error); + return false; + } + } + /** + * Get game statistics + */ + getStats() { + const captured = this.getCapturedCounts(); + const territory = this.getTerritory(); + let blackMoves = 0; + let whiteMoves = 0; + for (const step of this.stepHistory.slice(0, this.currentStepIndex)) { + if (step.type === StepType.DROP) { + if (step.player === game_1.StoneType.BLACK) { + blackMoves++; + } + else if (step.player === game_1.StoneType.WHITE) { + whiteMoves++; + } + } + } + return { + totalMoves: this.currentStepIndex, + blackMoves, + whiteMoves, + capturedByBlack: captured.white, // Black captures white stones + capturedByWhite: captured.black, // White captures black stones + territory + }; + } + /** + * Save game state to sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if save was successful + */ + saveToSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + const gameState = this.toJSON(); + globalThis.sessionStorage.setItem(key, JSON.stringify(gameState)); + return true; + } + catch (error) { + console.error("Failed to save game state to sessionStorage:", error); + return false; + } + } + console.warn("sessionStorage is not available"); + return false; + } + /** + * Load game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + * @returns true if load was successful + */ + loadFromSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + const savedState = globalThis.sessionStorage.getItem(key); + if (!savedState) { + console.log("No saved game state found"); + return false; + } + const data = JSON.parse(savedState); + return this.fromJSON(data); + } + catch (error) { + console.error("Failed to load game state from sessionStorage:", error); + return false; + } + } + console.warn("sessionStorage is not available"); + return false; + } + /** + * Clear saved game state from sessionStorage + * + * @param key Storage key (default: "trigoGameState") + */ + clearSessionStorage(key = "trigoGameState") { + // Check if sessionStorage is available (browser environment) + if (typeof globalThis !== "undefined" && globalThis.sessionStorage) { + try { + globalThis.sessionStorage.removeItem(key); + } + catch (error) { + console.error("Failed to clear sessionStorage:", error); + } + } + else { + console.warn("sessionStorage is not available"); + } + } +} +exports.TrigoGame = TrigoGame; +//# sourceMappingURL=trigoGame.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/trigoGame.js.map b/trigo-web/backend/dist/inc/trigo/trigoGame.js.map new file mode 100644 index 0000000000000000000000000000000000000000..e951cdf508404d58682645e59d1f6cb764f4774c --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/trigoGame.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoGame.js","sourceRoot":"","sources":["../../../../inc/trigo/trigoGame.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts b/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8b821c5337db6bf113d865af689340a826f86ea --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts @@ -0,0 +1,58 @@ +/** + * Type Adapters - Convert between frontend string types and TrigoGame number types + * + * Frontend gameStore uses string types like "black"|"white" for better readability + * TrigoGame uses number enum (StoneType) for better performance and compatibility with legacy code + * + * This module provides conversion functions between these two systems + */ +import type { Stone, Position, Player, Move } from "./types"; +import type { Step } from "./game"; +/** + * Convert Player string to Stone number + * + * @param player "black" | "white" + * @returns StoneType.BLACK | StoneType.WHITE + */ +export declare function playerToStone(player: Player): Stone; +/** + * Convert Stone number to Player string + * + * @param stone StoneType enum value + * @returns "black" | "white" + */ +export declare function stoneToPlayer(stone: Stone): Player; +/** + * Convert Step (TrigoGame format) to Move (frontend format) + * + * @param step Step from TrigoGame history + * @returns Move for frontend gameStore + */ +export declare function stepToMove(step: Step): Move; +/** + * Convert array of Steps to array of Moves + * + * @param steps Array of Steps from TrigoGame + * @returns Array of Moves for frontend + */ +export declare function stepsToMoves(steps: Step[]): Move[]; +/** + * Convert board (Stone[][][]) to frontend format (number[][][]) + * + * Frontend may prefer explicit number format + * 0 = Empty, 1 = Black, 2 = White + * + * @param board TrigoGame board + * @returns Frontend board format + */ +export declare function boardToNumbers(board: Stone[][][]): number[][][]; +/** + * Helper: Create Position object from coordinates + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @returns Position object + */ +export declare function makePosition(x: number, y: number, z: number): Position; +//# sourceMappingURL=typeAdapters.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts.map b/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..c0a8ad25fc3e5fd55ce7b7e9f1b05703b481fd90 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/typeAdapters.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"typeAdapters.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/typeAdapters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAQlD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAoB3C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,CAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ,CAEtE"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/typeAdapters.js b/trigo-web/backend/dist/inc/trigo/typeAdapters.js new file mode 100644 index 0000000000000000000000000000000000000000..6ae5c16c6cc1c2a92b91be92f32b67d98e8d4dda --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/typeAdapters.js @@ -0,0 +1,99 @@ +"use strict"; +/** + * Type Adapters - Convert between frontend string types and TrigoGame number types + * + * Frontend gameStore uses string types like "black"|"white" for better readability + * TrigoGame uses number enum (StoneType) for better performance and compatibility with legacy code + * + * This module provides conversion functions between these two systems + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.playerToStone = playerToStone; +exports.stoneToPlayer = stoneToPlayer; +exports.stepToMove = stepToMove; +exports.stepsToMoves = stepsToMoves; +exports.boardToNumbers = boardToNumbers; +exports.makePosition = makePosition; +const game_1 = require("./game"); +/** + * Convert Player string to Stone number + * + * @param player "black" | "white" + * @returns StoneType.BLACK | StoneType.WHITE + */ +function playerToStone(player) { + return player === "black" ? game_1.StoneType.BLACK : game_1.StoneType.WHITE; +} +/** + * Convert Stone number to Player string + * + * @param stone StoneType enum value + * @returns "black" | "white" + */ +function stoneToPlayer(stone) { + if (stone === game_1.StoneType.BLACK) { + return "black"; + } + else if (stone === game_1.StoneType.WHITE) { + return "white"; + } + // Default to black if EMPTY or invalid + return "black"; +} +/** + * Convert Step (TrigoGame format) to Move (frontend format) + * + * @param step Step from TrigoGame history + * @returns Move for frontend gameStore + */ +function stepToMove(step) { + const move = { + player: stoneToPlayer(step.player), + timestamp: new Date(step.timestamp) + }; + // If it's a DROP move, include position + if (step.position) { + move.x = step.position.x; + move.y = step.position.y; + move.z = step.position.z; + } + // If it's a PASS move, set flag + if (step.type === 1) { + // StepType.PASS + move.isPass = true; + } + return move; +} +/** + * Convert array of Steps to array of Moves + * + * @param steps Array of Steps from TrigoGame + * @returns Array of Moves for frontend + */ +function stepsToMoves(steps) { + return steps.map(stepToMove); +} +/** + * Convert board (Stone[][][]) to frontend format (number[][][]) + * + * Frontend may prefer explicit number format + * 0 = Empty, 1 = Black, 2 = White + * + * @param board TrigoGame board + * @returns Frontend board format + */ +function boardToNumbers(board) { + return board.map((plane) => plane.map((row) => row.map((cell) => cell))); +} +/** + * Helper: Create Position object from coordinates + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @returns Position object + */ +function makePosition(x, y, z) { + return { x, y, z }; +} +//# sourceMappingURL=typeAdapters.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/typeAdapters.js.map b/trigo-web/backend/dist/inc/trigo/typeAdapters.js.map new file mode 100644 index 0000000000000000000000000000000000000000..7e3fd0441f6f4a76336e16a804513af999a9a527 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/typeAdapters.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typeAdapters.js","sourceRoot":"","sources":["../../../../inc/trigo/typeAdapters.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAYH,sCAEC;AAQD,sCAQC;AAQD,gCAoBC;AAQD,oCAEC;AAWD,wCAEC;AAUD,oCAEC;AA1FD,iCAAmC;AAGnC;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,MAAc;IAC3C,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAS,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAS,CAAC,KAAK,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,KAAY;IACzC,IAAI,KAAK,KAAK,gBAAS,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC;IAChB,CAAC;SAAM,IAAI,KAAK,KAAK,gBAAS,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,uCAAuC;IACvC,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,IAAU;IACpC,MAAM,IAAI,GAAS;QAClB,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;KACnC,CAAC;IAEF,wCAAwC;IACxC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED,gCAAgC;IAChC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,gBAAgB;QAChB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAAC,KAAkB;IAChD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAc,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS;IAC3D,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACpB,CAAC"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/types.d.ts b/trigo-web/backend/dist/inc/trigo/types.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..698e653a21a66bc043c33f3c159e56aa96b604e9 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/types.d.ts @@ -0,0 +1,43 @@ +export interface Position { + x: number; + y: number; + z: number; +} +export interface Move { + x?: number; + y?: number; + z?: number; + player: "black" | "white"; + timestamp?: Date; + isPass?: boolean; +} +export interface BoardShape { + x: number; + y: number; + z: number; +} +export interface GameConfig { + boardShape: BoardShape; + timeLimit?: number; + allowUndo: boolean; +} +export declare enum Stone { + Empty = 0, + Black = 1, + White = 2 +} +export type Player = "black" | "white"; +export interface GameRecord { + id: string; + moves: Move[]; + result?: { + winner: Player | "draw"; + reason: "resignation" | "timeout" | "completion" | "double-pass"; + }; + createdAt: Date; + players: { + black: string; + white: string; + }; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/types.d.ts.map b/trigo-web/backend/dist/inc/trigo/types.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..2953924eaec213fae5fca7f20d6c987ad592ba65 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../inc/trigo/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED,MAAM,WAAW,IAAI;IACpB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED,MAAM,WAAW,UAAU;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,oBAAY,KAAK;IAChB,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;CACT;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAEvC,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;KACjE,CAAC;IACF,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACd,CAAC;CACF"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/types.js b/trigo-web/backend/dist/inc/trigo/types.js new file mode 100644 index 0000000000000000000000000000000000000000..19a6426ad2f45a2145f13d589f18883db04fdf22 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/types.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Stone = void 0; +var Stone; +(function (Stone) { + Stone[Stone["Empty"] = 0] = "Empty"; + Stone[Stone["Black"] = 1] = "Black"; + Stone[Stone["White"] = 2] = "White"; +})(Stone || (exports.Stone = Stone = {})); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigo/types.js.map b/trigo-web/backend/dist/inc/trigo/types.js.map new file mode 100644 index 0000000000000000000000000000000000000000..8cff44f290d54b6075827f7b3fae2aa2ec6626a6 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigo/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../inc/trigo/types.ts"],"names":[],"mappings":";;;AA2BA,IAAY,KAIX;AAJD,WAAY,KAAK;IAChB,mCAAS,CAAA;IACT,mCAAS,CAAA;IACT,mCAAS,CAAA;AACV,CAAC,EAJW,KAAK,qBAAL,KAAK,QAIhB"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoAgent.d.ts b/trigo-web/backend/dist/inc/trigoAgent.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa318a0b714ea35d646b1c8231e3dab40e56e6a7 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoAgent.d.ts @@ -0,0 +1,79 @@ +/** + * Trigo AI Agent - Language Model-based Move Selection (Frontend/Backend Common) + * + * Platform-agnostic AI agent that accepts ONNX session from platform-specific code. + * No direct dependency on onnxruntime packages - uses dependency injection pattern. + * + * Uses ONNX language model to score and select moves by: + * 1. Getting all valid moves for current position + * 2. Scoring each move by appending it to TGN and computing token probabilities + * 3. Selecting move with highest probability (argmax) + */ +import { ModelInferencer } from "./modelInferencer"; +import { TrigoGame } from "./trigo/game"; +import type { Move } from "./trigo/types"; +/** + * Configuration for the AI agent + */ +export interface TrigoAgentConfig { + vocabSize?: number; + seqLen?: number; + temperature?: number; +} +/** + * Move score result + */ +export interface MoveScore { + move: Move; + score: number; + logProb: number; +} +/** + * Trigo AI Agent for move generation + * Compatible with both frontend (onnxruntime-web) and backend (onnxruntime-node) + */ +export declare class TrigoAgent { + private inferencer; + constructor(inferencer: ModelInferencer); + /** + * Check if agent is initialized (checks if inferencer has a session) + */ + isInitialized(): boolean; + /** + * Convert Stone type to player string + */ + private stoneToPlayer; + /** + * Convert string to token IDs (byte-level encoding with ASCII direct mapping) + * For characters 32-127, token_id = ascii_value + * Special tokens (0-3) and newline (10) are handled by the tokenizer + */ + private stringToTokens; + /** + * Compute softmax probabilities from logits + */ + private softmax; + /** + * Score a candidate move by computing token probabilities + * + * Clones the game, applies the move, generates new TGN, and computes + * the probability of the move tokens. + */ + scoreMove(game: TrigoGame, move: Move): Promise; + /** + * Extract move tokens from TGN difference + * Returns the tokens that were added between currentTGN and newTGN + */ + private extractMoveTokens; + /** + * Select the best move using the language model + * + * Scores all valid moves and returns the one with highest probability (argmax). + */ + selectBestMove(game: TrigoGame): Promise; + /** + * Clean up resources + */ + destroy(): void; +} +//# sourceMappingURL=trigoAgent.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoAgent.d.ts.map b/trigo-web/backend/dist/inc/trigoAgent.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..63429911c267136f8e81cf2d9be26acde0286b97 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoAgent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoAgent.d.ts","sourceRoot":"","sources":["../../../inc/trigoAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,eAAe,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,UAAU,CAAkB;gBAExB,UAAU,EAAE,eAAe;IAIvC;;OAEG;IACH,aAAa,IAAI,OAAO;IAKxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,OAAO;IA0Bf;;;;;OAKG;IACG,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAmF7D;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;OAIG;IACG,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAoD3D;;OAEG;IACH,OAAO,IAAI,IAAI;CAIf"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoAgent.js b/trigo-web/backend/dist/inc/trigoAgent.js new file mode 100644 index 0000000000000000000000000000000000000000..9e0c621e6cfa66ddaf0ec81a4d16baaa252bd2cd --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoAgent.js @@ -0,0 +1,211 @@ +"use strict"; +/** + * Trigo AI Agent - Language Model-based Move Selection (Frontend/Backend Common) + * + * Platform-agnostic AI agent that accepts ONNX session from platform-specific code. + * No direct dependency on onnxruntime packages - uses dependency injection pattern. + * + * Uses ONNX language model to score and select moves by: + * 1. Getting all valid moves for current position + * 2. Scoring each move by appending it to TGN and computing token probabilities + * 3. Selecting move with highest probability (argmax) + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TrigoAgent = void 0; +const game_1 = require("./trigo/game"); +/** + * Trigo AI Agent for move generation + * Compatible with both frontend (onnxruntime-web) and backend (onnxruntime-node) + */ +class TrigoAgent { + constructor(inferencer) { + this.inferencer = inferencer; + } + /** + * Check if agent is initialized (checks if inferencer has a session) + */ + isInitialized() { + // Agent is initialized if the inferencer has been set up + return this.inferencer !== null; + } + /** + * Convert Stone type to player string + */ + stoneToPlayer(stone) { + if (stone === game_1.StoneType.BLACK) + return "black"; + if (stone === game_1.StoneType.WHITE) + return "white"; + throw new Error(`Invalid stone type: ${stone}`); + } + /** + * Convert string to token IDs (byte-level encoding with ASCII direct mapping) + * For characters 32-127, token_id = ascii_value + * Special tokens (0-3) and newline (10) are handled by the tokenizer + */ + stringToTokens(text) { + return Array.from(text).map((char) => char.charCodeAt(0)); + } + /** + * Compute softmax probabilities from logits + */ + softmax(logits, vocabSize) { + const probs = new Float32Array(vocabSize); + let maxLogit = -Infinity; + // Find max for numerical stability + for (let i = 0; i < vocabSize; i++) { + if (logits[i] > maxLogit) { + maxLogit = logits[i]; + } + } + // Compute exp and sum + let sum = 0; + for (let i = 0; i < vocabSize; i++) { + probs[i] = Math.exp(logits[i] - maxLogit); + sum += probs[i]; + } + // Normalize + for (let i = 0; i < vocabSize; i++) { + probs[i] /= sum; + } + return probs; + } + /** + * Score a candidate move by computing token probabilities + * + * Clones the game, applies the move, generates new TGN, and computes + * the probability of the move tokens. + */ + async scoreMove(game, move) { + // Clone the game + const clonedGame = game.clone(); + // Apply the move to the cloned game + let success; + if (move.isPass) { + success = clonedGame.pass(); + } + else if (move.x !== undefined && move.y !== undefined && move.z !== undefined) { + success = clonedGame.drop({ x: move.x, y: move.y, z: move.z }); + } + else { + // Invalid move format + return -1000; + } + if (!success) { + // Invalid move, return very low probability + return -1000; + } + // Generate TGN from both original and cloned game + const newTGN = clonedGame.toTGN().trim(); + // Extract the move substring + // The move should be the new content added after the current TGN + const moveTokens = this.extractMoveTokens(newTGN); + if (moveTokens.length === 0) { + // Could not extract move, return low probability + return -100; + } + // Convert new TGN to tokens + const tokens = this.stringToTokens(newTGN); + // Get configuration + const config = this.inferencer.getConfig(); + const seqLen = config.seqLen; + const vocabSize = config.vocabSize; + // Truncate if too long + if (tokens.length > seqLen) { + tokens.splice(0, tokens.length - seqLen); + } + // Run inference (START_TOKEN will be prepended by inferencer) + const logits = await this.inferencer.runInference(tokens); + // Compute probability for the move tokens + // Note: inferencer prepends START_TOKEN, so positions are offset by +1 + // Token sequence: [START_TOKEN, ...tokens, PAD, PAD, ...] + // Position in output: token_i is at position i+1 in the padded sequence + // Find where move tokens start in original token sequence + const moveStartInTokens = tokens.length - moveTokens.length; + let logProb = 0; + for (let i = 0; i < moveTokens.length; i++) { + // Position of this move token in the original tokens array + const tokenPos = moveStartInTokens + i; + // Skip if position is out of bounds + // Logits at position tokenPos predict the token at tokenPos+1 + if (tokenPos < 0 || tokenPos >= tokens.length) + continue; + const offset = tokenPos * vocabSize; + const tokenLogits = logits.slice(offset, offset + vocabSize); + const probs = this.softmax(tokenLogits, vocabSize); + const tokenId = moveTokens[i]; + const prob = probs[tokenId]; + if (prob > 0) { + logProb += Math.log(prob); + } + else { + // If probability is zero, assign very low prob + logProb += -100; + } + } + return logProb; + } + /** + * Extract move tokens from TGN difference + * Returns the tokens that were added between currentTGN and newTGN + */ + extractMoveTokens(tgn) { + const moveCapture = tgn.match(/[Pa-z0]+$/); + return this.stringToTokens(moveCapture ? moveCapture[0] : ""); + } + /** + * Select the best move using the language model + * + * Scores all valid moves and returns the one with highest probability (argmax). + */ + async selectBestMove(game) { + if (!this.isInitialized()) { + throw new Error("Agent not initialized. Pass initialized inferencer to constructor."); + } + console.log("[TrigoAgent] Selecting move..."); + // Get current player as string + const currentPlayer = this.stoneToPlayer(game.getCurrentPlayer()); + // Get all valid moves + const validMoves = game.validMovePositions().map((pos) => ({ + x: pos.x, + y: pos.y, + z: pos.z, + player: currentPlayer + })); + validMoves.push({ player: currentPlayer, isPass: true }); // Add pass move + if (validMoves.length === 0) { + console.log("[TrigoAgent] No valid moves available"); + return null; + } + console.log(`[TrigoAgent] Evaluating ${validMoves.length} valid moves...`); + // Score each move + const scores = []; + for (const move of validMoves) { + const logProb = await this.scoreMove(game, move); + scores.push({ + move, + score: Math.exp(logProb), // Convert log prob to probability + logProb + }); + } + // Find best move (argmax) + scores.sort((a, b) => b.logProb - a.logProb); + const bestMove = scores[0]; + console.debug("scores:", scores); + console.log("[TrigoAgent] Best move:", bestMove.move, "score:", bestMove.score.toFixed(6)); + console.log("[TrigoAgent] Top 5 moves:"); + for (let i = 0; i < Math.min(5, scores.length); i++) { + console.log(` ${i + 1}. ${scores[i].move}: ${scores[i].score.toFixed(6)}`); + } + return bestMove.move; + } + /** + * Clean up resources + */ + destroy() { + this.inferencer.destroy(); + console.log("[TrigoAgent] Destroyed"); + } +} +exports.TrigoAgent = TrigoAgent; +//# sourceMappingURL=trigoAgent.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoAgent.js.map b/trigo-web/backend/dist/inc/trigoAgent.js.map new file mode 100644 index 0000000000000000000000000000000000000000..9ac61f72907f8b74ab0371ba197df696ed1028c0 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoAgent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoAgent.js","sourceRoot":"","sources":["../../../inc/trigoAgent.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts b/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..c5ccac1e5c5a70b8705570355a378c5e9612c0bd --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts @@ -0,0 +1,85 @@ +/** + * Trigo Evaluation Agent - AI agent using value prediction for position evaluation + * + * Uses evaluation mode ONNX model to predict game outcomes. + * The model takes a TGN sequence and returns a value in [-1, 1]: + * - Positive values favor White (second player) + * - Negative values favor Black (first player) + * - Values near ±1 indicate strong advantage + * - Values near 0 indicate balanced position + */ +import { ModelInferencer } from "./modelInferencer"; +import { TrigoGame } from "./trigo/game"; +import type { Move } from "./trigo/types"; +export interface ValuedMove { + move: Move; + value: number; + notation: string; +} +export interface PositionEvaluation { + value: number; + interpretation: string; +} +export declare class TrigoEvaluationAgent { + private inferencer; + private readonly START_TOKEN; + private readonly END_TOKEN; + private readonly VALUE_TOKEN; + constructor(inferencer: ModelInferencer); + /** + * Check if agent is initialized (checks if inferencer has a session) + */ + isInitialized(): boolean; + /** + * Convert Stone type to player string + */ + private stoneToPlayer; + /** + * Encode a position to TGN notation + */ + private positionToTGN; + /** + * Convert string to byte tokens (ASCII encoding) + */ + private stringToTokens; + /** + * Tokenize TGN text with special tokens + * Adds START and END tokens for proper sequence formatting + */ + private tokenizeTGN; + /** + * Evaluate a position by predicting the game outcome value + * @param game - The game to evaluate + * @returns Position evaluation with value and interpretation + */ + evaluatePosition(game: TrigoGame): Promise; + /** + * Interpret a position value to human-readable text + */ + private interpretValue; + /** + * Evaluate all valid moves and return them sorted by value + * @param game - Current game state + * @returns Array of moves with their position values + */ + evaluateMoves(game: TrigoGame): Promise; + /** + * Select the best move based on position evaluation + * @param game - Current game state + * @returns Best move or null if no moves available + */ + selectBestMove(game: TrigoGame): Promise; + /** + * Get detailed evaluation report for current position + */ + getEvaluationReport(game: TrigoGame): Promise<{ + currentValue: PositionEvaluation; + topMoves: ValuedMove[]; + moveCount: number; + }>; + /** + * Clean up resources + */ + destroy(): void; +} +//# sourceMappingURL=trigoEvaluationAgent.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts.map b/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..09a32c1d93a99709be97ed09ea772581109d1423 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoEvaluationAgent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoEvaluationAgent.d.ts","sourceRoot":"","sources":["../../../inc/trigoEvaluationAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAmB,MAAM,eAAe,CAAC;AAG3D,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,oBAAoB;IAChC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAK;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAK;gBAErB,UAAU,EAAE,eAAe;IAIvC;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;OAIG;IACG,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAqBpE;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;;;OAIG;IACG,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAsE3D;;;;OAIG;IACG,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgB3D;;OAEG;IACG,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;QACnD,YAAY,EAAE,kBAAkB,CAAC;QACjC,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IAWF;;OAEG;IACH,OAAO,IAAI,IAAI;CAIf"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoEvaluationAgent.js b/trigo-web/backend/dist/inc/trigoEvaluationAgent.js new file mode 100644 index 0000000000000000000000000000000000000000..e0997264862eb445a0dffb76ffb0137a6fa77960 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoEvaluationAgent.js @@ -0,0 +1,218 @@ +"use strict"; +/** + * Trigo Evaluation Agent - AI agent using value prediction for position evaluation + * + * Uses evaluation mode ONNX model to predict game outcomes. + * The model takes a TGN sequence and returns a value in [-1, 1]: + * - Positive values favor White (second player) + * - Negative values favor Black (first player) + * - Values near ±1 indicate strong advantage + * - Values near 0 indicate balanced position + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TrigoEvaluationAgent = void 0; +const game_1 = require("./trigo/game"); +const ab0yz_1 = require("./trigo/ab0yz"); +class TrigoEvaluationAgent { + constructor(inferencer) { + this.START_TOKEN = 1; + this.END_TOKEN = 2; + this.VALUE_TOKEN = 3; + this.inferencer = inferencer; + } + /** + * Check if agent is initialized (checks if inferencer has a session) + */ + isInitialized() { + return this.inferencer !== null && this.inferencer.isReady(); + } + /** + * Convert Stone type to player string + */ + stoneToPlayer(stone) { + if (stone === game_1.StoneType.BLACK) + return "black"; + if (stone === game_1.StoneType.WHITE) + return "white"; + throw new Error(`Invalid stone type: ${stone}`); + } + /** + * Encode a position to TGN notation + */ + positionToTGN(pos, shape) { + const posArray = [pos.x, pos.y, pos.z]; + const shapeArray = [shape.x, shape.y, shape.z]; + return (0, ab0yz_1.encodeAb0yz)(posArray, shapeArray); + } + /** + * Convert string to byte tokens (ASCII encoding) + */ + stringToTokens(str) { + const tokens = []; + for (let i = 0; i < str.length; i++) { + const charCode = str.charCodeAt(i); + // Only accept valid ASCII tokens (0-127) + if (charCode < 128) { + tokens.push(charCode); + } + } + return tokens; + } + /** + * Tokenize TGN text with special tokens + * Adds START and END tokens for proper sequence formatting + */ + tokenizeTGN(tgnText, maxLength = 256) { + // Convert TGN to tokens + const contentTokens = this.stringToTokens(tgnText); + // Add special tokens: START + content + END + const tokens = [this.START_TOKEN, ...contentTokens, this.END_TOKEN]; + // Truncate if needed (preserve END token) + if (tokens.length > maxLength) { + return [...tokens.slice(0, maxLength - 1), this.END_TOKEN]; + } + // Pad with PAD tokens (0) to fixed length + while (tokens.length < maxLength) { + tokens.push(0); // PAD_TOKEN + } + return tokens; + } + /** + * Evaluate a position by predicting the game outcome value + * @param game - The game to evaluate + * @returns Position evaluation with value and interpretation + */ + async evaluatePosition(game) { + if (!this.isInitialized()) { + throw new Error("Agent not initialized. Inferencer must have a session."); + } + // Get current TGN + const tgn = game.toTGN().trim(); + // Tokenize + const config = this.inferencer.getConfig(); + const tokens = this.tokenizeTGN(tgn, config.seqLen); + // Run value prediction inference + const value = await this.inferencer.runValuePrediction(tokens); + return { + value, + interpretation: this.interpretValue(value) + }; + } + /** + * Interpret a position value to human-readable text + */ + interpretValue(value) { + if (value > 0.5) { + return `Strong advantage for White (+${value.toFixed(3)})`; + } + else if (value > 0.1) { + return `Slight advantage for White (+${value.toFixed(3)})`; + } + else if (value > -0.1) { + return `Balanced position (${value.toFixed(3)})`; + } + else if (value > -0.5) { + return `Slight advantage for Black (${value.toFixed(3)})`; + } + else { + return `Strong advantage for Black (${value.toFixed(3)})`; + } + } + /** + * Evaluate all valid moves and return them sorted by value + * @param game - Current game state + * @returns Array of moves with their position values + */ + async evaluateMoves(game) { + if (!this.isInitialized()) { + throw new Error("Agent not initialized"); + } + const currentPlayer = this.stoneToPlayer(game.getCurrentPlayer()); + // Get all valid moves + const validMoves = game.validMovePositions().map((pos) => ({ + x: pos.x, + y: pos.y, + z: pos.z, + player: currentPlayer + })); + validMoves.push({ player: currentPlayer, isPass: true }); // Add pass move + if (validMoves.length === 0) { + return []; + } + console.log(`[TrigoEvaluationAgent] Evaluating ${validMoves.length} moves...`); + // Evaluate each move by simulating it and evaluating the resulting position + const valuedMoves = []; + for (const move of validMoves) { + // Clone game and apply move + const testGame = game.clone(); + let success; + if (move.isPass) { + success = testGame.pass(); + } + else if (move.x !== undefined && move.y !== undefined && move.z !== undefined) { + success = testGame.drop({ x: move.x, y: move.y, z: move.z }); + } + else { + continue; // Invalid move format + } + if (!success) { + continue; // Move failed + } + // Evaluate the resulting position + const evaluation = await this.evaluatePosition(testGame); + // Get move notation + const notation = move.isPass + ? "P" + : this.positionToTGN({ x: move.x, y: move.y, z: move.z }, testGame.getShape()); + // Model returns white-positive values (positive = white advantage) + // Adjust to current player perspective: positive = advantage for current player + const adjustedValue = currentPlayer === "white" ? evaluation.value : -evaluation.value; + valuedMoves.push({ + move, + value: adjustedValue, + notation + }); + } + // Sort by value (highest first - best for current player) + valuedMoves.sort((a, b) => b.value - a.value); + return valuedMoves; + } + /** + * Select the best move based on position evaluation + * @param game - Current game state + * @returns Best move or null if no moves available + */ + async selectBestMove(game) { + const valuedMoves = await this.evaluateMoves(game); + if (valuedMoves.length === 0) { + return null; + } + console.log(`[TrigoEvaluationAgent] Best move: ${valuedMoves[0].notation} (value: ${valuedMoves[0].value.toFixed(4)})`); + console.log(`[TrigoEvaluationAgent] Top 3 moves:`); + for (let i = 0; i < Math.min(3, valuedMoves.length); i++) { + console.log(` ${i + 1}. ${valuedMoves[i].notation}: ${valuedMoves[i].value.toFixed(4)}`); + } + return valuedMoves[0].move; + } + /** + * Get detailed evaluation report for current position + */ + async getEvaluationReport(game) { + const currentEval = await this.evaluatePosition(game); + const valuedMoves = await this.evaluateMoves(game); + return { + currentValue: currentEval, + topMoves: valuedMoves.slice(0, 5), // Top 5 moves + moveCount: valuedMoves.length + }; + } + /** + * Clean up resources + */ + destroy() { + // Agent doesn't own the inferencer, so just clear reference + console.log("[TrigoEvaluationAgent] Destroyed"); + } +} +exports.TrigoEvaluationAgent = TrigoEvaluationAgent; +//# sourceMappingURL=trigoEvaluationAgent.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoEvaluationAgent.js.map b/trigo-web/backend/dist/inc/trigoEvaluationAgent.js.map new file mode 100644 index 0000000000000000000000000000000000000000..ba2a4a4b37d25b27eb765a41df63eb20e71dd8ab --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoEvaluationAgent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoEvaluationAgent.js","sourceRoot":"","sources":["../../../inc/trigoEvaluationAgent.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts b/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f65543db0fe476d1ed091bddafa1ad8ca529c5 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts @@ -0,0 +1,80 @@ +/** + * Trigo Tree Agent - AI agent using tree attention for efficient move evaluation + * + * Uses evaluation mode ONNX model to score all valid moves in parallel. + * Organizes moves as a prefix tree where branches with same head token are merged. + */ +import { ModelInferencer } from "./modelInferencer"; +import { TrigoGame } from "./trigo/game"; +import type { Move } from "./trigo/types"; +export interface ScoredMove { + move: Move; + score: number; + notation: string; +} +export declare class TrigoTreeAgent { + private inferencer; + constructor(inferencer: ModelInferencer); + /** + * Convert Stone type to player string + */ + private stoneToPlayer; + /** + * Encode a position to TGN notation (3 characters for 5×5×5 board) + */ + private positionToTGN; + /** + * Convert string to byte tokens (ASCII encoding) + */ + private stringToTokens; + /** + * Build prefix tree from token arrays using recursive merging + * Merges branches with the same token at EVERY level + * + * Algorithm: + * 1. Group sequences by their first token + * 2. For each group: + * - Create one node for the shared first token + * - Extract remaining tokens (residues) + * - Recursively build subtree from residues + * 3. Combine all subtrees and build attention mask + * + * Example for ["aa", "ab", "ba", "bb"]: + * Level 1: Group by first token → 'a': ["a","b"], 'b': ["a","b"] + * Level 2: Within 'a' group, build subtree for ["a","b"] + * Within 'b' group, build subtree for ["a","b"] + * Result: Two branches, each with properly merged second-level nodes + * + * @param tokenArrays - Array of token arrays + * @returns Flattened token array (length m), mask matrix (m×m), and move-to-position mapping + */ + private buildPrefixTree; + /** + * Build tree structure for all valid moves + * Returns prefix tokens and tree structure for batch evaluation + */ + private buildMoveTree; + /** + * Get tree structure for visualization (public method) + */ + getTreeStructure(game: TrigoGame, moves: Move[]): { + evaluatedIds: number[]; + mask: number[]; + parent: Array; + moveData: Array<{ + move: Move; + notation: string; + leafPos: number; + }>; + }; + /** + * Select best move using tree attention + * Evaluates all valid moves in a single inference call + */ + selectBestMove(game: TrigoGame): Promise; + /** + * Score all moves using tree attention (batch evaluation) + */ + scoreMoves(game: TrigoGame, moves: Move[]): Promise; +} +//# sourceMappingURL=trigoTreeAgent.d.ts.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts.map b/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts.map new file mode 100644 index 0000000000000000000000000000000000000000..6fdfbc39a2a6c795c5e48326553bb01a94b051d6 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoTreeAgent.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoTreeAgent.d.ts","sourceRoot":"","sources":["../../../inc/trigoTreeAgent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAmB,MAAM,eAAe,CAAC;AAG3D,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,cAAc;IAC1B,OAAO,CAAC,UAAU,CAAkB;gBAExB,UAAU,EAAE,eAAe;IAIvC;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,eAAe;IA8FvB;;;OAGG;IACH,OAAO,CAAC,aAAa;IA0ErB;;OAEG;IACH,gBAAgB,CACf,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,IAAI,EAAE,GACX;QACF,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC7B,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,IAAI,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnE;IAID;;;OAGG;IACG,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAiC3D;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAuKvE"} \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoTreeAgent.js b/trigo-web/backend/dist/inc/trigoTreeAgent.js new file mode 100644 index 0000000000000000000000000000000000000000..c508a92f33be44398535c07ebc7a72af08c00c70 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoTreeAgent.js @@ -0,0 +1,382 @@ +"use strict"; +/** + * Trigo Tree Agent - AI agent using tree attention for efficient move evaluation + * + * Uses evaluation mode ONNX model to score all valid moves in parallel. + * Organizes moves as a prefix tree where branches with same head token are merged. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TrigoTreeAgent = void 0; +const game_1 = require("./trigo/game"); +const ab0yz_1 = require("./trigo/ab0yz"); +class TrigoTreeAgent { + constructor(inferencer) { + this.inferencer = inferencer; + } + /** + * Convert Stone type to player string + */ + stoneToPlayer(stone) { + if (stone === game_1.StoneType.BLACK) + return "black"; + if (stone === game_1.StoneType.WHITE) + return "white"; + throw new Error(`Invalid stone type: ${stone}`); + } + /** + * Encode a position to TGN notation (3 characters for 5×5×5 board) + */ + positionToTGN(pos, shape) { + const posArray = [pos.x, pos.y, pos.z]; + const shapeArray = [shape.x, shape.y, shape.z]; + return (0, ab0yz_1.encodeAb0yz)(posArray, shapeArray); + } + /** + * Convert string to byte tokens (ASCII encoding) + */ + stringToTokens(str) { + const tokens = []; + for (let i = 0; i < str.length; i++) { + tokens.push(str.charCodeAt(i)); + } + return tokens; + } + /** + * Build prefix tree from token arrays using recursive merging + * Merges branches with the same token at EVERY level + * + * Algorithm: + * 1. Group sequences by their first token + * 2. For each group: + * - Create one node for the shared first token + * - Extract remaining tokens (residues) + * - Recursively build subtree from residues + * 3. Combine all subtrees and build attention mask + * + * Example for ["aa", "ab", "ba", "bb"]: + * Level 1: Group by first token → 'a': ["a","b"], 'b': ["a","b"] + * Level 2: Within 'a' group, build subtree for ["a","b"] + * Within 'b' group, build subtree for ["a","b"] + * Result: Two branches, each with properly merged second-level nodes + * + * @param tokenArrays - Array of token arrays + * @returns Flattened token array (length m), mask matrix (m×m), and move-to-position mapping + */ + buildPrefixTree(tokenArrays) { + let nextPos = 0; + // --- Build prefix tree through recursive grouping --- + function build(seqs, parent) { + // group by token + const groups = new Map(); + for (const s of seqs) { + if (s.tokens.length === 0) + continue; + const t = s.tokens[0]; + if (!groups.has(t)) + groups.set(t, []); + groups.get(t).push(s); + } + const levelNodes = []; + for (const [token, group] of groups) { + const pos = nextPos++; + const node = { + token, + pos, + parent, + children: [], + moveEnds: [] + }; + // split residues + const ends = []; + const residues = []; + for (const g of group) { + if (g.tokens.length === 1) + ends.push(g.moveIndex); + else + residues.push({ moveIndex: g.moveIndex, tokens: g.tokens.slice(1) }); + } + node.moveEnds = ends; + // create sub nodes recursively + if (residues.length > 0) { + node.children = build(residues, pos); + } + levelNodes.push(node); + } + return levelNodes; + } + // Build roots + const seqs = tokenArrays.map((t, i) => ({ moveIndex: i, tokens: t })); + const roots = build(seqs, null); + const total = nextPos; + // --- Flatten tree --- + const evaluatedIds = new Array(total); + const parent = new Array(total).fill(null); + const moveToLeafPos = new Array(tokenArrays.length).fill(-1); + function dfs(n) { + evaluatedIds[n.pos] = n.token; + parent[n.pos] = n.parent; + for (const m of n.moveEnds) + moveToLeafPos[m] = n.pos; + for (const c of n.children) + dfs(c); + } + for (const r of roots) + dfs(r); + // --- Build ancestor mask --- + const mask = new Array(total * total).fill(0); + for (let i = 0; i < total; i++) { + let p = i; + while (p !== null) { + mask[i * total + p] = 1; + p = parent[p]; + } + } + return { evaluatedIds, mask, moveToLeafPos, parent }; + } + /** + * Build tree structure for all valid moves + * Returns prefix tokens and tree structure for batch evaluation + */ + buildMoveTree(game, moves) { + // Get current TGN as prefix + const currentTGN = game.toTGN().trim(); + // Build prefix (everything up to next move) + const lines = currentTGN.split("\n"); + const lastLine = lines[lines.length - 1]; + let prefix; + if (lastLine.match(/^\d+\./)) { + // Last line is a move number, include it + prefix = currentTGN + " "; + } + else if (lastLine.trim() === "") { + // Empty line, add move number + const moveMatches = currentTGN.match(/\d+\.\s/g); + const moveNumber = moveMatches ? moveMatches.length + 1 : 1; + const isBlackTurn = game.getCurrentPlayer() === game_1.StoneType.BLACK; + if (isBlackTurn) { + prefix = currentTGN + `${moveNumber}. `; + } + else { + prefix = currentTGN + " "; + } + } + else { + // Last line has moves, add space + prefix = currentTGN + " "; + } + const prefixTokens = this.stringToTokens(prefix); + // Encode each move to tokens (only first 2 tokens) + const shape = game.getShape(); + const movesWithTokens = moves.map((move) => { + let notation; + if (move.isPass) { + notation = "Pass"; + } + else if (move.x !== undefined && move.y !== undefined && move.z !== undefined) { + notation = this.positionToTGN({ x: move.x, y: move.y, z: move.z }, shape); + } + else { + throw new Error("Invalid move: missing coordinates"); + } + // Exclude the last token + const fullTokens = this.stringToTokens(notation); + const tokens = fullTokens.slice(0, fullTokens.length - 1); + return { move, notation, tokens }; + }); + // Build prefix tree + const tokenArrays = movesWithTokens.map((m) => m.tokens); + const { evaluatedIds, mask, moveToLeafPos, parent } = this.buildPrefixTree(tokenArrays); + // Build move data with leaf positions only + const moveData = movesWithTokens.map((m, index) => { + const leafPos = moveToLeafPos[index]; + return { + move: m.move, + notation: m.notation, + leafPos + }; + }); + return { prefixTokens, evaluatedIds, mask, parent, moveData }; + } + /** + * Get tree structure for visualization (public method) + */ + getTreeStructure(game, moves) { + return this.buildMoveTree(game, moves); + } + /** + * Select best move using tree attention + * Evaluates all valid moves in a single inference call + */ + async selectBestMove(game) { + if (!this.inferencer.isReady()) { + throw new Error("Inferencer not initialized"); + } + // Get current player as string + const currentPlayer = this.stoneToPlayer(game.getCurrentPlayer()); + // Get all valid moves + const validMoves = game.validMovePositions().map((pos) => ({ + x: pos.x, + y: pos.y, + z: pos.z, + player: currentPlayer + })); + validMoves.push({ player: currentPlayer, isPass: true }); // Add pass move + if (validMoves.length === 0) { + return null; + } + // Score all moves using tree attention + const scoredMoves = await this.scoreMoves(game, validMoves); + // Return move with highest score + if (scoredMoves.length === 0) { + return null; + } + scoredMoves.sort((a, b) => b.score - a.score); + return scoredMoves[0].move; + } + /** + * Score all moves using tree attention (batch evaluation) + */ + async scoreMoves(game, moves) { + if (moves.length === 0) { + return []; + } + // Build tree structure + const { prefixTokens, evaluatedIds, mask, parent, moveData } = this.buildMoveTree(game, moves); + // Validate parent array structure + for (let i = 0; i < parent.length; i++) { + const p = parent[i]; + if (p !== null && (p < 0 || p >= parent.length)) { + throw new Error(`Invalid parent array: parent[${i}] = ${p}, but array length is ${parent.length}`); + } + } + // Validate leafPos in moveData + for (const data of moveData) { + if (data.leafPos < 0 || data.leafPos >= parent.length) { + throw new Error(`Invalid leafPos: ${data.leafPos} for move ${data.notation}, parent array length: ${parent.length}`); + } + } + //console.debug(`Tree structure: ${evaluatedIds.length} nodes for ${moveData.length} moves`); + //console.debug(`Evaluated IDs:`, evaluatedIds.map((id) => String.fromCharCode(id)).join("")); + //console.debug( + // `Move positions:`, + // moveData.map((m) => `${m.notation}@${m.leafPos}`) + //); + // Prepare inputs for evaluation + const inputs = { + prefixIds: prefixTokens, + evaluatedIds: evaluatedIds, + evaluatedMask: mask + }; + // Run inference + const output = await this.inferencer.runEvaluationInference(inputs); + const { logits, numEvaluated } = output; + //console.debug(`Inference output: ${numEvaluated} evaluated positions`); + //process.stdout.write("."); + // Minimum probability threshold to avoid log(0) while preserving small probabilities + const MIN_PROB = 1e-10; // log(1e-10) ≈ -23 + // Score each move by accumulating log probabilities along the path + // For each move, build the path from root to leaf using parent array + const scoredMoves = []; + // Cache softmax results for each output position to avoid recomputation + const softmaxCache = new Map(); + const getSoftmax = (outputPos) => { + if (!softmaxCache.has(outputPos)) { + softmaxCache.set(outputPos, this.inferencer.softmax(logits, outputPos)); + } + return softmaxCache.get(outputPos); + }; + for (const data of moveData) { + let logProb = 0; + // Build path from leaf to root using parent array, then reverse + const pathReverse = []; + let pos = data.leafPos; + const visited = new Set(); + // Safety checks: prevent infinite loops and invalid indices + while (pos !== null && pos !== undefined) { + // Check for cycles + if (visited.has(pos)) { + console.error(`Cycle detected in parent array at position ${pos}`); + break; + } + // Check for valid index + if (pos < 0 || pos >= parent.length) { + console.error(`Invalid position ${pos}, parent array length: ${parent.length}`); + break; + } + visited.add(pos); + pathReverse.push(pos); + pos = parent[pos]; + // Safety limit to prevent runaway loops + if (pathReverse.length > 10000) { + console.error(`Path too long (>10000), possible infinite loop. leafPos: ${data.leafPos}`); + break; + } + } + // Reverse to get root→leaf path (indices in evaluatedIds array) + const path = pathReverse.reverse(); + // Now accumulate log probabilities for each transition in path + // TreeLM returns logits[0..m] where: + // logits[0] = output at prefix last position (n-1) → predicts evaluatedIds[0] + // logits[i] = output at position (n-1+i) → predicts evaluatedIds[i] + // + // For a parent→child transition: + // Parent: evaluatedIds[parentIdx] at input position (n+parentIdx) + // Parent output: at position (n+parentIdx), which is logits[parentIdx+1] + // Child token: evaluatedIds[childIdx] + // Probability: softmax(logits[parentIdx+1])[evaluatedIds[childIdx]] + // Special case: root token (predicted from prefix last position) + if (path.length > 0) { + const rootPos = path[0]; + const rootToken = evaluatedIds[rootPos]; + // Root is predicted by prefix last position output (logits[0]) + const probs = getSoftmax(0); + const prob = Math.max(probs[rootToken], MIN_PROB); // Clip to minimum + logProb += Math.log(prob); + } + // Subsequent transitions: parent→child in tree + for (let i = 1; i < path.length; i++) { + const parentPos = path[i - 1]; // evaluatedIds index + const childPos = path[i]; // evaluatedIds index + const childToken = evaluatedIds[childPos]; + // Parent output is at logits[parentPos+1] + const logitsIndex = parentPos + 1; + // Check bounds: logitsIndex must be <= numEvaluated + // (logits has length numEvaluated+1, indices 0 to numEvaluated) + if (logitsIndex <= numEvaluated) { + const probs = getSoftmax(logitsIndex); + const prob = Math.max(probs[childToken], MIN_PROB); // Clip to minimum + logProb += Math.log(prob); + } + else { + // Parent position out of bounds + logProb += Math.log(MIN_PROB); + } + } + // CRITICAL: Add probability for the LAST token (excluded from tree) + // The last character of the move notation was excluded from evaluatedIds + // We need to predict it using the leaf node's output + if (path.length > 0) { + const leafPos = path[path.length - 1]; // Last position in path + const lastToken = this.stringToTokens(data.notation).pop(); // Last char of notation + // Leaf output is at logits[leafPos+1] + const logitsIndex = leafPos + 1; + if (logitsIndex <= numEvaluated) { + const probs = getSoftmax(logitsIndex); + const prob = Math.max(probs[lastToken], MIN_PROB); // Clip to minimum + logProb += Math.log(prob); + } + else { + logProb += Math.log(MIN_PROB); + } + } + scoredMoves.push({ + move: data.move, + score: logProb, + notation: data.notation + }); + } + return scoredMoves; + } +} +exports.TrigoTreeAgent = TrigoTreeAgent; +//# sourceMappingURL=trigoTreeAgent.js.map \ No newline at end of file diff --git a/trigo-web/backend/dist/inc/trigoTreeAgent.js.map b/trigo-web/backend/dist/inc/trigoTreeAgent.js.map new file mode 100644 index 0000000000000000000000000000000000000000..3abd9ee646b440eb0720a733f6d613b75473c619 --- /dev/null +++ b/trigo-web/backend/dist/inc/trigoTreeAgent.js.map @@ -0,0 +1 @@ +{"version":3,"file":"trigoTreeAgent.js","sourceRoot":"","sources":["../../../inc/trigoTreeAgent.ts"],"names":[],"mappings":"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"} \ No newline at end of file