Spaces:
Sleeping
Sleeping
import React from 'react' | |
import { GameState, CHESS_MODELS } from '../types/chess' | |
import { VolumeSlider } from './VolumeSlider' | |
import '../styles/GameControls.css' | |
export const GameControls: React.FC<{ | |
gameState: GameState | |
audioEnabled: boolean | |
volumeSettings: { | |
ambient: number | |
game: number | |
} | |
selectedModel: string | |
onStartGame: () => void | |
onResignGame: () => void | |
onToggleColor: () => void | |
onToggleAudio: () => void | |
onVolumeChange: (type: "ambient" | "game", value: number) => void | |
onModelChange: (modelId: string) => void | |
}> = ({ | |
gameState, | |
audioEnabled, | |
volumeSettings, | |
selectedModel, | |
onStartGame, | |
onResignGame, | |
onToggleColor, | |
onToggleAudio, | |
onVolumeChange, | |
onModelChange | |
}) => { | |
const getMainButtonText = () => { | |
if (gameState.gameActive) { | |
return 'โ Resign Game' | |
} | |
return '๐ฎ Start Game' | |
} | |
const getMainButtonAction = () => { | |
if (gameState.gameActive) { | |
return onResignGame | |
} | |
return onStartGame | |
} | |
const getColorButtonText = () => { | |
return `โช Play as ${gameState.playerColor === 'w' ? 'White' : 'Black'}` | |
} | |
const getAudioButtonText = () => { | |
return `๐ Audio: ${audioEnabled ? 'ON' : 'OFF'}` | |
} | |
const getGameStatus = () => { | |
if (gameState.aiModelLoading) { | |
return ( | |
<div className="thinking-indicator"> | |
Loading AI model<span className="thinking-dots"></span> | |
</div> | |
) | |
} | |
if (gameState.gameActive) { | |
if (gameState.aiThinking) { | |
return ( | |
<div className="thinking-indicator"> | |
AI is thinking<span className="thinking-dots"></span> | |
</div> | |
) | |
} else if (gameState.board.turn() === gameState.playerColor) { | |
return `Your turn (${gameState.playerColor === 'w' ? 'White' : 'Black'})` | |
} else { | |
return `AI turn (${gameState.playerColor === 'w' ? 'Black' : 'White'})` | |
} | |
} else if (gameState.gameResult?.isGameOver) { | |
return gameState.gameResult.message | |
} else { | |
const aiStatusText = gameState.aiModelLoaded ? '' : ' (AI: Fallback mode)' | |
return `Click 'Start Game' to begin${aiStatusText}` | |
} | |
} | |
return ( | |
<div className="game-controls"> | |
<div className="game-status"> | |
{getGameStatus()} | |
</div> | |
<div className="control-buttons"> | |
<button | |
className="button main-button" | |
onClick={getMainButtonAction()} | |
> | |
{getMainButtonText()} | |
</button> | |
{!gameState.gameActive && ( | |
<> | |
<button | |
className="button color-button" | |
onClick={onToggleColor} | |
> | |
{getColorButtonText()} | |
</button> | |
<div className="model-selector"> | |
<label htmlFor="model-select">๐ค Chess Model:</label> | |
<select | |
id="model-select" | |
className="model-dropdown" | |
value={selectedModel} | |
onChange={(e) => onModelChange(e.target.value)} | |
disabled={gameState.aiModelLoading} | |
> | |
{CHESS_MODELS.map((model) => ( | |
<option key={model} value={model}> | |
{model} | |
</option> | |
))} | |
</select> | |
</div> | |
</> | |
)} | |
<button | |
className="button audio-button" | |
onClick={onToggleAudio} | |
> | |
{getAudioButtonText()} | |
</button> | |
</div> | |
{audioEnabled && ( | |
<div className="volume-controls"> | |
<h3 className="volume-controls-title">Audio Volume</h3> | |
<VolumeSlider | |
label="๐ต Initative Tempo" | |
value={volumeSettings.ambient} | |
onChange={(value) => onVolumeChange('ambient', value)} | |
/> | |
<VolumeSlider | |
label="โ๏ธ Move Notes" | |
value={volumeSettings.game} | |
onChange={(value) => onVolumeChange('game', value)} | |
/> | |
</div> | |
)} | |
</div> | |
) | |
} |