@ayshrj/ludo.js
Version:
A TypeScript-based headless Ludo game engine for simulating game logic, AI moves, and game state management.
138 lines (134 loc) • 4.52 kB
TypeScript
import { EventEmitter } from 'events';
/**
* The player colors we can have in Ludo.
*/
type Color = "red" | "green" | "yellow" | "blue";
/**
* Represents a single cell on the 15x15 board.
*/
interface Block {
redTrack?: number;
greenTrack?: number;
blueTrack?: number;
yellowTrack?: number;
isSafeZone?: boolean;
isStartingPosition?: Color;
isHome?: Color;
isOnPathToFinalPosition?: Color;
isFinalPosition?: Color;
}
/**
* Stores positions of the 4 tokens for each color (0..56, or -1 if in "home")
*/
type TokenPositions = {
[key in Color]: [number, number, number, number];
};
/**
* The possible game states:
*/
type GameState = "playerHasToRollADice" | "playerHasToSelectAPosition" | "gameFinished";
/**
* A snapshot of the game's state, emitted whenever changes occur.
*/
interface LudoGameState {
turn: Color;
tokenPositions: TokenPositions;
ranking: Color[];
boardStatus: string;
diceRoll: number | null;
lastDiceRoll: number | null;
gameState: GameState;
players: Color[];
}
/**
* Generate initial position of the tokens
*/
declare function initializeTokenPosition(): TokenPositions;
/**
* The Ludo class extends EventEmitter so you can listen to "stateChange" events.
*/
declare class Ludo extends EventEmitter {
private numberOfPlayers;
/** The 15x15 board, with `Block` or `null` if not used. */
board: (Block | null)[][];
/** The positions of all tokens for each color. */
tokenPositions: TokenPositions;
/** The color currently taking its turn. */
currentPiece: Color;
/** Which colors have completely finished (all tokens at final), in order. */
ranking: Color[];
/** The current dice roll value, or null if not rolled yet. */
currentDiceRoll: number | null;
/** The previous dice roll value (for reference in UI, etc.). */
lastDiceRoll: number | null;
/** Token indices (0..3) that are valid to move with the current dice roll. */
validTokenIndices: number[];
/** Number of consecutive sixes rolled by the current player. */
currentConsecutiveSixes: number;
/** Track length from index 0 to 56. */
readonly TRACK_LENGTH = 57;
/** Indices on the track considered "safe" (cannot be captured). */
readonly safeZones: number[];
/** A status message about the current board state (e.g. "Blue captured a token"). */
currentBoardStatus: string;
/** The overall game state. */
gameState: GameState;
/** Color-specific paths for each player's tokens ([row, col] coordinates). */
colorPaths: Record<Color, [number, number][]>;
/** The active player colors in this game (e.g. ["blue","red","green"]). */
players: Color[];
/**
* Create a new Ludo game with the specified number of players (2..4).
* Emits a "stateChange" event whenever the internal state changes.
*/
constructor(numberOfPlayers?: 2 | 3 | 4);
/**
* Emit the current state to all listeners of "stateChange".
*/
private emitStateChange;
/**
* Reset the entire board, token positions, ranking, etc.
* Randomly selects which color starts.
*/
reset(): void;
/**
* Rotate (r,c) by 90/180/270 around center (7,7).
*/
private rotateCoord;
/**
* Roll the dice for the current player, if allowed.
* Automatically checks for consecutive sixes & skip turn if needed.
*/
rollDiceForCurrentPiece(): number;
/**
* The user/bot picks which token to move (0..3), if valid.
*/
selectToken(tokenIndex: number): void;
/**
* Return valid token indices for a given dice roll.
*/
private getValidMoves;
/**
* Check if any opponent is on newPos. If so, capture them (send home).
* Returns number of captures.
*/
private handleCollisions;
/**
* Proceed to the next player's turn, or end the game if all finished.
*/
private nextTurn;
/**
* Reset the current dice roll & valid token indices. Optionally clear lastDiceRoll.
*/
private resetTurnState;
/**
* Returns a snapshot of the current state, used by emitStateChange() or for UI.
*/
getCurrentState(): LudoGameState;
/**
* A basic AI heuristic for picking the best token to move given currentDiceRoll.
* Returns -1 if no moves.
*/
bestMove(): number;
}
export { type Block, type Color, type GameState, Ludo, type LudoGameState, type TokenPositions, initializeTokenPosition };