TypeScript · 2922 bytes Raw Blame History
1 import { useState, useCallback } from 'react';
2 import { gameApi, FileSystemTree, TreeNode, MoleDirection } from '@/lib/api';
3
4 interface GameState {
5 tree: FileSystemTree | null;
6 sessionId: number | null;
7 loading: boolean;
8 error: string | null;
9 }
10
11 interface GameStats {
12 score: number;
13 molesKilled: number;
14 moleDirection: MoleDirection | null;
15 moleKilled: boolean;
16 }
17
18 export const useGameState = () => {
19 const [gameState, setGameState] = useState<GameState>({
20 tree: null,
21 sessionId: null,
22 loading: false,
23 error: null,
24 });
25
26 const [gameStats, setGameStats] = useState<GameStats>({
27 score: 0,
28 molesKilled: 0,
29 moleDirection: null,
30 moleKilled: false,
31 });
32
33 const [hasPlayedIntro, setHasPlayedIntro] = useState(false);
34
35 const updatePlayerLocation = useCallback((newPath: string) => {
36 setGameState(prev => ({
37 ...prev,
38 tree: prev.tree ? {
39 ...prev.tree,
40 player_location: newPath,
41 } : null,
42 }));
43 }, []);
44
45 const updateTreeData = useCallback((updater: (tree: TreeNode) => TreeNode) => {
46 setGameState(prev => ({
47 ...prev,
48 tree: prev.tree ? {
49 ...prev.tree,
50 tree_data: updater(prev.tree.tree_data),
51 } : null,
52 }));
53 }, []);
54
55 const setMoleDirection = useCallback((direction: MoleDirection | null) => {
56 setGameStats(prev => ({ ...prev, moleDirection: direction }));
57
58 // Auto-hide after 5 seconds
59 if (direction) {
60 setTimeout(() => {
61 setGameStats(prev => ({ ...prev, moleDirection: null }));
62 }, 5000);
63 }
64 }, []);
65
66 const setMoleKilled = useCallback((killed: boolean) => {
67 setGameStats(prev => ({ ...prev, moleKilled: killed }));
68 }, []);
69
70 const updateScore = useCallback((score: number, molesKilled: number) => {
71 setGameStats(prev => ({
72 ...prev,
73 score,
74 molesKilled,
75 }));
76 }, []);
77
78 const startNewGame = useCallback(async () => {
79 try {
80 setGameState(prev => ({ ...prev, loading: true, error: null }));
81 const response = await gameApi.createGame('Player1');
82
83 setGameState({
84 tree: response.tree,
85 sessionId: response.session_id,
86 loading: false,
87 error: null,
88 });
89
90 // Reset game stats
91 setGameStats({
92 score: 0,
93 molesKilled: 0,
94 moleDirection: null,
95 moleKilled: false,
96 });
97
98 setHasPlayedIntro(false);
99
100 return response;
101 } catch {
102 setGameState(prev => ({
103 ...prev,
104 loading: false,
105 error: 'Failed to start game. Is the backend running on http://localhost:8000?',
106 }));
107 return null;
108 }
109 }, []);
110
111 return {
112 // State
113 gameState,
114 gameStats,
115 hasPlayedIntro,
116
117 // Actions
118 startNewGame,
119 updatePlayerLocation,
120 updateTreeData,
121 setMoleDirection,
122 setMoleKilled,
123 updateScore,
124 setHasPlayedIntro,
125 };
126 };