From 9a9022356ab1472d6eeae0a0f63fd9ccd303bdf3 Mon Sep 17 00:00:00 2001 From: Horoli Date: Sun, 7 Dec 2025 18:49:07 +0900 Subject: [PATCH] Refactor: Centralize Constants and Configuration --- lib/game/config/battle_config.dart | 14 ++++++++++++++ lib/game/config/game_config.dart | 5 +++++ lib/game/config/item_config.dart | 3 +++ lib/game/logic/combat_calculator.dart | 13 +++++++------ lib/game/logic/loot_generator.dart | 3 ++- lib/providers/battle_provider.dart | 23 ++++++++++++----------- prompt/59_centralize_constants.md | 19 +++++++++++++++++++ 7 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 prompt/59_centralize_constants.md diff --git a/lib/game/config/battle_config.dart b/lib/game/config/battle_config.dart index b5de767..17cbc47 100644 --- a/lib/game/config/battle_config.dart +++ b/lib/game/config/battle_config.dart @@ -20,6 +20,20 @@ class BattleConfig { static const double sizeNormal = 60.0; static const double sizeSafe = 40.0; + // Logic Constants + // Safe + static const double safeBaseChance = 1.0; // 100% + static const double safeEfficiency = 0.5; // 50% + // Normal + static const double normalBaseChance = 0.8; // 80% + static const double normalEfficiency = 1.0; // 100% + // Risky + static const double riskyBaseChance = 0.4; // 40% + static const double riskyEfficiency = 2.0; // 200% + + // Enemy Logic + static const double enemyAttackChance = 0.7; // 70% Attack, 30% Defend + static IconData getIcon(ActionType type) { switch (type) { case ActionType.attack: diff --git a/lib/game/config/game_config.dart b/lib/game/config/game_config.dart index 076d1aa..1b0cfdf 100644 --- a/lib/game/config/game_config.dart +++ b/lib/game/config/game_config.dart @@ -18,6 +18,11 @@ class GameConfig { static const double stageHealRatio = 0.1; static const double vulnerableDamageMultiplier = 1.5; static const double armorDecayRate = 0.5; + + // Rewards + static const int baseGoldReward = 10; + static const int goldRewardPerStage = 5; + static const int goldRewardVariance = 10; // Animations (Duration in milliseconds) static const int animDelaySafe = 500; diff --git a/lib/game/config/item_config.dart b/lib/game/config/item_config.dart index e492d32..04d3772 100644 --- a/lib/game/config/item_config.dart +++ b/lib/game/config/item_config.dart @@ -11,4 +11,7 @@ class ItemConfig { ItemRarity.legendary: 4, ItemRarity.unique: 1, }; + + // Loot Generation + static const double magicPrefixChance = 0.5; // 50% } diff --git a/lib/game/logic/combat_calculator.dart b/lib/game/logic/combat_calculator.dart index be11f0b..c2c901f 100644 --- a/lib/game/logic/combat_calculator.dart +++ b/lib/game/logic/combat_calculator.dart @@ -3,6 +3,7 @@ import '../model/entity.dart'; import '../model/status_effect.dart'; import '../enums.dart'; import '../config/game_config.dart'; +import '../config/battle_config.dart'; // Import BattleConfig import '../model/damage_event.dart'; class CombatResult { @@ -33,16 +34,16 @@ class CombatCalculator { switch (risk) { case RiskLevel.safe: - baseChance = 1.0; - efficiency = 0.5; + baseChance = BattleConfig.safeBaseChance; + efficiency = BattleConfig.safeEfficiency; break; case RiskLevel.normal: - baseChance = 0.8; - efficiency = 1.0; + baseChance = BattleConfig.normalBaseChance; + efficiency = BattleConfig.normalEfficiency; break; case RiskLevel.risky: - baseChance = 0.4; - efficiency = 2.0; + baseChance = BattleConfig.riskyBaseChance; + efficiency = BattleConfig.riskyEfficiency; break; } diff --git a/lib/game/logic/loot_generator.dart b/lib/game/logic/loot_generator.dart index d8f0f3d..d07b43b 100644 --- a/lib/game/logic/loot_generator.dart +++ b/lib/game/logic/loot_generator.dart @@ -4,6 +4,7 @@ import '../data/item_table.dart'; // For ItemTemplate import '../data/item_prefix_table.dart'; import '../data/name_generator.dart'; import '../enums.dart'; +import '../config/item_config.dart'; // Import ItemConfig class LootGenerator { static final Random _random = Random(); @@ -48,7 +49,7 @@ class LootGenerator { } // 1. Magic Rarity: 50% chance to get a Magic Prefix (1 stat change) else if (template.rarity == ItemRarity.magic) { - if (_random.nextBool()) { // 50% chance + if (_random.nextDouble() < ItemConfig.magicPrefixChance) { // Use constant // Filter valid prefixes for this slot final validPrefixes = ItemPrefixTable.magicPrefixes.where((p) { return p.allowedSlots == null || p.allowedSlots!.contains(template.slot); diff --git a/lib/providers/battle_provider.dart b/lib/providers/battle_provider.dart index 20bdd89..b7cb7fa 100644 --- a/lib/providers/battle_provider.dart +++ b/lib/providers/battle_provider.dart @@ -18,6 +18,7 @@ import '../game/model/effect_event.dart'; // EffectEvent import import '../game/save_manager.dart'; import '../game/config/game_config.dart'; +import '../game/config/battle_config.dart'; // Import BattleConfig import 'shop_provider.dart'; // Import ShopProvider import '../game/logic/battle_log_manager.dart'; @@ -625,7 +626,7 @@ class BattleProvider with ChangeNotifier { // Calculate Gold Reward // Base 10 + (Stage * 5) + Random variance final random = Random(); - int goldReward = 10 + (stage * 5) + random.nextInt(10); + int goldReward = GameConfig.baseGoldReward + (stage * GameConfig.goldRewardPerStage) + random.nextInt(GameConfig.goldRewardVariance); player.gold += goldReward; _lastGoldReward = goldReward; // Store for UI display @@ -798,7 +799,7 @@ class BattleProvider with ChangeNotifier { if (canDefend) { // 70% Attack, 30% Defend - isAttack = random.nextDouble() < 0.7; + isAttack = random.nextDouble() < BattleConfig.enemyAttackChance; } else { isAttack = true; } @@ -808,13 +809,13 @@ class BattleProvider with ChangeNotifier { double efficiency = 1.0; switch (risk) { case RiskLevel.safe: - efficiency = 0.5; + efficiency = BattleConfig.safeEfficiency; break; case RiskLevel.normal: - efficiency = 1.0; + efficiency = BattleConfig.normalEfficiency; break; case RiskLevel.risky: - efficiency = 2.0; + efficiency = BattleConfig.riskyEfficiency; break; } @@ -828,13 +829,13 @@ class BattleProvider with ChangeNotifier { bool success = false; switch (risk) { case RiskLevel.safe: - success = random.nextDouble() < 1.0; + success = random.nextDouble() < BattleConfig.safeBaseChance; break; case RiskLevel.normal: - success = random.nextDouble() < 0.8; + success = random.nextDouble() < BattleConfig.normalBaseChance; break; case RiskLevel.risky: - success = random.nextDouble() < 0.4; + success = random.nextDouble() < BattleConfig.riskyBaseChance; break; } @@ -856,13 +857,13 @@ class BattleProvider with ChangeNotifier { bool success = false; switch (risk) { case RiskLevel.safe: - success = random.nextDouble() < 1.0; + success = random.nextDouble() < BattleConfig.safeBaseChance; break; case RiskLevel.normal: - success = random.nextDouble() < 0.8; + success = random.nextDouble() < BattleConfig.normalBaseChance; break; case RiskLevel.risky: - success = random.nextDouble() < 0.4; + success = random.nextDouble() < BattleConfig.riskyBaseChance; break; } diff --git a/prompt/59_centralize_constants.md b/prompt/59_centralize_constants.md new file mode 100644 index 0000000..b10fea0 --- /dev/null +++ b/prompt/59_centralize_constants.md @@ -0,0 +1,19 @@ +# 59. Centralize Constants and Configuration + +## 1. 목표 (Goal) +- 코드 곳곳에 흩어져 있는 '매직 넘버(Magic Numbers)'와 하드코딩된 설정 값들을 `lib/game/config/` 폴더 내의 설정 파일들로 중앙화합니다. +- 특히 전투 공식, 확률, 아이템 생성 가중치 등을 설정 파일로 이동하여 밸런스 조정 및 유지보수를 용이하게 합니다. + +## 2. 구현 계획 (Implementation Plan) +1. **설정 파일 업데이트:** + - `BattleConfig`: 리스크 레벨별 확률, 효율(Efficiency), 데미지 분산 범위(현재는 제거됨, 필요 시 부활), 상태이상 확률 등. + - `ItemConfig`: 아이템 생성 시 Rarity 가중치(이미 일부 존재), Prefix 등장 확률 등. + - `GameConfig`: 골드 보상 공식 상수, 스테이지 관련 상수 등. +2. **코드 리팩토링:** + - `CombatCalculator`: 하드코딩된 리스크 확률(0.5, 0.8, 0.4 등)과 효율(0.5, 1.0, 2.0)을 `BattleConfig` 상수로 대체. + - `LootGenerator`: Prefix 등장 확률(50% 등)을 `ItemConfig` 상수로 대체. + - `BattleProvider`: 골드 계산 공식 상수를 `GameConfig`로 이동. + +## 3. 기대 효과 (Expected Outcome) +- 게임 밸런스 조정 시 코드 로직을 건드리지 않고 `config` 파일만 수정하면 됨. +- 코드의 가독성이 향상됨 (숫자의 의미가 변수명으로 명확해짐).