organized types
This commit is contained in:
+36
-7
@@ -59,18 +59,22 @@ return {
|
|||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── index.ts # Main package exports
|
├── index.ts # Main package exports
|
||||||
├── types.ts # All shared TypeScript types
|
├── types.ts # Re-exports all types from modules, useGame-specific types
|
||||||
├── useGame.ts # Main orchestrator hook
|
├── useGame.ts # Main orchestrator hook
|
||||||
├── useGameStatus/
|
├── useGameStatus/
|
||||||
|
│ ├── index.ts # Public exports
|
||||||
|
│ ├── types.ts # GameStatus, GameStatusManager
|
||||||
│ └── useGameStatus.ts # Game state management
|
│ └── useGameStatus.ts # Game state management
|
||||||
├── useBoard/
|
├── useBoard/
|
||||||
│ ├── index.ts # Public exports
|
│ ├── index.ts # Public exports
|
||||||
|
│ ├── types.ts # Coord, MazeCell, MazeData, BoardManager, MazeNavigator
|
||||||
│ ├── useBoard.ts # Board/maze management hook
|
│ ├── useBoard.ts # Board/maze management hook
|
||||||
│ ├── MazeGenerator.ts # Maze generation algorithm
|
│ ├── MazeGenerator.ts # Maze generation algorithm
|
||||||
│ ├── MazeRenderer.ts # DOM rendering for maze
|
│ ├── MazeRenderer.ts # DOM rendering for maze
|
||||||
│ └── useMazeNavigation.ts # Pathfinding and validation
|
│ └── useMazeNavigation.ts # Pathfinding and validation
|
||||||
├── useCursor/
|
├── useCursor/
|
||||||
│ ├── index.ts # Public exports
|
│ ├── index.ts # Public exports
|
||||||
|
│ ├── types.ts # CursorMode, CursorManager, HeroManager, Motion, AnimationSystem, VimMotionSystem
|
||||||
│ ├── useCursor.ts # Main cursor/input hook
|
│ ├── useCursor.ts # Main cursor/input hook
|
||||||
│ ├── useHero.ts # Player position and movement
|
│ ├── useHero.ts # Player position and movement
|
||||||
│ ├── useHeroRender.ts # Hero rendering on DOM
|
│ ├── useHeroRender.ts # Hero rendering on DOM
|
||||||
@@ -79,6 +83,7 @@ src/
|
|||||||
│ └── useAnimation.ts # Multi-step movement animation
|
│ └── useAnimation.ts # Multi-step movement animation
|
||||||
└── useScore/
|
└── useScore/
|
||||||
├── index.ts # Public exports
|
├── index.ts # Public exports
|
||||||
|
├── types.ts # TimerManager, ScorePathsResult, ScoreManager
|
||||||
├── useScore.ts # Main scoring hook
|
├── useScore.ts # Main scoring hook
|
||||||
├── useScorePaths.ts # Distance calculations
|
├── useScorePaths.ts # Distance calculations
|
||||||
├── useScoreTime.ts # Timer integration
|
├── useScoreTime.ts # Timer integration
|
||||||
@@ -89,7 +94,15 @@ src/
|
|||||||
|
|
||||||
## Type System
|
## Type System
|
||||||
|
|
||||||
All types are centralized in `src/types.ts` for consistency and maintainability.
|
Types are organized by module for clarity and maintainability:
|
||||||
|
|
||||||
|
- **`src/useBoard/types.ts`**: Board, maze, and navigation types
|
||||||
|
- **`src/useCursor/types.ts`**: Cursor, hero, vim motions, and animation types
|
||||||
|
- **`src/useGameStatus/types.ts`**: Game status and lifecycle types
|
||||||
|
- **`src/useScore/types.ts`**: Scoring and timer types
|
||||||
|
- **`src/types.ts`**: Re-exports all module types + useGame-specific types (GameOptions, GameKeyManager, GameManager)
|
||||||
|
|
||||||
|
This modular organization keeps types colocated with their related hooks while maintaining a unified `src/types.ts` entry point for convenience.
|
||||||
|
|
||||||
### Main Types
|
### Main Types
|
||||||
|
|
||||||
@@ -938,13 +951,28 @@ Rendering updates via refs
|
|||||||
|
|
||||||
### Hook Return Types
|
### Hook Return Types
|
||||||
|
|
||||||
All hook return types are explicitly defined in `src/types.ts`. Import them directly:
|
All hook return types are explicitly defined and organized by module:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
// Import from main types.ts (re-exports all modules)
|
||||||
import type { GameManager, CursorManager, ScoreManager } from './types';
|
import type { GameManager, CursorManager, ScoreManager } from './types';
|
||||||
import type { TimerManager, HeroRenderManager, AnimationSystem } from './types';
|
import type { TimerManager, HeroRenderManager, AnimationSystem } from './types';
|
||||||
|
import type { BoardManager, Coord } from './types';
|
||||||
|
import type { GameStatus, GameStatusManager } from './types';
|
||||||
|
|
||||||
|
// Or import directly from module types for clarity
|
||||||
|
import type { CursorManager } from './useCursor/types';
|
||||||
|
import type { BoardManager } from './useBoard/types';
|
||||||
|
import type { ScoreManager } from './useScore/types';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Type Organization
|
||||||
|
|
||||||
|
- **Module-local types**: Defined in each hook's `types.ts` file
|
||||||
|
- **Cross-module types**: Imported as needed within modules
|
||||||
|
- **Public API types**: Re-exported through `src/types.ts`
|
||||||
|
- **useGame-specific types**: Defined in main `src/types.ts` (GameOptions, GameKeyManager, GameManager)
|
||||||
|
|
||||||
### Type Imports
|
### Type Imports
|
||||||
|
|
||||||
Always import types with `import type`:
|
Always import types with `import type`:
|
||||||
@@ -979,9 +1007,10 @@ const same = pos1.row === pos2.row && pos1.col === pos2.col;
|
|||||||
The vim-maze unified API provides a composable, type-safe game engine:
|
The vim-maze unified API provides a composable, type-safe game engine:
|
||||||
|
|
||||||
- **Single Entry Point**: `useGame()` for all initialization
|
- **Single Entry Point**: `useGame()` for all initialization
|
||||||
- **Modular Design**: Independent, reusable hooks
|
- **Modular Design**: Independent, reusable hooks with colocated types
|
||||||
- **Type Safe**: Comprehensive TypeScript support
|
- **Type Safe**: Comprehensive TypeScript support with explicit type definitions
|
||||||
|
- **Organized Types**: Types organized by module with main `types.ts` re-exporting all
|
||||||
- **Extensible**: Platform hook system for customization
|
- **Extensible**: Platform hook system for customization
|
||||||
- **Well Structured**: Clear separation of concerns
|
- **Well Structured**: Clear separation of concerns with intuitive file structure
|
||||||
|
|
||||||
For detailed implementation, refer to source files in `src/`.
|
For detailed implementation, refer to source files in `src/`. Each module's `types.ts` provides the interface definitions for that domain.
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { useGame } from "../../src/useGame";
|
import { useGame } from "../../src/useGame";
|
||||||
import { useKeyBindings } from "./useKeyBindings";
|
import { useKeyBindings } from "./useKeyBindings";
|
||||||
import { useMounted } from "./useMounted";
|
|
||||||
import { useIsMobile } from "./useIsMobile";
|
import { useIsMobile } from "./useIsMobile";
|
||||||
import '../../src/game.css';
|
import '../../src/game.css';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const mounted = useMounted();
|
|
||||||
const cols = isMobile ? 12 : 32;
|
const cols = isMobile ? 12 : 32;
|
||||||
const rows = isMobile ? 8 : 24;
|
const rows = isMobile ? 8 : 24;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import { useState, useEffect } from 'react';
|
|
||||||
|
|
||||||
export const useMounted = () => {
|
|
||||||
const [mounted, setMounted] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setMounted(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return mounted;
|
|
||||||
};
|
|
||||||
+15
-161
@@ -1,48 +1,12 @@
|
|||||||
import type { RefObject } from 'react';
|
import type { RefObject } from 'react';
|
||||||
import { MazeRenderer, MazeGenerator } from "./useBoard";
|
import type { CursorManager, HeroManager, HeroRenderManager } from './useCursor/types';
|
||||||
export * from './useGame';
|
import type { GameStatusManager } from './useGameStatus/types';
|
||||||
export * from './useBoard';
|
import type { ScoreManager } from './useScore/types';
|
||||||
export * from './useCursor';
|
|
||||||
export * from './useScore';
|
|
||||||
|
|
||||||
export type GameStatus = 'waiting' | 'started' | 'has-key' | 'paused' | 'game-over' | 'game-won'
|
|
||||||
|
|
||||||
export type GameManager = {
|
|
||||||
containerRef: RefObject<HTMLDivElement | null>;
|
|
||||||
renderBoard: () => void;
|
|
||||||
cursor: CursorManager;
|
|
||||||
hero: HeroManager;
|
|
||||||
renderer: HeroRenderer;
|
|
||||||
scoreManager: ScoreManager;
|
|
||||||
} & GameStatusManager & GameKeyManager;
|
|
||||||
|
|
||||||
|
|
||||||
export type BoardManager = {
|
|
||||||
containerRef: RefObject<HTMLDivElement | null>
|
|
||||||
mazeRef: RefObject<MazeCell[][]>
|
|
||||||
mazeInstanceRef: RefObject<MazeGenerator | null>
|
|
||||||
rendererRef: RefObject<MazeRenderer | null>
|
|
||||||
renderBoard: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export type PositionTag = "entrance" | "exit" | "key" | "hero";
|
|
||||||
|
|
||||||
export type Coord = { row: number, col: number };
|
|
||||||
|
|
||||||
export type CellTag = "wall" | "door" | PositionTag;
|
|
||||||
|
|
||||||
export type MazeCell = CellTag[];
|
|
||||||
|
|
||||||
export type MazeData = {
|
|
||||||
maze: MazeCell[][];
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
cols: number;
|
|
||||||
rows: number;
|
|
||||||
totalSteps: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export * from './useBoard/types';
|
||||||
|
export * from './useCursor/types';
|
||||||
|
export * from './useGameStatus/types';
|
||||||
|
export * from './useScore/types';
|
||||||
|
|
||||||
export type GameOptions = {
|
export type GameOptions = {
|
||||||
rows: number;
|
rows: number;
|
||||||
@@ -57,121 +21,11 @@ export type GameKeyManager = {
|
|||||||
getKeyLog: () => KeyLogEntry[];
|
getKeyLog: () => KeyLogEntry[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GameStatusManager = {
|
export type GameManager = {
|
||||||
gameStatus: GameStatus;
|
containerRef: RefObject<HTMLDivElement | null>;
|
||||||
setGameStatus: (status: GameStatus) => void;
|
renderBoard: () => void;
|
||||||
startGame: () => void;
|
cursor: CursorManager;
|
||||||
togglePause: (pause?: boolean) => void;
|
hero: HeroManager;
|
||||||
quitGame: () => void;
|
renderer: HeroRenderManager;
|
||||||
};
|
scoreManager: ScoreManager;
|
||||||
|
} & GameStatusManager & GameKeyManager;
|
||||||
//Cursor Stuff
|
|
||||||
export type CursorMode = 'normal' | 'insert' | 'replace' | 'visual' | 'visual-line';
|
|
||||||
|
|
||||||
export type UseHeroType = {
|
|
||||||
position: Coord | null;
|
|
||||||
canMoveTo: (coord: Coord) => boolean;
|
|
||||||
moveTo: (coord: Coord) => void;
|
|
||||||
pickupKey: () => void;
|
|
||||||
reachExit: () => void;
|
|
||||||
reset: () => void;
|
|
||||||
heroPos: Coord | null;
|
|
||||||
setHeroPos: (pos: Coord | null) => void;
|
|
||||||
moveHero: (dr: number, dc: number, steps: number, gameStatus: GameStatus, setGameStatus: (s: GameStatus) => void) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CursorManager = {
|
|
||||||
position: () => Coord;
|
|
||||||
mode: () => CursorMode;
|
|
||||||
move: (dCols: number, dRows: number, count: number) => void;
|
|
||||||
moveLeft: (count?: number) => void;
|
|
||||||
moveRight: (count?: number) => void;
|
|
||||||
moveUp: (count?: number) => void;
|
|
||||||
moveDown: (count?: number) => void;
|
|
||||||
moveToStart: () => void;
|
|
||||||
moveToEnd: () => void;
|
|
||||||
moveToTop: () => void;
|
|
||||||
moveToBottom: () => void;
|
|
||||||
repeatLastMotion: () => void;
|
|
||||||
resetCount: () => void;
|
|
||||||
getCount: () => string;
|
|
||||||
hasCount: () => boolean;
|
|
||||||
setCount: (digit: string) => void;
|
|
||||||
setLastKey: (key: string) => void;
|
|
||||||
getLastKey: () => string;
|
|
||||||
hero?: UseHeroType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HeroManager = {
|
|
||||||
position: Coord | null;
|
|
||||||
canMoveTo: (coord: Coord) => boolean;
|
|
||||||
moveTo: (coord: Coord) => void;
|
|
||||||
pickupKey: () => void;
|
|
||||||
reachExit: () => void;
|
|
||||||
reset: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type HeroRenderer = {
|
|
||||||
render: () => void;
|
|
||||||
updatePosition: (coord: Coord) => void;
|
|
||||||
showCoordinates: (show: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy type for backward compatibility
|
|
||||||
export type Cursor = CursorManager;
|
|
||||||
|
|
||||||
export type Motion = { dr: number; dc: number; steps: number };
|
|
||||||
|
|
||||||
export type VimMotionSystem = {
|
|
||||||
processKey: (key: string) => { type: 'move'|'anchor'|'repeat'|'count', data: any } | null;
|
|
||||||
resetCount: () => void;
|
|
||||||
getCount: () => number;
|
|
||||||
hasCount: () => boolean;
|
|
||||||
setLastMotion: (motion: Motion) => void;
|
|
||||||
repeatLastMotion: () => Motion | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AnimationSystem = {
|
|
||||||
animateMovement: (from: Coord, to: Coord, steps: number, onStep: (coord: Coord) => void, onComplete: () => void) => void;
|
|
||||||
cancelAnimation: () => void;
|
|
||||||
isAnimating: () => boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MazeNavigator = {
|
|
||||||
isValidMove: (from: Coord, to: Coord) => boolean;
|
|
||||||
findAnchorTarget: (from: Coord, direction: 'left'|'right'|'top'|'bottom') => Coord | null;
|
|
||||||
validatePath: (from: Coord, direction: Coord, steps: number) => boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type HeroRenderManager = {
|
|
||||||
render: () => void;
|
|
||||||
updatePosition: (coord: Coord) => void;
|
|
||||||
showCoordinates: (show: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TimerManager = {
|
|
||||||
timeValue: number;
|
|
||||||
startTimer: () => void;
|
|
||||||
stopTimer: () => void;
|
|
||||||
resetTimer: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ScorePathsResult = {
|
|
||||||
entranceToKey: number;
|
|
||||||
entranceToExit: number;
|
|
||||||
heroToKey: number;
|
|
||||||
heroToExit: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ScoreManager = {
|
|
||||||
timeValue: number;
|
|
||||||
startTimer: () => void;
|
|
||||||
stopTimer: () => void;
|
|
||||||
resetTimer: () => void;
|
|
||||||
distToKey: number;
|
|
||||||
distToExit: number;
|
|
||||||
keystrokes: number;
|
|
||||||
optimalSteps: number;
|
|
||||||
efficiency: number;
|
|
||||||
finalScore: number | null;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { PositionTag, Coord, CellTag, MazeCell, MazeData } from "../types";
|
import type { PositionTag, Coord, CellTag, MazeCell, MazeData } from "./types";
|
||||||
|
|
||||||
export class MazeGenerator {
|
export class MazeGenerator {
|
||||||
width: number;
|
width: number;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { MazeData } from "../types";
|
import type { MazeData } from "./types";
|
||||||
|
|
||||||
export class MazeRenderer {
|
export class MazeRenderer {
|
||||||
private mazeData: MazeData;
|
private mazeData: MazeData;
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ export * from './useBoard';
|
|||||||
export * from './MazeGenerator';
|
export * from './MazeGenerator';
|
||||||
export * from './MazeRenderer';
|
export * from './MazeRenderer';
|
||||||
export * from './useMazeNavigation';
|
export * from './useMazeNavigation';
|
||||||
|
export * from './types';
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import type { RefObject } from 'react';
|
||||||
|
|
||||||
|
export type PositionTag = "entrance" | "exit" | "key" | "hero";
|
||||||
|
|
||||||
|
export type Coord = { row: number; col: number };
|
||||||
|
|
||||||
|
export type CellTag = "wall" | "door" | PositionTag;
|
||||||
|
|
||||||
|
export type MazeCell = CellTag[];
|
||||||
|
|
||||||
|
export type MazeData = {
|
||||||
|
maze: MazeCell[][];
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
cols: number;
|
||||||
|
rows: number;
|
||||||
|
totalSteps: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BoardManager = {
|
||||||
|
containerRef: RefObject<HTMLDivElement | null>;
|
||||||
|
mazeRef: RefObject<MazeCell[][]>;
|
||||||
|
mazeInstanceRef: RefObject<any>;
|
||||||
|
rendererRef: RefObject<any>;
|
||||||
|
renderBoard: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MazeNavigator = {
|
||||||
|
isValidMove: (from: Coord, to: Coord) => boolean;
|
||||||
|
findAnchorTarget: (from: Coord, direction: 'left' | 'right' | 'top' | 'bottom') => Coord | null;
|
||||||
|
validatePath: (from: Coord, direction: Coord, steps: number) => boolean;
|
||||||
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { MazeGenerator } from "./MazeGenerator";
|
import { MazeGenerator } from "./MazeGenerator";
|
||||||
import { MazeRenderer } from "./MazeRenderer";
|
import { MazeRenderer } from "./MazeRenderer";
|
||||||
import type { MazeCell } from "../types";
|
import type { MazeCell } from "./types";
|
||||||
|
|
||||||
export function useBoard(cols: number, rows: number) {
|
export function useBoard(cols: number, rows: number) {
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Coord, MazeCell, MazeNavigator } from '../types';
|
import type { Coord, MazeCell, MazeNavigator } from './types';
|
||||||
|
|
||||||
export type { MazeNavigator } from '../types';
|
export type { MazeNavigator } from './types';
|
||||||
|
|
||||||
export function useMazeNavigation(maze: MazeCell[][]): MazeNavigator {
|
export function useMazeNavigation(maze: MazeCell[][]): MazeNavigator {
|
||||||
function isValidMove(_from: Coord, to: Coord): boolean {
|
function isValidMove(_from: Coord, to: Coord): boolean {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './types';
|
||||||
export * from './useCursor';
|
export * from './useCursor';
|
||||||
export * from './useHero';
|
export * from './useHero';
|
||||||
export * from './useHeroRender';
|
export * from './useHeroRender';
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import type { Coord } from '../useBoard/types';
|
||||||
|
import type { GameStatus } from '../useGameStatus/types';
|
||||||
|
|
||||||
|
export type { Coord } from '../useBoard/types';
|
||||||
|
|
||||||
|
export type CursorMode = 'normal' | 'insert' | 'replace' | 'visual' | 'visual-line';
|
||||||
|
|
||||||
|
export type Motion = { dr: number; dc: number; steps: number };
|
||||||
|
|
||||||
|
export type VimMotionSystem = {
|
||||||
|
processKey: (key: string) => { type: 'move' | 'anchor' | 'repeat' | 'count'; data: any } | null;
|
||||||
|
resetCount: () => void;
|
||||||
|
getCount: () => number;
|
||||||
|
hasCount: () => boolean;
|
||||||
|
setLastMotion: (motion: Motion) => void;
|
||||||
|
repeatLastMotion: () => Motion | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AnimationSystem = {
|
||||||
|
animateMovement: (from: Coord, to: Coord, steps: number, onStep: (coord: Coord) => void, onComplete: () => void) => void;
|
||||||
|
cancelAnimation: () => void;
|
||||||
|
isAnimating: () => boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UseHeroType = {
|
||||||
|
position: Coord | null;
|
||||||
|
canMoveTo: (coord: Coord) => boolean;
|
||||||
|
moveTo: (coord: Coord) => void;
|
||||||
|
pickupKey: () => void;
|
||||||
|
reachExit: () => void;
|
||||||
|
reset: () => void;
|
||||||
|
heroPos: Coord | null;
|
||||||
|
setHeroPos: (pos: Coord | null) => void;
|
||||||
|
moveHero: (dr: number, dc: number, steps: number, gameStatus: GameStatus, setGameStatus: (s: GameStatus) => void) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CursorManager = {
|
||||||
|
position: () => Coord;
|
||||||
|
mode: () => CursorMode;
|
||||||
|
move: (dCols: number, dRows: number, count: number) => void;
|
||||||
|
moveLeft: (count?: number) => void;
|
||||||
|
moveRight: (count?: number) => void;
|
||||||
|
moveUp: (count?: number) => void;
|
||||||
|
moveDown: (count?: number) => void;
|
||||||
|
moveToStart: () => void;
|
||||||
|
moveToEnd: () => void;
|
||||||
|
moveToTop: () => void;
|
||||||
|
moveToBottom: () => void;
|
||||||
|
repeatLastMotion: () => void;
|
||||||
|
resetCount: () => void;
|
||||||
|
getCount: () => string;
|
||||||
|
hasCount: () => boolean;
|
||||||
|
setCount: (digit: string) => void;
|
||||||
|
setLastKey: (key: string) => void;
|
||||||
|
getLastKey: () => string;
|
||||||
|
hero?: UseHeroType;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type HeroManager = {
|
||||||
|
position: Coord | null;
|
||||||
|
canMoveTo: (coord: Coord) => boolean;
|
||||||
|
moveTo: (coord: Coord) => void;
|
||||||
|
pickupKey: () => void;
|
||||||
|
reachExit: () => void;
|
||||||
|
reset: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type HeroRenderManager = {
|
||||||
|
render: () => void;
|
||||||
|
updatePosition: (coord: Coord) => void;
|
||||||
|
showCoordinates: (show: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Cursor = CursorManager;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import type { Coord, AnimationSystem } from '../types';
|
import type { Coord, AnimationSystem } from './types';
|
||||||
|
|
||||||
export type { AnimationSystem } from '../types';
|
export type { AnimationSystem } from './types';
|
||||||
|
|
||||||
export function useAnimation(): AnimationSystem {
|
export function useAnimation(): AnimationSystem {
|
||||||
const animatingRef = useRef(false);
|
const animatingRef = useRef(false);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { useRef, useEffect } from 'react'
|
import { useRef, useEffect } from 'react'
|
||||||
import type { CursorMode, Coord, BoardManager, GameStatusManager } from '../types'
|
import type { CursorMode, Coord } from './types';
|
||||||
|
import type { BoardManager } from '../useBoard/types';
|
||||||
|
import type { GameStatusManager } from '../useGameStatus/types';
|
||||||
import { useHero } from './useHero';
|
import { useHero } from './useHero';
|
||||||
import { useGameKeys } from './useGameKeys';
|
import { useGameKeys } from './useGameKeys';
|
||||||
import { useMazeNavigation } from '../useBoard';
|
import { useMazeNavigation } from '../useBoard';
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import type { GameStatusManager, KeyLogEntry, Cursor } from "../types";
|
import type { GameStatusManager } from "../useGameStatus/types";
|
||||||
|
import type { KeyLogEntry } from "../types";
|
||||||
|
import type { Cursor } from "./types";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import type { BoardManager, GameStatusManager, GameStatus, Coord, UseHeroType } from "../types";
|
import type { BoardManager } from "../useBoard/types";
|
||||||
|
import type { GameStatusManager, GameStatus } from "../useGameStatus/types";
|
||||||
|
import type { UseHeroType, Coord } from "./types";
|
||||||
import { useHeroRender } from "./useHeroRender";
|
import { useHeroRender } from "./useHeroRender";
|
||||||
import { useMazeNavigation } from "../useBoard";
|
import { useMazeNavigation } from "../useBoard";
|
||||||
import { useAnimation } from "./useAnimation";
|
import { useAnimation } from "./useAnimation";
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import type { BoardManager, GameStatus, Coord, UseHeroType, HeroRenderManager } from "../types";
|
import type { BoardManager } from "../useBoard/types";
|
||||||
|
import type { GameStatus } from "../useGameStatus/types";
|
||||||
|
import type { UseHeroType, HeroRenderManager, Coord } from "./types";
|
||||||
|
|
||||||
export type { HeroRenderManager } from "../types";
|
export type { HeroRenderManager } from "./types";
|
||||||
|
|
||||||
type UseHeroRenderParams = {
|
type UseHeroRenderParams = {
|
||||||
gameStatus: GameStatus;
|
gameStatus: GameStatus;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import type { VimMotionSystem, Motion } from '../types';
|
import type { VimMotionSystem, Motion } from './types';
|
||||||
|
|
||||||
export type { Motion } from '../types';
|
export type { Motion } from './types';
|
||||||
export type { VimMotionSystem } from '../types';
|
export type { VimMotionSystem } from './types';
|
||||||
|
|
||||||
export function useVimMotions(): VimMotionSystem {
|
export function useVimMotions(): VimMotionSystem {
|
||||||
const countRef = useRef<string>('');
|
const countRef = useRef<string>('');
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
export * from './types';
|
||||||
export * from './useGameStatus';
|
export * from './useGameStatus';
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export type GameStatus = 'waiting' | 'started' | 'has-key' | 'paused' | 'game-over' | 'game-won';
|
||||||
|
|
||||||
|
export type GameStatusManager = {
|
||||||
|
gameStatus: GameStatus;
|
||||||
|
setGameStatus: (status: GameStatus) => void;
|
||||||
|
startGame: () => void;
|
||||||
|
togglePause: (pause?: boolean) => void;
|
||||||
|
quitGame: () => void;
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { GameStatus, BoardManager, Coord } from '../types';
|
import type { GameStatus } from './types';
|
||||||
|
import type { BoardManager, Coord } from '../useBoard/types';
|
||||||
|
|
||||||
export function useGameStatus(board?: BoardManager, setHeroPos?: (pos: Coord) => void) {
|
export function useGameStatus(board?: BoardManager, setHeroPos?: (pos: Coord) => void) {
|
||||||
const [gameStatus, setGameStatus] = useState<GameStatus>('waiting');
|
const [gameStatus, setGameStatus] = useState<GameStatus>('waiting');
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from './types';
|
||||||
export * from './useScore';
|
export * from './useScore';
|
||||||
export * from './useScorePaths';
|
export * from './useScorePaths';
|
||||||
export * from './useScoreTime';
|
export * from './useScoreTime';
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export type TimerManager = {
|
||||||
|
timeValue: number;
|
||||||
|
startTimer: () => void;
|
||||||
|
stopTimer: () => void;
|
||||||
|
resetTimer: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ScorePathsResult = {
|
||||||
|
entranceToKey: number;
|
||||||
|
entranceToExit: number;
|
||||||
|
heroToKey: number;
|
||||||
|
heroToExit: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ScoreManager = {
|
||||||
|
timeValue: number;
|
||||||
|
startTimer: () => void;
|
||||||
|
stopTimer: () => void;
|
||||||
|
resetTimer: () => void;
|
||||||
|
distToKey: number;
|
||||||
|
distToExit: number;
|
||||||
|
keystrokes: number;
|
||||||
|
optimalSteps: number;
|
||||||
|
efficiency: number;
|
||||||
|
finalScore: number | null;
|
||||||
|
};
|
||||||
@@ -2,7 +2,9 @@ import { useEffect, useRef, useState } from "react";
|
|||||||
import { useTimer } from "./useTimer";
|
import { useTimer } from "./useTimer";
|
||||||
import { useScoreTime } from "./useScoreTime";
|
import { useScoreTime } from "./useScoreTime";
|
||||||
import { useScorePaths } from "./useScorePaths";
|
import { useScorePaths } from "./useScorePaths";
|
||||||
import type { BoardManager, GameStatusManager, UseHeroType } from "../types";
|
import type { BoardManager } from "../useBoard/types";
|
||||||
|
import type { GameStatusManager } from "../useGameStatus/types";
|
||||||
|
import type { UseHeroType } from "../useCursor/types";
|
||||||
|
|
||||||
type UseScoreParams = {
|
type UseScoreParams = {
|
||||||
board: BoardManager;
|
board: BoardManager;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import type { BoardManager, Coord, ScorePathsResult } from "../types";
|
import type { BoardManager, Coord } from "../useBoard/types";
|
||||||
|
import type { ScorePathsResult } from "./types";
|
||||||
|
|
||||||
export type { ScorePathsResult } from "../types";
|
export type { ScorePathsResult } from "./types";
|
||||||
|
|
||||||
type UseScorePathsParams = {
|
type UseScorePathsParams = {
|
||||||
board: BoardManager;
|
board: BoardManager;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import type { TimerManager, GameStatus } from "../types";
|
import type { TimerManager } from "./types";
|
||||||
|
import type { GameStatus } from "../useGameStatus/types";
|
||||||
|
|
||||||
type UseScoreTimeParams = {
|
type UseScoreTimeParams = {
|
||||||
gameStatus: GameStatus;
|
gameStatus: GameStatus;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useState, useRef, useEffect } from "react";
|
import { useState, useRef, useEffect } from "react";
|
||||||
import type { TimerManager } from '../types';
|
import type { TimerManager } from './types';
|
||||||
|
|
||||||
export type { TimerManager } from '../types';
|
export type { TimerManager } from './types';
|
||||||
|
|
||||||
export function useTimer(): TimerManager {
|
export function useTimer(): TimerManager {
|
||||||
const [timeValue, setTimeValue] = useState(0);
|
const [timeValue, setTimeValue] = useState(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user