# 경험 기반 성장 곡선 설계

## 개요

로빙의 성장은 단순한 선형 진행이 아닌, 실제 학습 심리학과 게임 디자인 이론에 기반한 정교한 곡선을 따릅니다. 이 장에서는 성장 곡선의 수학적 모델링과 실제 적용 방법을 다룹니다.

## 성장 곡선의 이론적 배경

### 학습 심리학 기반

```python
class LearningPsychologyModel:
    """
    에빙하우스의 학습 곡선과 플로우 이론을 결합한 모델
    """
    def __init__(self):
        self.stages = {
            "honeymoon": (0, 0.2),      # 초기 흥미 단계 (0-20%)
            "struggle": (0.2, 0.4),      # 어려움 직면 단계 (20-40%)
            "breakthrough": (0.4, 0.6),  # 돌파 단계 (40-60%)
            "mastery": (0.6, 0.8),       # 숙달 단계 (60-80%)
            "refinement": (0.8, 1.0)     # 정교화 단계 (80-100%)
        }
        
    def calculate_learning_efficiency(self, progress: float, engagement: float):
        """
        현재 진행도와 참여도를 기반으로 학습 효율성 계산
        """
        # 각 단계별 기본 효율성
        stage_efficiency = {
            "honeymoon": 1.5,      # 높은 초기 학습률
            "struggle": 0.7,       # 정체기
            "breakthrough": 2.0,   # 급격한 성장
            "mastery": 1.2,        # 안정적 성장
            "refinement": 0.8      # 점진적 개선
        }
        
        current_stage = self.get_current_stage(progress)
        base_efficiency = stage_efficiency[current_stage]
        
        # 참여도에 따른 조정
        engagement_multiplier = 0.5 + (engagement * 1.5)
        
        return base_efficiency * engagement_multiplier
```

### 게임 디자인 원칙

```python
class GameDesignPrinciples:
    """
    플레이어 참여와 보상 체계 설계
    """
    def __init__(self):
        self.reward_schedule = {
            "fixed_interval": self.fixed_interval_reward,
            "variable_ratio": self.variable_ratio_reward,
            "progressive": self.progressive_reward,
            "surprise": self.surprise_reward
        }
        
    def design_reward_curve(self, level: int):
        """
        레벨에 따른 보상 곡선 설계
        """
        # 초반: 잦은 보상으로 동기 부여
        if level <= 5:
            return {
                "frequency": "high",
                "magnitude": "small",
                "type": "fixed_interval"
            }
        # 중반: 변동 보상으로 흥미 유지
        elif level <= 15:
            return {
                "frequency": "medium",
                "magnitude": "variable",
                "type": "variable_ratio"
            }
        # 후반: 큰 보상으로 지속성 확보
        else:
            return {
                "frequency": "low",
                "magnitude": "large",
                "type": "progressive"
            }
```

## 수학적 모델링

### 성장 함수 정의

```python
import numpy as np
from scipy.optimize import curve_fit

class GrowthCurveModel:
    """
    로빙의 성장을 모델링하는 수학적 함수들
    """
    
    @staticmethod
    def sigmoid_growth(x, L, k, x0):
        """
        S자 곡선 성장 모델 (Sigmoid/Logistic)
        L: 최대 성장치 (상한선)
        k: 성장률
        x0: 중간점 (성장이 가장 빠른 지점)
        """
        return L / (1 + np.exp(-k * (x - x0)))
    
    @staticmethod
    def power_law_growth(x, a, b):
        """
        멱법칙 성장 모델 (초기 빠른 성장, 후기 둔화)
        a: 스케일 파라미터
        b: 지수 (0 < b < 1)
        """
        return a * (x ** b)
    
    @staticmethod
    def logarithmic_growth(x, a, b):
        """
        로그 성장 모델 (초기 급성장, 빠른 포화)
        """
        return a * np.log(x + 1) + b
    
    @staticmethod
    def composite_growth(x, level_cap=20):
        """
        복합 성장 모델 (로빙 최적화)
        초반: 로그 성장
        중반: 선형 성장  
        후반: 역 지수 성장
        """
        if x <= 5:
            # 초반: 빠른 성장으로 동기 부여
            return 20 * np.log(x + 1)
        elif x <= 15:
            # 중반: 안정적 선형 성장
            return 35 + (x - 5) * 8
        else:
            # 후반: 점진적 둔화
            return 115 + 20 * (1 - np.exp(-0.5 * (x - 15)))
```

### 스탯별 성장 곡선

```python
class StatGrowthCurves:
    """
    각 스탯의 고유한 성장 특성 모델링
    """
    def __init__(self):
        self.stat_models = {
            "memory": self.memory_growth,
            "compute": self.compute_growth,
            "empathy": self.empathy_growth,
            "leadership": self.leadership_growth,
            "ethics": self.ethics_growth
        }
    
    def memory_growth(self, base_value: int, experience: int, interactions: int):
        """
        기억력: 사용 빈도에 따라 성장
        """
        usage_factor = np.log(interactions + 1) / 10
        experience_factor = np.sqrt(experience) / 100
        
        growth = base_value * (1 + usage_factor + experience_factor)
        return min(growth, 105)  # 상한선
    
    def compute_growth(self, base_value: int, complexity_score: float, success_rate: float):
        """
        연산력: 복잡한 작업 성공 시 성장
        """
        challenge_factor = complexity_score * success_rate
        growth_rate = 0.1 * challenge_factor
        
        growth = base_value * (1 + growth_rate)
        return min(growth, 105)
    
    def empathy_growth(self, base_value: int, emotional_interactions: int, feedback_sentiment: float):
        """
        공감력: 감정적 상호작용과 피드백 품질에 의존
        """
        interaction_factor = np.tanh(emotional_interactions / 100)
        sentiment_factor = (feedback_sentiment + 1) / 2  # -1~1 을 0~1로 정규화
        
        growth = base_value + (interaction_factor * sentiment_factor * 10)
        return min(growth, 105)
```

## 경험 포인트 시스템

### 다차원 경험치 모델

```python
class MultiDimensionalExperience:
    """
    단일 경험치가 아닌 다차원 경험 추적
    """
    def __init__(self):
        self.experience_dimensions = {
            "task_completion": 0,
            "creative_solutions": 0,
            "social_interaction": 0,
            "learning_new_skills": 0,
            "helping_others": 0,
            "problem_solving": 0
        }
        
    def calculate_weighted_experience(self, activity: dict):
        """
        활동 유형에 따른 가중 경험치 계산
        """
        weights = {
            "routine_task": {
                "task_completion": 1.0,
                "problem_solving": 0.2
            },
            "creative_work": {
                "creative_solutions": 1.5,
                "learning_new_skills": 0.8
            },
            "collaboration": {
                "social_interaction": 1.2,
                "helping_others": 1.0
            }
        }
        
        activity_type = activity.get('type', 'routine_task')
        base_exp = activity.get('base_experience', 10)
        
        # 각 차원별 경험치 분배
        distribution = weights.get(activity_type, {})
        
        for dimension, weight in distribution.items():
            self.experience_dimensions[dimension] += base_exp * weight
        
        return self.experience_dimensions
```

### 경험치 변환 메커니즘

```python
class ExperienceConverter:
    """
    누적 경험을 실제 성장으로 변환
    """
    def __init__(self):
        self.conversion_rates = {
            "memory": 0.8,      # 경험이 기억력으로 변환되는 비율
            "compute": 0.6,     # 계산 능력은 더 어려움
            "empathy": 1.0,     # 감정 경험은 직접 변환
            "leadership": 0.4,  # 리더십은 가장 어려움
            "ethics": 0.7       # 윤리적 판단력
        }
        
    def convert_experience_to_stats(self, experience_pool: dict, current_stats: dict):
        """
        경험 풀에서 스탯으로 변환
        """
        stat_gains = {}
        
        # 경험 유형과 스탯 매핑
        mapping = {
            "task_completion": ["compute", "memory"],
            "creative_solutions": ["compute", "empathy"],
            "social_interaction": ["empathy", "leadership"],
            "learning_new_skills": ["memory", "compute"],
            "helping_others": ["empathy", "ethics"],
            "problem_solving": ["compute", "leadership"]
        }
        
        # 각 경험 차원을 해당 스탯으로 변환
        for exp_type, exp_value in experience_pool.items():
            affected_stats = mapping.get(exp_type, [])
            
            for stat in affected_stats:
                conversion_rate = self.conversion_rates[stat]
                gain = (exp_value / 100) * conversion_rate
                
                stat_gains[stat] = stat_gains.get(stat, 0) + gain
        
        # 현재 스탯에 적용 (감소하는 한계 효용)
        updated_stats = {}
        for stat, current_value in current_stats.items():
            gain = stat_gains.get(stat, 0)
            
            # 높은 스탯일수록 성장 둔화
            diminishing_factor = 1 - (current_value / 105) ** 2
            actual_gain = gain * diminishing_factor
            
            updated_stats[stat] = min(current_value + actual_gain, 105)
        
        return updated_stats
```

## 성장 이벤트와 브레이크스루

### 성장 이벤트 시스템

```python
class GrowthEvents:
    """
    특별한 성장 이벤트와 브레이크스루 모멘트
    """
    def __init__(self):
        self.event_triggers = {
            "first_mastery": self.trigger_first_mastery,
            "synergy_discovery": self.trigger_synergy,
            "eureka_moment": self.trigger_eureka,
            "plateau_breakthrough": self.trigger_breakthrough
        }
        
    def check_growth_events(self, robeing_state: dict, history: list):
        """
        현재 상태와 이력을 분석해 특별 이벤트 감지
        """
        triggered_events = []
        
        # 첫 번째 스탯 마스터리 (80+ 도달)
        for stat, value in robeing_state['stats'].items():
            if value >= 80 and not self.has_triggered('first_mastery', stat):
                triggered_events.append({
                    "type": "first_mastery",
                    "stat": stat,
                    "bonus": {"all_stats": 5, "confidence": 10}
                })
        
        # 시너지 발견 (두 스탯이 함께 높을 때)
        stat_pairs = [
            ("memory", "compute"),
            ("empathy", "ethics"),
            ("compute", "leadership")
        ]
        
        for stat1, stat2 in stat_pairs:
            if (robeing_state['stats'][stat1] >= 60 and 
                robeing_state['stats'][stat2] >= 60):
                triggered_events.append({
                    "type": "synergy_discovery",
                    "stats": [stat1, stat2],
                    "unlock": f"advanced_{stat1}_{stat2}_skill"
                })
        
        return triggered_events
    
    def trigger_eureka(self, context: dict):
        """
        유레카 모멘트: 갑작스러운 깨달음
        """
        return {
            "type": "eureka",
            "description": "갑작스러운 통찰력이 생겼습니다!",
            "effects": {
                "temporary_boost": {
                    "compute": 20,
                    "duration": "24 hours"
                },
                "permanent_gain": {
                    "experience_multiplier": 1.5,
                    "duration": "1 week"
                }
            }
        }
```

### 정체 극복 메커니즘

```python
class PlateauBreakthrough:
    """
    성장 정체기 감지 및 극복
    """
    def __init__(self):
        self.plateau_threshold = 0.01  # 1% 미만 성장
        self.plateau_duration = 7       # 7일 이상 지속
        
    def detect_plateau(self, growth_history: list):
        """
        성장 정체기 감지
        """
        recent_growth = growth_history[-self.plateau_duration:]
        
        if len(recent_growth) < self.plateau_duration:
            return None
        
        # 각 스탯별 성장률 계산
        growth_rates = {}
        for stat in ['memory', 'compute', 'empathy', 'leadership', 'ethics']:
            initial = recent_growth[0]['stats'][stat]
            final = recent_growth[-1]['stats'][stat]
            
            growth_rate = (final - initial) / initial if initial > 0 else 0
            growth_rates[stat] = growth_rate
        
        # 정체된 스탯 식별
        plateaued_stats = [
            stat for stat, rate in growth_rates.items() 
            if rate < self.plateau_threshold
        ]
        
        if plateaued_stats:
            return {
                "plateaued_stats": plateaued_stats,
                "duration": self.plateau_duration,
                "suggested_activities": self.suggest_breakthrough_activities(plateaued_stats)
            }
        
        return None
    
    def suggest_breakthrough_activities(self, plateaued_stats: list):
        """
        정체 극복을 위한 활동 제안
        """
        breakthrough_activities = {
            "memory": [
                "새로운 분야의 지식 학습",
                "복잡한 정보 체계화 작업",
                "장기 프로젝트 기록 관리"
            ],
            "compute": [
                "알고리즘 문제 해결",
                "대규모 데이터 분석",
                "복잡한 시뮬레이션 실행"
            ],
            "empathy": [
                "감정적 대화 참여",
                "사용자 피드백 심층 분석",
                "다양한 관점 이해 연습"
            ],
            "leadership": [
                "프로젝트 계획 수립",
                "우선순위 결정 작업",
                "팀 조율 시뮬레이션"
            ],
            "ethics": [
                "윤리적 딜레마 분석",
                "가치 판단 연습",
                "결과 예측 시나리오 작성"
            ]
        }
        
        activities = []
        for stat in plateaued_stats:
            activities.extend(breakthrough_activities.get(stat, []))
        
        return activities
```

## 시각화와 피드백

### 성장 곡선 시각화

```python
import matplotlib.pyplot as plt
import seaborn as sns

class GrowthVisualization:
    """
    성장 곡선과 진행 상황 시각화
    """
    def __init__(self):
        self.style_config = {
            'figure.figsize': (12, 8),
            'axes.titlesize': 16,
            'axes.labelsize': 14,
            'xtick.labelsize': 12,
            'ytick.labelsize': 12
        }
        plt.rcParams.update(self.style_config)
        
    def plot_growth_curve(self, robeing_id: str, history: list):
        """
        전체 성장 곡선 플롯
        """
        fig, axes = plt.subplots(2, 3, figsize=(15, 10))
        axes = axes.flatten()
        
        stats = ['memory', 'compute', 'empathy', 'leadership', 'ethics', 'total']
        colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#6C5CE7']
        
        for idx, stat in enumerate(stats):
            ax = axes[idx]
            
            if stat == 'total':
                # 전체 레벨 진행
                levels = [h['level'] for h in history]
                dates = [h['timestamp'] for h in history]
                ax.plot(dates, levels, color=colors[idx], linewidth=2)
                ax.fill_between(dates, 0, levels, alpha=0.3, color=colors[idx])
                ax.set_title('Overall Level Progress')
                ax.set_ylabel('Level')
            else:
                # 개별 스탯 성장
                values = [h['stats'][stat] for h in history]
                dates = [h['timestamp'] for h in history]
                
                # 실제 성장 곡선
                ax.plot(dates, values, color=colors[idx], linewidth=2, label='Actual')
                
                # 이상적 성장 곡선 (참고용)
                ideal_values = [self.ideal_growth(i, stat) for i in range(len(history))]
                ax.plot(dates, ideal_values, '--', color='gray', alpha=0.5, label='Ideal')
                
                ax.fill_between(dates, 0, values, alpha=0.3, color=colors[idx])
                ax.set_title(f'{stat.capitalize()} Growth')
                ax.set_ylabel('Stat Value')
                ax.legend()
            
            ax.set_xlabel('Date')
            ax.grid(True, alpha=0.3)
            
        plt.tight_layout()
        return fig
    
    def generate_growth_report_visual(self, robeing_state: dict):
        """
        현재 상태 레이더 차트
        """
        fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(projection='polar'))
        
        # 스탯 데이터 준비
        stats = ['Memory', 'Compute', 'Empathy', 'Leadership', 'Ethics']
        values = [
            robeing_state['stats']['memory'],
            robeing_state['stats']['compute'],
            robeing_state['stats']['empathy'],
            robeing_state['stats']['leadership'],
            robeing_state['stats']['ethics']
        ]
        
        # 각도 계산
        angles = np.linspace(0, 2 * np.pi, len(stats), endpoint=False).tolist()
        values += values[:1]  # 원을 닫기 위해
        angles += angles[:1]
        
        # 플롯
        ax.plot(angles, values, 'o-', linewidth=2, color='#6C5CE7')
        ax.fill(angles, values, alpha=0.25, color='#6C5CE7')
        
        # 최대값 표시
        ax.plot(angles, [105] * len(angles), '--', color='gray', alpha=0.5)
        
        # 라벨
        ax.set_xticks(angles[:-1])
        ax.set_xticklabels(stats)
        ax.set_ylim(0, 105)
        
        # 제목
        ax.set_title(f"Level {robeing_state['level']} Robeing Stats", size=20, y=1.1)
        
        return fig
```

## 적응형 난이도 조정

### 동적 난이도 시스템

```python
class AdaptiveDifficulty:
    """
    사용자 실력에 맞춘 동적 난이도 조정
    """
    def __init__(self):
        self.performance_window = 20  # 최근 20개 작업 분석
        self.optimal_success_rate = 0.7  # 목표 성공률 70%
        
    def calculate_difficulty_adjustment(self, recent_tasks: list):
        """
        최근 수행 기록을 바탕으로 난이도 조정 계수 계산
        """
        if len(recent_tasks) < 5:
            return 1.0  # 데이터 부족 시 기본값
        
        # 성공률 계산
        success_count = sum(1 for task in recent_tasks if task['success'])
        success_rate = success_count / len(recent_tasks)
        
        # 평균 수행 시간 대비 실제 시간
        avg_expected_time = np.mean([task['expected_time'] for task in recent_tasks])
        avg_actual_time = np.mean([task['actual_time'] for task in recent_tasks])
        time_efficiency = avg_expected_time / avg_actual_time if avg_actual_time > 0 else 1
        
        # 난이도 조정 계산
        if success_rate > 0.85 and time_efficiency > 1.2:
            # 너무 쉬움 - 난이도 상승
            adjustment = 1.2
        elif success_rate < 0.5 or time_efficiency < 0.7:
            # 너무 어려움 - 난이도 하락  
            adjustment = 0.8
        else:
            # 적절한 수준 - 미세 조정
            adjustment = 1.0 + (success_rate - self.optimal_success_rate) * 0.5
        
        return np.clip(adjustment, 0.5, 1.5)  # 극단적 조정 방지
```

## 성장 예측 모델

### 머신러닝 기반 성장 예측

```python
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler

class GrowthPredictor:
    """
    과거 데이터를 기반으로 미래 성장 예측
    """
    def __init__(self):
        self.model = RandomForestRegressor(n_estimators=100, random_state=42)
        self.scaler = StandardScaler()
        self.feature_names = [
            'current_level', 'total_exp', 'days_active',
            'avg_daily_interactions', 'success_rate',
            'feedback_sentiment', 'skill_diversity'
        ]
        
    def prepare_features(self, robeing_data: dict):
        """
        예측을 위한 특징 추출
        """
        features = [
            robeing_data['level'],
            robeing_data['total_exp'],
            robeing_data['days_active'],
            robeing_data['avg_daily_interactions'],
            robeing_data['metrics']['success_rate'],
            robeing_data['metrics']['avg_feedback_sentiment'],
            len(robeing_data['unlocked_skills'])
        ]
        
        return np.array(features).reshape(1, -1)
    
    def predict_growth_timeline(self, current_state: dict, target_level: int):
        """
        목표 레벨 도달 예상 시간 예측
        """
        # 현재 특징 추출
        current_features = self.prepare_features(current_state)
        
        # 일일 성장률 예측
        daily_growth_rate = self.model.predict(current_features)[0]
        
        # 필요한 경험치 계산
        current_exp = current_state['total_exp']
        target_exp = self.calculate_total_exp_for_level(target_level)
        required_exp = target_exp - current_exp
        
        # 예상 소요 일수
        estimated_days = required_exp / (daily_growth_rate * current_state['avg_daily_interactions'])
        
        # 신뢰 구간 계산
        predictions = []
        for tree in self.model.estimators_:
            pred = tree.predict(current_features)[0]
            days = required_exp / (pred * current_state['avg_daily_interactions'])
            predictions.append(days)
        
        confidence_interval = (
            np.percentile(predictions, 25),
            np.percentile(predictions, 75)
        )
        
        return {
            "estimated_days": int(estimated_days),
            "confidence_interval": confidence_interval,
            "recommended_daily_interactions": self.calculate_optimal_interactions(
                estimated_days,
                current_state['avg_daily_interactions']
            )
        }
```

## 성과 측정과 최적화

### KPI 추적 시스템

```python
class GrowthKPITracker:
    """
    성장 관련 핵심 성과 지표 추적
    """
    def __init__(self):
        self.kpis = {
            "growth_velocity": self.calculate_growth_velocity,
            "engagement_score": self.calculate_engagement,
            "skill_acquisition_rate": self.calculate_skill_rate,
            "user_satisfaction_correlation": self.calculate_satisfaction_correlation
        }
        
    def generate_kpi_dashboard(self, robeing_id: str, period: str = "monthly"):
        """
        KPI 대시보드 생성
        """
        dashboard = {
            "period": period,
            "metrics": {}
        }
        
        for kpi_name, calculator in self.kpis.items():
            value = calculator(robeing_id, period)
            benchmark = self.get_benchmark(kpi_name)
            
            dashboard["metrics"][kpi_name] = {
                "value": value,
                "benchmark": benchmark,
                "performance": "above" if value > benchmark else "below",
                "trend": self.calculate_trend(robeing_id, kpi_name)
            }
        
        dashboard["recommendations"] = self.generate_recommendations(dashboard["metrics"])
        
        return dashboard
```

## 결론

경험 기반 성장 곡선은 로빙이 각 사용자에게 최적화된 속도로 성장할 수 있게 하는 핵심 메커니즘입니다. 학습 심리학, 게임 디자인, 그리고 데이터 과학을 결합하여 지속 가능하고 의미 있는 성장을 보장합니다.