Spaces:
Sleeping
Sleeping
| /// <reference path="../react-app-env.d.ts" /> | |
| import * as React from 'react'; | |
| const { useState, useEffect } = React; | |
| import { startNewGame, undoMove, resignGame, NewGameOptions } from '../services/api'; | |
| import { setSoundEnabled, playSound } from '../services/soundService'; | |
| interface GameControlsProps { | |
| // Theme props removed but kept in comments for future reference | |
| // onThemeChange: (theme: 'brown' | 'grey') => void; | |
| // currentTheme: 'brown' | 'grey'; | |
| } | |
| const GameControls: React.FC<GameControlsProps> = () => { | |
| const [showNewGameOptions, setShowNewGameOptions] = useState(false); | |
| const [soundOn, setSoundOn] = useState(true); | |
| const [gameOptions, setGameOptions] = useState<NewGameOptions>({ | |
| player_color: 'white', | |
| difficulty: 'medium', | |
| time_limit: 1.0, | |
| use_opening_book: true, | |
| enable_analysis: true, | |
| }); | |
| // Initialize sound settings | |
| useEffect(() => { | |
| setSoundEnabled(soundOn); | |
| }, [soundOn]); | |
| const handleNewGame = async () => { | |
| try { | |
| await startNewGame(gameOptions); | |
| setShowNewGameOptions(false); | |
| window.location.reload(); // Refresh to reset the board state | |
| } catch (error) { | |
| console.error('Error starting new game:', error); | |
| } | |
| }; | |
| const handleUndo = async () => { | |
| try { | |
| await undoMove(); | |
| window.location.reload(); // Refresh to update the board state | |
| } catch (error) { | |
| console.error('Error undoing move:', error); | |
| } | |
| }; | |
| const handleResign = async () => { | |
| if (window.confirm('Are you sure you want to resign?')) { | |
| try { | |
| await resignGame(); | |
| window.location.reload(); // Refresh to update the game state | |
| } catch (error) { | |
| console.error('Error resigning game:', error); | |
| } | |
| } | |
| }; | |
| return ( | |
| <div className="w-full max-w-[800px] mb-6"> | |
| <div className="flex flex-wrap gap-3 justify-center mb-4"> | |
| <button | |
| className="px-5 py-3 bg-gradio-orange text-white rounded-lg hover:bg-orange-500 transition-colors text-lg font-medium" | |
| onClick={() => setShowNewGameOptions(!showNewGameOptions)} | |
| > | |
| New Game | |
| </button> | |
| <button | |
| className="px-5 py-3 bg-gradio-blue text-white rounded-lg hover:bg-blue-500 transition-colors text-lg font-medium" | |
| onClick={handleUndo} | |
| > | |
| Undo Move | |
| </button> | |
| <button | |
| className="px-5 py-3 bg-gradio-red text-white rounded-lg hover:bg-red-500 transition-colors text-lg font-medium" | |
| onClick={handleResign} | |
| > | |
| Resign | |
| </button> | |
| </div> | |
| {showNewGameOptions && ( | |
| <div className="mt-4 p-6 bg-gradio-card border border-gradio-border rounded-lg shadow-lg text-gradio-text"> | |
| <h3 className="text-2xl font-medium mb-4 text-gradio-yellow">New Game Options</h3> | |
| <div className="space-y-4"> | |
| <div> | |
| <label className="block text-lg font-medium mb-2">Play as</label> | |
| <select | |
| className="w-full px-4 py-3 bg-gradio-bg border border-gradio-border rounded-lg text-lg" | |
| value={gameOptions.player_color} | |
| onChange={(e) => setGameOptions({ ...gameOptions, player_color: e.target.value as 'white' | 'black' })} | |
| > | |
| <option value="white">White</option> | |
| <option value="black">Black</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label className="block text-lg font-medium mb-2">Difficulty</label> | |
| <select | |
| className="w-full px-4 py-3 bg-gradio-bg border border-gradio-border rounded-lg text-lg" | |
| value={gameOptions.difficulty} | |
| onChange={(e) => setGameOptions({ ...gameOptions, difficulty: e.target.value as any })} | |
| > | |
| <option value="beginner">Beginner</option> | |
| <option value="easy">Easy</option> | |
| <option value="medium">Medium</option> | |
| <option value="hard">Hard</option> | |
| <option value="expert">Expert</option> | |
| <option value="master">Master</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label className="block text-lg font-medium mb-2"> | |
| Time Limit (seconds): <span className="text-gradio-orange">{gameOptions.time_limit}</span> | |
| </label> | |
| <input | |
| type="range" | |
| min="0.1" | |
| max="10" | |
| step="0.1" | |
| className="w-full h-3 bg-gradio-bg rounded-lg appearance-none cursor-pointer" | |
| value={gameOptions.time_limit} | |
| onChange={(e) => setGameOptions({ ...gameOptions, time_limit: parseFloat(e.target.value) })} | |
| /> | |
| </div> | |
| <div className="flex items-center"> | |
| <input | |
| type="checkbox" | |
| id="use-opening-book" | |
| checked={gameOptions.use_opening_book} | |
| onChange={(e) => setGameOptions({ ...gameOptions, use_opening_book: e.target.checked })} | |
| className="w-5 h-5 mr-3" | |
| /> | |
| <label htmlFor="use-opening-book" className="text-lg">Use opening book</label> | |
| </div> | |
| <div className="flex items-center"> | |
| <input | |
| type="checkbox" | |
| id="enable-analysis" | |
| checked={gameOptions.enable_analysis} | |
| onChange={(e) => setGameOptions({ ...gameOptions, enable_analysis: e.target.checked })} | |
| className="w-5 h-5 mr-3" | |
| /> | |
| <label htmlFor="enable-analysis" className="text-lg">Enable position analysis</label> | |
| </div> | |
| <button | |
| className="w-full px-4 py-3 bg-gradio-orange text-white rounded-lg hover:bg-orange-500 transition-colors text-xl font-medium mt-2" | |
| onClick={handleNewGame} | |
| > | |
| Start Game | |
| </button> | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default GameControls; |