UNPKG

tmemory

Version:

A terminal-based Memory card game built with React Ink. Features multiple grid sizes, AI opponent, and high scores.

104 lines (103 loc) 5.38 kB
import { Box, Text, useApp, useInput } from 'ink'; import BigText from 'ink-big-text'; import Gradient from 'ink-gradient'; import React, { useState } from 'react'; import { submitScore } from '../../api/scoreApi.js'; import { GameLayout } from "../../components/layout/GameLayout.js"; import { COLORS } from "../../constants/colors.js"; import { useGame } from "../../context/GameContext/index.js"; import { useHighScores } from "../../context/HighScoreContext/index.js"; import { formatTime } from "../../utils/time.js"; import { FinalScore } from "./components/FinalScore.js"; import { Leaderboard } from "./components/Leaderboard.js"; import { PlayerNameInput } from "./components/PlayerNameInput.js"; import { WinnerDisplay } from "./components/WinnerDisplay.js"; export const GameOver = () => { const { exit } = useApp(); const { state, dispatch } = useGame(); const [nameSubmitted, setNameSubmitted] = useState(false); const [scoreChecked, setScoreChecked] = useState(false); useInput((input) => { if (nameSubmitted && input === 'n') { dispatch({ type: 'SET_GAME_STATE', payload: 'welcome' }); } else if (nameSubmitted && input === 'q') { exit(); } else if (input.toLowerCase() === 'l') { dispatch({ type: 'SET_GAME_STATE', payload: 'leaderboard' }); } }); const { getHighScore, isNewHighScore, saveHighScore, getDeviceId } = useHighScores(); // Check high scores React.useEffect(() => { const timeElapsed = endTime - startTime; const isNew = isNewHighScore(timeElapsed, gridDimension, gameMode); if (isNew) { dispatch({ type: 'SET_IS_NEW_RECORD', payload: true }); } dispatch({ type: 'SET_SHOULD_TRACK_SCORE', payload: true }); setScoreChecked(true); }, []); // Handle player name submission const handleNameSubmit = async (playerName) => { const timeElapsed = endTime - startTime; const date = new Date().toISOString(); const scoreData = { time: timeElapsed, rows: gridDimension.rows, cols: gridDimension.cols, gameMode, date, playerName, deviceId: getDeviceId(), }; // Save the high score locally saveHighScore(scoreData); // Submit the score remotely via API try { const response = await submitScore(scoreData); console.log('Score submitted:', response.score); } catch (error) { console.error('Score submission error:', error); } setNameSubmitted(true); }; const { endTime, startTime, scores, gameMode, gridDimension, winner, shouldTrackScore, isNewRecord, } = state; const timeElapsed = endTime - startTime; const currentHighScore = getHighScore(gameMode, gridDimension); return (React.createElement(GameLayout, null, React.createElement(Box, { flexDirection: "column", alignItems: "center", padding: 1 }, React.createElement(Box, { flexDirection: "column", alignItems: "center", height: 4 }, React.createElement(Gradient, { name: "mind" }, React.createElement(BigText, { text: "Game Over" }))), React.createElement(WinnerDisplay, { winner: winner }), React.createElement(FinalScore, { scores: scores, gameMode: gameMode }), React.createElement(Box, { flexDirection: "column", alignItems: "center" }, React.createElement(Text, { color: COLORS.info }, "Time: ", React.createElement(Text, { bold: true }, formatTime(timeElapsed))), shouldTrackScore && (isNewRecord ? (React.createElement(Text, { color: COLORS.gold, bold: true }, "\u2605 New Record", gameMode === 'vs-player' ? ` by ${winner}` : '', "! \u2605")) : (currentHighScore && (React.createElement(Text, { color: COLORS.dim }, "Best: ", React.createElement(Text, { bold: true }, formatTime(currentHighScore.time))))))), scoreChecked && (React.createElement(PlayerNameInput, { isNewRecord: isNewRecord, onNameSubmit: handleNameSubmit })), nameSubmitted && (React.createElement(Leaderboard, { gameMode: gameMode, gridDimension: gridDimension })), React.createElement(Text, { color: COLORS.dim }, "Press ", React.createElement(Text, { color: COLORS.ai, bold: true }, "L"), " to view leaderboard"), React.createElement(Box, { flexDirection: "column", alignItems: "center", marginY: 1 }, React.createElement(Text, { color: COLORS.dim }, nameSubmitted ? (React.createElement(React.Fragment, null, "Press ", React.createElement(Text, { color: COLORS.p1, bold: true }, "N"), " for new game")) : (React.createElement(React.Fragment, null, "Enter your name to continue"))), nameSubmitted && (React.createElement(Text, { color: COLORS.dim }, "Press ", React.createElement(Text, { color: COLORS.ai, bold: true }, "Q"), " to quit")))))); };