trigo / trigo-web /app /src /utils /TrigoGameFrontend.ts
k-l-lambda's picture
updated
502af73
/**
* TrigoGameFrontend - Frontend wrapper for TrigoGame
*
* Provides convenient string-based interfaces for frontend use
* Wraps TrigoGame's number-based types with string types
*/
import {
TrigoGame,
type BoardShape,
type Move,
type Player,
type TerritoryResult,
stoneToPlayer,
stepsToMoves,
makePosition,
type GameStatus,
type GameResult
} from "../../../inc/trigo";
/**
* TrigoGameFrontend - Extended TrigoGame with frontend-friendly interfaces
*/
export class TrigoGameFrontend extends TrigoGame {
/**
* Make a move with coordinates (convenience method)
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @returns true if move was successful
*/
makeMove(x: number, y: number, z: number): boolean {
return this.drop(makePosition(x, y, z));
}
/**
* Get current player as string
*
* @returns "black" | "white"
*/
getCurrentPlayerString(): Player {
return stoneToPlayer(this.getCurrentPlayer());
}
/**
* Get move history in frontend format
*
* @returns Array of Move objects
*/
getMoveHistory(): Move[] {
return stepsToMoves(this.getHistory());
}
/**
* Get stone at position, returns number format for frontend
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @returns 0 = Empty, 1 = Black, 2 = White
*/
getStoneAt(x: number, y: number, z: number): number {
return this.getStone(makePosition(x, y, z)) as number;
}
/**
* Check if position is valid
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @returns true if position is on the board
*/
isValidPosition(x: number, y: number, z: number): boolean {
const shape = this.getShape();
return x >= 0 && x < shape.x && y >= 0 && y < shape.y && z >= 0 && z < shape.z;
}
/**
* Check if position is empty
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @returns true if position is empty
*/
isEmpty(x: number, y: number, z: number): boolean {
if (!this.isValidPosition(x, y, z)) {
return false;
}
return this.getStoneAt(x, y, z) === 0;
}
/**
* Check if a move is valid at position
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @returns Object with valid flag and optional reason
*/
isValidMoveAt(x: number, y: number, z: number): { valid: boolean; reason?: string } {
return this.isValidMove(makePosition(x, y, z));
}
/**
* Get opponent player
*
* @returns Opponent player color
*/
getOpponentPlayer(): Player {
const current = this.getCurrentPlayerString();
return current === "black" ? "white" : "black";
}
/**
* Check if undo is available
*
* @returns true if can undo
*/
canUndo(): boolean {
return this.getCurrentStep() > 0;
}
/**
* Undo move (convenience wrapper)
*
* @returns true if undo was successful
*/
undoMove(): boolean {
return this.undo();
}
/**
* Redo move (convenience wrapper)
*
* @returns true if redo was successful
*/
redoMove(): boolean {
return this.redo();
}
/**
* Jump to specific move in history
*
* @param index Move index (-1 for initial state)
* @returns true if jump was successful
*/
jumpToMove(index: number): boolean {
return this.jumpToStep(index);
}
/**
* Get total move count
*
* @returns Number of moves played
*/
getMoveCount(): number {
return this.getCurrentStep();
}
/**
* Get current move index
*
* @returns Current step index
*/
getCurrentMoveIndex(): number {
return this.getCurrentStep();
}
/**
* Get board shape
*
* @returns Board dimensions
*/
getBoardShape(): BoardShape {
return this.getShape();
}
/**
* Initialize game with board shape
*
* @param shape Board dimensions
*/
initializeGame(shape?: BoardShape): void {
if (shape) {
// Would need to recreate the game instance with new shape
// For now, just reset
this.reset();
} else {
this.reset();
}
}
/**
* Compute territory (convenience wrapper)
*
* @returns Territory calculation result
*/
computeTerritory(): TerritoryResult {
return this.getTerritory();
}
/**
* Get game status
*
* @returns Game status
*/
getStatus(): GameStatus {
return this.getGameStatus();
}
/**
* Get game result
*
* @returns Game result if available
*/
getResult(): GameResult | undefined {
return this.getGameResult();
}
/**
* Get consecutive pass count
*
* @returns Number of consecutive passes
*/
getConsecutivePassCount(): number {
return this.getPassCount();
}
}