146 lines
8.5 KiB
Dart
146 lines
8.5 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;
|
|
final String matchId;
|
|
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 = [
|
|
"🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼", "🐨", "🐯",
|
|
"🦁", "🐮", "🐷", "🐸", "🐵", "🐔", "🐧", "🐦", "🐤", "🦆",
|
|
"🍎", "🍌", "🍇", "🍓", "🍊", "🍋", "🍉", "🍑", "🍒", "🥝",
|
|
"⚽", "🏀", "🏈", "⚾", "🎾", "🏐", "🏉", "🎱", "🏓", "🏸"
|
|
];
|
|
|
|
// 연상 단어 풀 (총 80+쌍)
|
|
static const Map<String, String> wordPairs = {
|
|
"토끼": "당근", "원숭이": "바나나", "다람쥐": "도토리", "고양이": "생선",
|
|
"개": "뼈다귀", "소": "여물", "닭": "달걀", "벌": "꿀",
|
|
"거미": "거미줄", "개구리": "올챙이", "팬더": "대나무", "호랑이": "가죽",
|
|
"누에": "뽕잎", "양": "양털", "펭귄": "남극", "사자": "초원",
|
|
|
|
"바늘": "실", "망치": "못", "활": "화살", "자물쇠": "열쇠",
|
|
"숟가락": "젓가락", "책상": "의자", "신발": "양말", "장갑": "목도리",
|
|
"지우개": "연필", "칠판": "분필", "붓": "물감", "도장": "인주",
|
|
"냄비": "뚜껑", "샴푸": "린스", "치약": "칫솔", "비누": "수건",
|
|
"배게": "이불", "항아리": "뚜껑", "핸드폰": "충전기",
|
|
|
|
"해": "달", "하늘": "구름", "비": "우산", "눈": "눈사람",
|
|
"봄": "꽃", "여름": "부채", "가을": "단풍", "겨울": "눈",
|
|
"바다": "파도", "산": "나무", "사막": "선인장", "밤": "별",
|
|
"번개": "천둥", "무지개": "비온뒤", "화산": "용암", "지진": "진동",
|
|
|
|
"밥": "국", "빵": "우유", "삼겹살": "상추", "짜장면": "단무지",
|
|
"치킨": "무", "떡볶이": "오뎅", "피자": "콜라", "회": "초장",
|
|
"감자": "고구마", "소금": "설탕", "간장": "고추장", "된장": "쌈장",
|
|
|
|
"남자": "여자", "부모": "자식", "할아버지": "할머니", "형": "동생",
|
|
"선생님": "학생", "의사": "환자", "경찰": "도둑", "가수": "마이크",
|
|
"화가": "그림", "요리사": "주방", "어부": "낚시대", "군인": "총",
|
|
"왕": "왕비", "왕자": "공주", "신랑": "신부", "주인": "손님",
|
|
|
|
"한국": "서울", "미국": "워싱턴", "프랑스": "파리", "영국": "런던",
|
|
"일본": "도쿄", "중국": "베이징", "학교": "교실", "병원": "주사기",
|
|
"은행": "돈", "우체국": "편지", "극장": "영화", "도서관": "책",
|
|
"공항": "비행기", "항구": "배", "역": "기차", "정류장": "버스",
|
|
|
|
"시계": "시간", "달력": "날짜", "거울": "얼굴", "빗": "머리카락",
|
|
"가방": "책", "모자": "머리", "안경": "눈", "마스크": "입",
|
|
};
|
|
|
|
// [🔥 수정] 21단계 난이도 목록 (6x6 헬모드 추가)
|
|
static final List<CardFlipDifficulty> allDifficulties = [
|
|
// --- Phase 1: 입문 (6~8장) ---
|
|
const CardFlipDifficulty(levelIndex: 1, name: 'Lv. 1: 입문 (숫자 6장)', contextId: 'FLIP_L1_2x3_NUM', rows: 3, cols: 2, timeLimitSeconds: 30, contentType: CardContentType.number),
|
|
const CardFlipDifficulty(levelIndex: 2, name: 'Lv. 2: 입문 (이모지 6장)', contextId: 'FLIP_L2_2x3_EMOJI', rows: 3, cols: 2, timeLimitSeconds: 25, contentType: CardContentType.emoji),
|
|
const CardFlipDifficulty(levelIndex: 3, name: 'Lv. 3: 기초 (숫자 8장)', contextId: 'FLIP_L3_2x4_NUM', rows: 4, cols: 2, timeLimitSeconds: 40, contentType: CardContentType.number),
|
|
const CardFlipDifficulty(levelIndex: 4, name: 'Lv. 4: 기초 (이모지 8장)', contextId: 'FLIP_L4_2x4_EMOJI', rows: 4, cols: 2, timeLimitSeconds: 35, contentType: CardContentType.emoji),
|
|
|
|
// --- Phase 2: 초급 (12장) ---
|
|
const CardFlipDifficulty(levelIndex: 5, name: 'Lv. 5: 초급 (이모지 12장)', contextId: 'FLIP_L5_3x4_EMOJI', rows: 4, cols: 3, timeLimitSeconds: 50, contentType: CardContentType.emoji),
|
|
const CardFlipDifficulty(levelIndex: 6, name: 'Lv. 6: 초급 (아이콘 12장)', contextId: 'FLIP_L6_3x4_ICON', rows: 4, cols: 3, timeLimitSeconds: 45, contentType: CardContentType.icon),
|
|
const CardFlipDifficulty(levelIndex: 7, name: 'Lv. 7: 초급 (연산 12장)', contextId: 'FLIP_L7_3x4_CALC', rows: 4, cols: 3, timeLimitSeconds: 60, contentType: CardContentType.calculation),
|
|
const CardFlipDifficulty(levelIndex: 8, name: 'Lv. 8: 초급 (단어 12장)', contextId: 'FLIP_L8_3x4_PAIR', rows: 4, cols: 3, timeLimitSeconds: 60, contentType: CardContentType.pairWord),
|
|
|
|
// --- Phase 3: 중급 (16장) ---
|
|
const CardFlipDifficulty(levelIndex: 9, name: 'Lv. 9: 중급 (숫자 16장)', contextId: 'FLIP_L9_4x4_NUM', rows: 4, cols: 4, timeLimitSeconds: 70, contentType: CardContentType.number),
|
|
const CardFlipDifficulty(levelIndex: 10, name: 'Lv. 10: 중급 (아이콘 16장)', contextId: 'FLIP_L10_4x4_ICON', rows: 4, cols: 4, timeLimitSeconds: 65, contentType: CardContentType.icon),
|
|
const CardFlipDifficulty(levelIndex: 11, name: 'Lv. 11: 중급 (연산 16장)', contextId: 'FLIP_L11_4x4_CALC', rows: 4, cols: 4, timeLimitSeconds: 90, contentType: CardContentType.calculation),
|
|
const CardFlipDifficulty(levelIndex: 12, name: 'Lv. 12: 중급 (단어 16장)', contextId: 'FLIP_L12_4x4_PAIR', rows: 4, cols: 4, timeLimitSeconds: 90, contentType: CardContentType.pairWord),
|
|
|
|
// --- Phase 4: 상급 (20~24장) ---
|
|
const CardFlipDifficulty(levelIndex: 13, name: 'Lv. 13: 상급 (이모지 20장)', contextId: 'FLIP_L13_5x4_EMOJI', rows: 5, cols: 4, timeLimitSeconds: 100, contentType: CardContentType.emoji),
|
|
const CardFlipDifficulty(levelIndex: 14, name: 'Lv. 14: 상급 (연산 20장)', contextId: 'FLIP_L14_5x4_CALC', rows: 5, cols: 4, timeLimitSeconds: 120, contentType: CardContentType.calculation),
|
|
const CardFlipDifficulty(levelIndex: 15, name: 'Lv. 15: 전문가 (아이콘 24장)', contextId: 'FLIP_L15_6x4_ICON', rows: 6, cols: 4, timeLimitSeconds: 120, contentType: CardContentType.icon),
|
|
const CardFlipDifficulty(levelIndex: 16, name: 'Lv. 16: 전문가 (단어 24장)', contextId: 'FLIP_L16_6x4_PAIR', rows: 6, cols: 4, timeLimitSeconds: 150, contentType: CardContentType.pairWord),
|
|
|
|
// --- Phase 5: 마스터 (30장) ---
|
|
const CardFlipDifficulty(levelIndex: 17, name: 'Lv. 17: 마스터 (숫자 30장)', contextId: 'FLIP_L17_6x5_NUM', rows: 6, cols: 5, timeLimitSeconds: 150, contentType: CardContentType.number),
|
|
const CardFlipDifficulty(levelIndex: 18, name: 'Lv. 18: 마스터 (연산 30장)', contextId: 'FLIP_L18_6x5_CALC', rows: 6, cols: 5, timeLimitSeconds: 180, contentType: CardContentType.calculation),
|
|
const CardFlipDifficulty(levelIndex: 19, name: 'Lv. 19: 레전드 (단어 30장)', contextId: 'FLIP_L19_6x5_PAIR', rows: 6, cols: 5, timeLimitSeconds: 180, contentType: CardContentType.pairWord),
|
|
const CardFlipDifficulty(levelIndex: 20, name: 'Lv. 20: 갓모드 (이모지 30장)', contextId: 'FLIP_L20_6x5_EMOJI', rows: 6, cols: 5, timeLimitSeconds: 120, contentType: CardContentType.emoji),
|
|
|
|
// --- [🔥 신규] Phase 6: 헬모드 (6x6 = 36장) ---
|
|
const CardFlipDifficulty(
|
|
levelIndex: 21,
|
|
name: 'Lv. 21: 헬모드 (36장)',
|
|
contextId: 'FLIP_L21_6x6_HELL',
|
|
rows: 6,
|
|
cols: 6,
|
|
timeLimitSeconds: 240,
|
|
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]);
|
|
}
|
|
} |