| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { useState, useCallback } from 'react';
- import type { GuessEntry, GuessResponse } from '@wordle/shared';
- const BASE = '/api';
- interface UseGameReturn {
- guesses: GuessEntry[];
- gameStatus: 'playing' | 'won' | 'lost';
- message: string | null;
- lastDifficulty: number | null;
- revealedWord: string | null;
- submitGuess: (wordId: number, guess: string) => Promise<void>;
- dismissMessage: () => void;
- resetForNewGame: () => void;
- }
- export function useGame(initialGuesses: GuessEntry[]): UseGameReturn {
- const [guesses, setGuesses] = useState<GuessEntry[]>(initialGuesses);
- const [message, setMessage] = useState<string | null>(null);
- const [lastDifficulty, setLastDifficulty] = useState<number | null>(null);
- const [revealedWord, setRevealedWord] = useState<string | null>(null);
- const gameStatus = deriveStatus(guesses);
- const dismissMessage = useCallback(() => setMessage(null), []);
- const resetForNewGame = useCallback(() => {
- setGuesses([]);
- setMessage(null);
- setLastDifficulty(null);
- setRevealedWord(null);
- }, []);
- const submitGuess = useCallback(async (wordId: number, guess: string) => {
- const tryNo = guesses.length + 1;
- const lowerGuess = guess.toLowerCase();
- const res = await fetch(`${BASE}/guess`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ wordId, guess: lowerGuess, tryNo }),
- });
- if (!res.ok) {
- const body = await res.json().catch(() => ({}));
- setMessage((body as { error?: string }).error ?? `HTTP ${res.status}`);
- return;
- }
- const data: GuessResponse = await res.json();
- if (!data.valid) {
- setMessage('Unknown word');
- return;
- }
- const entry: GuessEntry = { guess: lowerGuess, colors: data.colors! };
- setGuesses((prev) => [...prev, entry]);
- if (data.difficulty !== undefined) {
- setLastDifficulty(data.difficulty);
- }
- if (data.word) {
- setRevealedWord(data.word);
- }
- }, [guesses.length]);
- return { guesses, gameStatus, message, lastDifficulty, revealedWord, submitGuess, dismissMessage, resetForNewGame };
- }
- function deriveStatus(guesses: GuessEntry[]): 'playing' | 'won' | 'lost' {
- if (guesses.length === 0) return 'playing';
- const last = guesses[guesses.length - 1];
- if (last.colors.every((c) => c === 'g')) return 'won';
- if (guesses.length >= 6) return 'lost';
- return 'playing';
- }
|