2025-11-19 17:00:33 +09:00
// packages/feature_game_cardflip/lib/models/cardflip_models.dart
import ' package:flutter/material.dart ' ;
import ' package:service_api/service_api.dart ' ;
enum CardContentType {
2025-11-19 17:16:43 +09:00
emoji , // 🐰 ↔ 🐰
icon , // ⭐️ ↔ ⭐️
number , // 1 ↔ 1
2025-11-19 17:34:52 +09:00
calculation , // 3+4 ↔ 7
2025-11-19 17:16:43 +09:00
pairWord , // 토끼 ↔ 당근
2025-11-19 17:00:33 +09:00
}
class CardItem {
2025-11-19 17:16:43 +09:00
final int id ;
final String matchId ;
final String displayContent ;
2025-11-19 17:00:33 +09:00
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 {
2025-11-19 17:34:52 +09:00
// --- 콘텐츠 풀 ---
2025-11-19 17:00:33 +09:00
static const List < String > emojis = [
" 🐶 " , " 🐱 " , " 🐭 " , " 🐹 " , " 🐰 " , " 🦊 " , " 🐻 " , " 🐼 " , " 🐨 " , " 🐯 " ,
" 🦁 " , " 🐮 " , " 🐷 " , " 🐸 " , " 🐵 " , " 🐔 " , " 🐧 " , " 🐦 " , " 🐤 " , " 🦆 " ,
" 🍎 " , " 🍌 " , " 🍇 " , " 🍓 " , " 🍊 " , " 🍋 " , " 🍉 " , " 🍑 " , " 🍒 " , " 🥝 " ,
" ⚽ " , " 🏀 " , " 🏈 " , " ⚾ " , " 🎾 " , " 🏐 " , " 🏉 " , " 🎱 " , " 🏓 " , " 🏸 "
] ;
2025-11-19 17:34:52 +09:00
// 연상 단어 풀 (총 80+쌍)
2025-11-19 17:00:33 +09:00
static const Map < String , String > wordPairs = {
2025-11-19 17:34:52 +09:00
" 토끼 " : " 당근 " , " 원숭이 " : " 바나나 " , " 다람쥐 " : " 도토리 " , " 고양이 " : " 생선 " ,
" 개 " : " 뼈다귀 " , " 소 " : " 여물 " , " 닭 " : " 달걀 " , " 벌 " : " 꿀 " ,
" 거미 " : " 거미줄 " , " 개구리 " : " 올챙이 " , " 팬더 " : " 대나무 " , " 호랑이 " : " 가죽 " ,
" 누에 " : " 뽕잎 " , " 양 " : " 양털 " , " 펭귄 " : " 남극 " , " 사자 " : " 초원 " ,
" 바늘 " : " 실 " , " 망치 " : " 못 " , " 활 " : " 화살 " , " 자물쇠 " : " 열쇠 " ,
" 숟가락 " : " 젓가락 " , " 책상 " : " 의자 " , " 신발 " : " 양말 " , " 장갑 " : " 목도리 " ,
" 지우개 " : " 연필 " , " 칠판 " : " 분필 " , " 붓 " : " 물감 " , " 도장 " : " 인주 " ,
" 냄비 " : " 뚜껑 " , " 샴푸 " : " 린스 " , " 치약 " : " 칫솔 " , " 비누 " : " 수건 " ,
" 배게 " : " 이불 " , " 항아리 " : " 뚜껑 " , " 안경 " : " 안경집 " , " 핸드폰 " : " 충전기 " ,
" 해 " : " 달 " , " 하늘 " : " 구름 " , " 비 " : " 우산 " , " 눈 " : " 눈사람 " ,
" 봄 " : " 꽃 " , " 여름 " : " 부채 " , " 가을 " : " 단풍 " , " 겨울 " : " 눈 " ,
" 바다 " : " 파도 " , " 산 " : " 나무 " , " 사막 " : " 선인장 " , " 밤 " : " 별 " ,
" 번개 " : " 천둥 " , " 무지개 " : " 비온뒤 " , " 화산 " : " 용암 " , " 지진 " : " 진동 " ,
" 밥 " : " 국 " , " 빵 " : " 우유 " , " 삼겹살 " : " 상추 " , " 짜장면 " : " 단무지 " ,
" 치킨 " : " 무 " , " 떡볶이 " : " 오뎅 " , " 피자 " : " 콜라 " , " 회 " : " 초장 " ,
" 감자 " : " 고구마 " , " 소금 " : " 설탕 " , " 간장 " : " 고추장 " , " 된장 " : " 쌈장 " ,
" 남자 " : " 여자 " , " 부모 " : " 자식 " , " 할아버지 " : " 할머니 " , " 형 " : " 동생 " ,
" 선생님 " : " 학생 " , " 의사 " : " 환자 " , " 경찰 " : " 도둑 " , " 가수 " : " 마이크 " ,
" 화가 " : " 그림 " , " 요리사 " : " 주방 " , " 어부 " : " 낚시대 " , " 군인 " : " 총 " ,
" 왕 " : " 왕비 " , " 왕자 " : " 공주 " , " 신랑 " : " 신부 " , " 주인 " : " 손님 " ,
" 한국 " : " 서울 " , " 미국 " : " 워싱턴 " , " 프랑스 " : " 파리 " , " 영국 " : " 런던 " ,
" 일본 " : " 도쿄 " , " 중국 " : " 베이징 " , " 학교 " : " 교실 " , " 병원 " : " 주사기 " ,
" 은행 " : " 돈 " , " 우체국 " : " 편지 " , " 극장 " : " 영화 " , " 도서관 " : " 책 " ,
" 공항 " : " 비행기 " , " 항구 " : " 배 " , " 역 " : " 기차 " , " 정류장 " : " 버스 " ,
" 시계 " : " 시간 " , " 달력 " : " 날짜 " , " 거울 " : " 얼굴 " , " 빗 " : " 머리카락 " ,
" 가방 " : " 책 " , " 모자 " : " 머리 " , " 안경 " : " 눈 " , " 마스크 " : " 입 " ,
2025-11-19 17:00:33 +09:00
} ;
2025-11-19 17:34:52 +09:00
// [🔥 수정] 21단계 난이도 목록 (6x6 헬모드 추가)
2025-11-19 17:00:33 +09:00
static final List < CardFlipDifficulty > allDifficulties = [
2025-11-19 17:34:52 +09:00
// --- 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
) ,
2025-11-19 17:00:33 +09:00
] ;
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 ] ) ;
}
}