flutter_sudoku/lib/services/puzzle_service.dart
2025-11-11 14:38:15 +09:00

88 lines
2.9 KiB
Dart

import 'dart:convert';
import 'dart:developer';
import 'package:http/http.dart' as http;
import 'package:sudoku_app/models/sudoku_game_dto.dart';
import 'package:sudoku_app/models/unified_rank_dto.dart';
import 'package:sudoku_app/models/game_rank_dto.dart';
class PuzzleService {
final String _baseUrl = "https://lunaticbum.kr";
// 🔽 [수정] 'difficulty' 파라미터 1개만 받음 (1~11)
Future<SudokuGameDto> startGame(String difficulty) async {
final response = await http.get(
// 🔽 [수정] 'difficulty' 파라미터만 전달
Uri.parse('$_baseUrl/puzzle/sudoku/start?difficulty=$difficulty'),
);
if (response.statusCode == 200) {
final data = jsonDecode(utf8.decode(response.bodyBytes));
return SudokuGameDto.fromJson(data);
} else {
throw Exception('게임 로딩 실패: ${response.statusCode}');
}
}
// 'puzzleId'를 받아 검증 (서버 DTO와 일치)
Future<bool> validateSolution(int puzzleId, String answer) async {
final response = await http.post(
Uri.parse('$_baseUrl/puzzle/sudoku/validate'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'puzzleId': puzzleId,
'answer': answer,
}),
);
if (response.statusCode == 200) {
return jsonDecode(response.body)['correct'] ?? false;
} else {
log("정답 확인 실패: ${response.statusCode}");
log("응답 본문: ${response.body}");
throw Exception('정답 확인 실패: ${response.statusCode}');
}
}
// 랭킹 등록
Future<void> submitRank(UnifiedRankDto rankDto) async {
final requestBody = jsonEncode(rankDto.toJson());
log(">>> 랭킹 등록 요청: $requestBody");
final response = await http.post(
Uri.parse('$_baseUrl/api/ranks/submit'),
headers: {'Content-Type': 'application/json'},
body: requestBody,
);
if (response.statusCode != 200) {
log("<<< 랭킹 등록 실패: ${response.statusCode}");
try {
final errorBody = utf8.decode(response.bodyBytes);
log("<<< 서버 에러 메시지: $errorBody");
throw Exception(errorBody);
} catch (e) {
throw Exception('랭킹 등록 실패: ${response.reasonPhrase}');
}
}
log("<<< 랭킹 등록 성공: 200 OK");
}
// 랭킹 조회
Future<List<GameRankDto>> fetchRanks(String gameType, String? contextId) async {
final queryParams = {
'gameType': gameType,
if (contextId != null) 'contextId': contextId,
};
final uri = Uri.parse('$_baseUrl/api/ranks/list').replace(queryParameters: queryParams);
final response = await http.get(uri);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
return data.map((json) => GameRankDto.fromJson(json)).toList();
} else {
throw Exception('랭킹 로딩 실패');
}
}
}