// 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 emojis = [ "๐Ÿถ", "๐Ÿฑ", "๐Ÿญ", "๐Ÿน", "๐Ÿฐ", "๐ŸฆŠ", "๐Ÿป", "๐Ÿผ", "๐Ÿจ", "๐Ÿฏ", "๐Ÿฆ", "๐Ÿฎ", "๐Ÿท", "๐Ÿธ", "๐Ÿต", "๐Ÿ”", "๐Ÿง", "๐Ÿฆ", "๐Ÿค", "๐Ÿฆ†", "๐ŸŽ", "๐ŸŒ", "๐Ÿ‡", "๐Ÿ“", "๐ŸŠ", "๐Ÿ‹", "๐Ÿ‰", "๐Ÿ‘", "๐Ÿ’", "๐Ÿฅ", "โšฝ", "๐Ÿ€", "๐Ÿˆ", "โšพ", "๐ŸŽพ", "๐Ÿ", "๐Ÿ‰", "๐ŸŽฑ", "๐Ÿ“", "๐Ÿธ" ]; // โŒ [์‚ญ์ œ๋จ] calculationPairs (์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋™์  ์ƒ์„ฑํ•˜๋ฏ€๋กœ ์ œ๊ฑฐ) // ์—ฐ์ƒ ๋‹จ์–ด ํ’€ (A : B) static const Map wordPairs = { "ํ† ๋ผ": "๋‹น๊ทผ", "์›์ˆญ์ด": "๋ฐ”๋‚˜๋‚˜", "ํ•œ๊ตญ": "์„œ์šธ", "๋ฏธ๊ตญ": "์›Œ์‹ฑํ„ด", "ํ•ด": "๋‹ฌ", "์—ฌ๋ฆ„": "๊ฒจ์šธ", "๋‚จ์ž": "์—ฌ์ž", "ํ•™๊ต": "ํ•™์ƒ", "๋ณ‘์›": "์˜์‚ฌ", "๋ฐ”๋Š˜": "์‹ค", "์šฐ์‚ฐ": "๋น„", "์ฑ…์ƒ": "์˜์ž", "๋ด„": "๊ฝƒ", "๊ฐ€์„": "๋‹จํ’", "์ˆŸ๊ฐ€๋ฝ": "์ “๊ฐ€๋ฝ" }; // ๋‚œ์ด๋„ ๋ชฉ๋ก (15๋‹จ๊ณ„) static final List 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), const CardFlipDifficulty(levelIndex: 16, name: 'Lv. 15: ํ—ฌ (์—ฐ์ƒ)', contextId: 'FLIP_L16_6x6_PAIR', rows: 6, cols: 6, 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]); } }