import 'package:flutter/material.dart'; import 'package:sudoku_app/models/sudoku_game_dto.dart'; import 'package:sudoku_app/models/sudoku_theme.dart'; import 'package:sudoku_app/screens/game_screen.dart'; import 'package:sudoku_app/screens/ranking_screen.dart'; import 'package:sudoku_app/services/puzzle_service.dart'; import 'package:sudoku_app/widgets/ad_banner_widget.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { // 난이도 double _difficultyLevel = 2.0; final List levelLabels = ["Easy", "Normal", "Medium", "Hard", "Expert"]; // 그리드 크기 double _blockSize = 3.0; // 🔽 [수정] 16x16, 25x25 옵션 제거 final List sizeLabels = ["4x4", "9x9"]; // 테마 이름 late String _selectedThemeName; bool isLoading = false; final PuzzleService _puzzleService = PuzzleService(); @override void initState() { super.initState(); // 기본 테마를 '랜덤' 이름으로 설정 _selectedThemeName = AppThemes.random; } Future _startGame() async { setState(() { isLoading = true; }); try { final String level = _difficultyLevel.round().toString(); final String blockSize = _blockSize.round().toString(); final SudokuGameDto gameData = await _puzzleService.startGame(level, blockSize); // 선택된 '테마 이름(String)'을 그대로 전달 if (mounted) { Navigator.push( context, MaterialPageRoute( builder: (context) => GameScreen( gameData: gameData, themeName: _selectedThemeName, ), ), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('게임 로딩 실패: $e')), ); } } finally { if (mounted) { setState(() { isLoading = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('스도쿠 게임')), body: LayoutBuilder( // 비율 기반 레이아웃 builder: (context, constraints) { const double maxContentRatio = 0.6; final double constrainedWidth = constraints.maxHeight * maxContentRatio; return Center( child: ConstrainedBox( constraints: BoxConstraints(maxWidth: constrainedWidth), child: Column( children: [ Expanded( child: Center( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 1. 난이도 선택 const Text("난이도", style: TextStyle(fontSize: 18)), Slider( value: _difficultyLevel, min: 1.0, max: 5.0, divisions: 4, label: levelLabels[_difficultyLevel.round() - 1], onChanged: (newValue) => setState(() { _difficultyLevel = newValue; }), ), const SizedBox(height: 20), // 2. 그리드 크기 선택 const Text("그리드 크기", style: TextStyle(fontSize: 18)), Text( // 🔽 [수정] 인덱스 매핑 변경 (2.0 -> index 0) sizeLabels[_blockSize.round() - 2], style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.deepOrange), ), Slider( value: _blockSize, // 🔽 [수정] 최대값을 3.0으로, divisions를 1로 변경 min: 2.0, max: 3.0, divisions: 1, label: sizeLabels[_blockSize.round() - 2], activeColor: Colors.deepOrange, onChanged: (newValue) => setState(() { _blockSize = newValue; }), ), const SizedBox(height: 20), // 3. 테마 선택 (String 기반) const Text("테마", style: TextStyle(fontSize: 18)), DropdownButton( value: _selectedThemeName, items: AppThemes.selectableThemeNames.map((themeName) { return DropdownMenuItem( value: themeName, child: Text(themeName, style: const TextStyle(fontSize: 20)), ); }).toList(), onChanged: (themeName) { if (themeName != null) { setState(() { _selectedThemeName = themeName; }); } }, ), const SizedBox(height: 30), if (isLoading) const CircularProgressIndicator() else ElevatedButton( onPressed: _startGame, style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 15)), child: const Text('게임 시작', style: TextStyle(fontSize: 18)), ), const SizedBox(height: 10), TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const RankingScreen()), ); }, child: const Text('랭킹 보기'), ), ], ), ), ), ), const AdBannerWidget(), ], ), ), ); }, ), ); } }