feat: integrate MemoryPairs game with global GameModeContext
- Remove local gameMode state from MemoryPairsContext - Derive game mode from global activePlayerCount - Update types to reflect gameMode as computed property - Remove SET_GAME_MODE action and setGameMode function - Update gameScoring getAchievements to accept gameMode parameter - Games now read player configuration from global context 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { createContext, useContext, useReducer, useEffect, type ReactNode } from 'react'
|
||||
import { useGameMode } from '../../../../contexts/GameModeContext'
|
||||
import { validateMatch } from '../utils/matchValidation'
|
||||
import { generateGameCards } from '../utils/cardGeneration'
|
||||
import type {
|
||||
@@ -12,15 +13,14 @@ import type {
|
||||
CelebrationAnimation
|
||||
} from './types'
|
||||
|
||||
// Initial state
|
||||
// Initial state (gameMode removed - now derived from global context)
|
||||
const initialState: MemoryPairsState = {
|
||||
// Core game data
|
||||
cards: [],
|
||||
gameCards: [],
|
||||
flippedCards: [],
|
||||
|
||||
// Game configuration
|
||||
gameMode: 'single',
|
||||
// Game configuration (gameMode removed)
|
||||
gameType: 'abacus-numeral',
|
||||
difficulty: 6,
|
||||
turnTimer: 30,
|
||||
@@ -49,14 +49,7 @@ const initialState: MemoryPairsState = {
|
||||
// Reducer function
|
||||
function memoryPairsReducer(state: MemoryPairsState, action: MemoryPairsAction): MemoryPairsState {
|
||||
switch (action.type) {
|
||||
case 'SET_GAME_MODE':
|
||||
return {
|
||||
...state,
|
||||
gameMode: action.mode,
|
||||
// Reset scores when switching modes
|
||||
scores: { player1: 0, player2: 0 },
|
||||
currentPlayer: 1
|
||||
}
|
||||
// SET_GAME_MODE removed - game mode now derived from global context
|
||||
|
||||
case 'SET_GAME_TYPE':
|
||||
return {
|
||||
@@ -153,17 +146,14 @@ function memoryPairsReducer(state: MemoryPairsState, action: MemoryPairsAction):
|
||||
}
|
||||
|
||||
case 'MATCH_FAILED': {
|
||||
const newCurrentPlayer = state.gameMode === 'two-player'
|
||||
? (state.currentPlayer === 1 ? 2 : 1)
|
||||
: state.currentPlayer
|
||||
|
||||
// Player switching is now handled by passing activePlayerCount
|
||||
return {
|
||||
...state,
|
||||
flippedCards: [],
|
||||
currentPlayer: newCurrentPlayer,
|
||||
moves: state.moves + 1,
|
||||
showMismatchFeedback: true,
|
||||
isProcessingMove: false
|
||||
isProcessingMove: false,
|
||||
// currentPlayer will be updated by SWITCH_PLAYER action when needed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +200,6 @@ function memoryPairsReducer(state: MemoryPairsState, action: MemoryPairsAction):
|
||||
case 'RESET_GAME':
|
||||
return {
|
||||
...initialState,
|
||||
gameMode: state.gameMode,
|
||||
gameType: state.gameType,
|
||||
difficulty: state.difficulty,
|
||||
turnTimer: state.turnTimer,
|
||||
@@ -232,6 +221,10 @@ const MemoryPairsContext = createContext<MemoryPairsContextValue | null>(null)
|
||||
// Provider component
|
||||
export function MemoryPairsProvider({ children }: { children: ReactNode }) {
|
||||
const [state, dispatch] = useReducer(memoryPairsReducer, initialState)
|
||||
const { activePlayerCount } = useGameMode()
|
||||
|
||||
// Derive game mode from active player count
|
||||
const gameMode = activePlayerCount > 1 ? 'two-player' : 'single'
|
||||
|
||||
// Handle card matching logic when two cards are flipped
|
||||
useEffect(() => {
|
||||
@@ -247,10 +240,14 @@ export function MemoryPairsProvider({ children }: { children: ReactNode }) {
|
||||
dispatch({ type: 'MATCH_FOUND', cardIds: [card1.id, card2.id] })
|
||||
} else {
|
||||
dispatch({ type: 'MATCH_FAILED', cardIds: [card1.id, card2.id] })
|
||||
// Switch player only in two-player mode
|
||||
if (gameMode === 'two-player') {
|
||||
dispatch({ type: 'SWITCH_PLAYER' })
|
||||
}
|
||||
}
|
||||
}, 1000) // Give time to see both cards
|
||||
}
|
||||
}, [state.flippedCards, state.isProcessingMove])
|
||||
}, [state.flippedCards, state.isProcessingMove, gameMode])
|
||||
|
||||
// Auto-hide mismatch feedback
|
||||
useEffect(() => {
|
||||
@@ -307,9 +304,7 @@ export function MemoryPairsProvider({ children }: { children: ReactNode }) {
|
||||
dispatch({ type: 'RESET_GAME' })
|
||||
}
|
||||
|
||||
const setGameMode = (mode: typeof state.gameMode) => {
|
||||
dispatch({ type: 'SET_GAME_MODE', mode })
|
||||
}
|
||||
// setGameMode removed - game mode is now derived from global context
|
||||
|
||||
const setGameType = (gameType: typeof state.gameType) => {
|
||||
dispatch({ type: 'SET_GAME_TYPE', gameType })
|
||||
@@ -320,7 +315,7 @@ export function MemoryPairsProvider({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
const contextValue: MemoryPairsContextValue = {
|
||||
state,
|
||||
state: { ...state, gameMode }, // Add derived gameMode to state
|
||||
dispatch,
|
||||
isGameActive,
|
||||
canFlipCard,
|
||||
@@ -328,9 +323,9 @@ export function MemoryPairsProvider({ children }: { children: ReactNode }) {
|
||||
startGame,
|
||||
flipCard,
|
||||
resetGame,
|
||||
setGameMode,
|
||||
setGameType,
|
||||
setDifficulty
|
||||
setDifficulty,
|
||||
gameMode // Expose derived gameMode
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -47,8 +47,7 @@ export interface MemoryPairsState {
|
||||
gameCards: GameCard[]
|
||||
flippedCards: GameCard[]
|
||||
|
||||
// Game configuration
|
||||
gameMode: GameMode
|
||||
// Game configuration (gameMode removed - now derived from global context)
|
||||
gameType: GameType
|
||||
difficulty: Difficulty
|
||||
turnTimer: number // Seconds for two-player mode
|
||||
@@ -75,7 +74,6 @@ export interface MemoryPairsState {
|
||||
}
|
||||
|
||||
export type MemoryPairsAction =
|
||||
| { type: 'SET_GAME_MODE'; mode: GameMode }
|
||||
| { type: 'SET_GAME_TYPE'; gameType: GameType }
|
||||
| { type: 'SET_DIFFICULTY'; difficulty: Difficulty }
|
||||
| { type: 'SET_TURN_TIMER'; timer: number }
|
||||
@@ -93,19 +91,19 @@ export type MemoryPairsAction =
|
||||
| { type: 'UPDATE_TIMER' }
|
||||
|
||||
export interface MemoryPairsContextValue {
|
||||
state: MemoryPairsState
|
||||
state: MemoryPairsState & { gameMode: GameMode } // gameMode added as computed property
|
||||
dispatch: React.Dispatch<MemoryPairsAction>
|
||||
|
||||
// Computed values
|
||||
isGameActive: boolean
|
||||
canFlipCard: (cardId: string) => boolean
|
||||
currentGameStatistics: GameStatistics
|
||||
gameMode: GameMode // Derived from global context
|
||||
|
||||
// Actions
|
||||
startGame: () => void
|
||||
flipCard: (cardId: string) => void
|
||||
resetGame: () => void
|
||||
setGameMode: (mode: GameMode) => void
|
||||
setGameType: (type: GameType) => void
|
||||
setDifficulty: (difficulty: Difficulty) => void
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ export interface Achievement {
|
||||
earned: boolean
|
||||
}
|
||||
|
||||
export function getAchievements(state: MemoryPairsState): Achievement[] {
|
||||
const { matchedPairs, totalPairs, moves, scores, gameMode, gameStartTime, gameEndTime } = state
|
||||
export function getAchievements(state: MemoryPairsState, gameMode: 'single' | 'two-player'): Achievement[] {
|
||||
const { matchedPairs, totalPairs, moves, scores, gameStartTime, gameEndTime } = state
|
||||
const accuracy = moves > 0 ? (matchedPairs / moves) * 100 : 0
|
||||
const gameTime = gameStartTime && gameEndTime ? gameEndTime - gameStartTime : 0
|
||||
const gameTimeInSeconds = gameTime / 1000
|
||||
|
||||
Reference in New Issue
Block a user