import 'dart:math'; import '../models/cognitive_type.dart'; import '../models/assessment_data.dart'; class BrainTrainingService { final Random _random = Random(); /// 사용자 취약점을 분석하여 맞춤형 게임 3개를 추천합니다. List recommendGames(Map? scores) { if (scores == null || scores.isEmpty) { // 기록이 없으면 골고루 추천 (기억, 계산, 주의) return [ BrainGameType.sequence, BrainGameType.mathQuiz, BrainGameType.schulte, ]; } // 1. 점수 기반 취약점 분석 (점수가 높을수록 위험/취약) Map riskRatios = {}; Map totalCountByArea = {}; for (var q in rawAssessmentQuestions) { totalCountByArea[q.area] = (totalCountByArea[q.area] ?? 0) + 1; } scores.forEach((area, score) { int total = totalCountByArea[area] ?? 1; riskRatios[area] = score / total; }); var sortedRisks = riskRatios.entries.toList() ..sort((a, b) => b.value.compareTo(a.value)); CognitiveArea primaryWeakness = sortedRisks[0].key; CognitiveArea secondaryWeakness = sortedRisks.length > 1 ? sortedRisks[1].key : primaryWeakness; List recommendation = []; // 2. 추천 리스트 생성 // (1) 가장 취약한 영역의 게임 recommendation.add(_getGameForArea(primaryWeakness)); // (2) 두 번째 취약한 영역의 게임 (중복 방지) BrainGameType secondGame = _getGameForArea(secondaryWeakness); if (!recommendation.contains(secondGame)) { recommendation.add(secondGame); } else { recommendation.add(_getRandomGameExcluding(recommendation)); } // (3) 랜덤 게임 (밸런스) recommendation.add(_getRandomGameExcluding(recommendation)); return recommendation; } /// 영역별 게임 랜덤 선택 (2개 중 1개) BrainGameType _getGameForArea(CognitiveArea area) { switch (area) { case CognitiveArea.memory: return _random.nextBool() ? BrainGameType.sequence : BrainGameType.cardFlip; case CognitiveArea.calculation: return _random.nextBool() ? BrainGameType.mathQuiz : BrainGameType.sudoku; case CognitiveArea.attention: return _random.nextBool() ? BrainGameType.colorMatch : BrainGameType.schulte; // 슐테(숫자찾기) case CognitiveArea.perception: return _random.nextBool() ? BrainGameType.findDiff : BrainGameType.tracing; // 따라그리기 case CognitiveArea.language: return _random.nextBool() ? BrainGameType.readAloud : BrainGameType.dictation; // 읽기/쓰기 } } BrainGameType _getRandomGameExcluding(List exclude) { var candidates = BrainGameType.values.where((g) => !exclude.contains(g)).toList(); if (candidates.isEmpty) return BrainGameType.sudoku; return candidates[_random.nextInt(candidates.length)]; } }