2025-11-19 17:00:33 +09:00

111 lines
6.0 KiB
Dart

// packages/feature_game_cardflip/lib/models/cardflip_models.dart
import 'package:flutter/material.dart';
import 'package:service_api/service_api.dart';
/// 카드에 들어갈 콘텐츠 타입
enum CardContentType {
emoji, // 기존: 똑같은 이모지 (🐰 ↔ 🐰)
icon, // 기존: 똑같은 아이콘 (⭐️ ↔ ⭐️)
number, // 기존: 똑같은 숫자 (1 ↔ 1)
calculation, // [🔥 신규] 연산 (3+4 ↔ 7)
pairWord, // [🔥 신규] 연상 단어 (토끼 ↔ 당근)
}
/// 개별 카드 상태 모델
class CardItem {
final int id; // 카드의 고유 식별자 (GridView 인덱스와 무관, 셔플됨)
final String matchId; // [🔥 신규] 매칭 판단용 ID (이게 같으면 정답)
final String displayContent; // [🔥 신규] 화면에 보여질 내용
bool isFaceUp;
bool isMatched;
CardItem({
required this.id,
required this.matchId,
required this.displayContent,
this.isFaceUp = false,
this.isMatched = false,
});
}
class CardFlipDifficulty extends GameDifficulty {
final int levelIndex;
final int rows;
final int cols;
final int timeLimitSeconds;
final CardContentType contentType;
const CardFlipDifficulty({
required this.levelIndex,
required super.name,
required super.contextId,
required this.rows,
required this.cols,
required this.timeLimitSeconds,
required this.contentType,
});
int get totalCards => rows * cols;
}
class CardFlipDifficulties {
// --- 콘텐츠 풀 ---
static const List<String> emojis = [
"🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼", "🐨", "🐯",
"🦁", "🐮", "🐷", "🐸", "🐵", "🐔", "🐧", "🐦", "🐤", "🦆",
"🍎", "🍌", "🍇", "🍓", "🍊", "🍋", "🍉", "🍑", "🍒", "🥝",
"", "🏀", "🏈", "", "🎾", "🏐", "🏉", "🎱", "🏓", "🏸"
];
// [🔥 신규] 연산 문제 풀 (질문 : 정답)
static const Map<String, String> calculationPairs = {
"2 + 3": "5", "5 + 5": "10", "7 - 2": "5", "3 x 3": "9", "10 - 4": "6",
"6 + 6": "12", "8 + 1": "9", "4 x 2": "8", "15 - 5": "10", "20 / 2": "10",
"1 + 1": "2", "9 - 3": "6", "2 x 5": "10", "8 / 2": "4", "3 + 7": "10"
};
// [🔥 신규] 연상 단어 풀 (A : B)
static const Map<String, String> wordPairs = {
"토끼": "당근", "원숭이": "바나나", "한국": "서울", "미국": "워싱턴",
"": "", "여름": "겨울", "남자": "여자", "학교": "학생",
"병원": "의사", "바늘": "", "우산": "", "책상": "의자",
"": "", "가을": "단풍", "숟가락": "젓가락"
};
// --- 난이도 목록 (15단계) ---
static final List<CardFlipDifficulty> allDifficulties = [
// Phase 1: 입문 (동일 매칭)
const CardFlipDifficulty(levelIndex: 1, name: 'Lv. 1: 입문 (이모지 12)', contextId: 'FLIP_L1_EMOJI', rows: 4, cols: 3, timeLimitSeconds: 40, contentType: CardContentType.emoji),
const CardFlipDifficulty(levelIndex: 2, name: 'Lv. 2: 초급 (아이콘 12)', contextId: 'FLIP_L2_ICON', rows: 4, cols: 3, timeLimitSeconds: 30, contentType: CardContentType.icon),
const CardFlipDifficulty(levelIndex: 3, name: 'Lv. 3: 기초 (숫자 16)', contextId: 'FLIP_L3_NUM', rows: 4, cols: 4, timeLimitSeconds: 50, contentType: CardContentType.number),
// Phase 2: 연산/연상 (기억 + 사고)
const CardFlipDifficulty(levelIndex: 4, name: 'Lv. 4: 연산 (덧셈/뺄셈)', contextId: 'FLIP_L4_CALC', rows: 4, cols: 4, timeLimitSeconds: 60, contentType: CardContentType.calculation),
const CardFlipDifficulty(levelIndex: 5, name: 'Lv. 5: 연상 (짝꿍 단어)', contextId: 'FLIP_L5_PAIR', rows: 4, cols: 4, timeLimitSeconds: 60, contentType: CardContentType.pairWord),
const CardFlipDifficulty(levelIndex: 6, name: 'Lv. 6: 도전 (이모지 20)', contextId: 'FLIP_L6_EMOJI_20', rows: 5, cols: 4, timeLimitSeconds: 70, contentType: CardContentType.emoji),
// Phase 3: 상급 (혼합/확장)
const CardFlipDifficulty(levelIndex: 7, name: 'Lv. 7: 상급 (연산 20)', contextId: 'FLIP_L7_CALC_20', rows: 5, cols: 4, timeLimitSeconds: 90, contentType: CardContentType.calculation),
const CardFlipDifficulty(levelIndex: 8, name: 'Lv. 8: 전문가 (연상 20)', contextId: 'FLIP_L8_PAIR_20', rows: 5, cols: 4, timeLimitSeconds: 90, contentType: CardContentType.pairWord),
const CardFlipDifficulty(levelIndex: 9, name: 'Lv. 9: 엘리트 (아이콘 24)', contextId: 'FLIP_L9_ICON_24', rows: 6, cols: 4, timeLimitSeconds: 100, contentType: CardContentType.icon),
// Phase 4: 마스터 (대형 그리드)
const CardFlipDifficulty(levelIndex: 10, name: 'Lv. 10: 마스터 (24장)', contextId: 'FLIP_L10_6x4', rows: 6, cols: 4, timeLimitSeconds: 100, contentType: CardContentType.emoji),
const CardFlipDifficulty(levelIndex: 11, name: 'Lv. 11: 그랜드마스터', contextId: 'FLIP_L11_6x4_CALC', rows: 6, cols: 4, timeLimitSeconds: 110, contentType: CardContentType.calculation),
const CardFlipDifficulty(levelIndex: 12, name: 'Lv. 12: 레전드', contextId: 'FLIP_L12_6x4_PAIR', rows: 6, cols: 4, timeLimitSeconds: 110, contentType: CardContentType.pairWord),
// Phase 5: 신의 영역
const CardFlipDifficulty(levelIndex: 13, name: 'Lv. 13: 갓모드 (30장)', contextId: 'FLIP_L13_6x5', rows: 6, cols: 5, timeLimitSeconds: 130, contentType: CardContentType.emoji),
const CardFlipDifficulty(levelIndex: 14, name: 'Lv. 14: 타임어택 (연산)', contextId: 'FLIP_L14_6x5_CALC', rows: 6, cols: 5, timeLimitSeconds: 120, contentType: CardContentType.calculation),
const CardFlipDifficulty(levelIndex: 15, name: 'Lv. 15: 엔드게임 (연상)', contextId: 'FLIP_L15_6x5_PAIR', rows: 6, cols: 5, timeLimitSeconds: 120, contentType: CardContentType.pairWord),
];
static CardFlipDifficulty getLevel(int levelIndex) {
if (levelIndex < 1) levelIndex = 1;
if (levelIndex > allDifficulties.length) levelIndex = allDifficulties.length;
return allDifficulties.firstWhere((level) => level.levelIndex == levelIndex,
orElse: () => allDifficulties[0]);
}
}