rorshi's picture
μ—λŸ¬ λ°œμƒμœΌλ‘œ μ‹€ν–‰ λΆˆκ°€
6fe0d0c
# 감정 μƒνƒœ, 감정 μ—…λ°μ΄νŠΈ, decay 처리
# portfolio/npc_social_network/npc/npc_emotion.py
from .emotion_config import EMOTION_LIST, EMOTION_DECAY_RATE, EMOTION_CATEGORY_MAP
class EmotionManager:
def __init__(self, decay_rate, personality=None, initial_baseline=None):
# λ‚΄λΆ€: float 감정 수치 κ΄€λ¦¬μš© 버퍼
self._emotion_buffer = {emo: 0.0 for emo in EMOTION_LIST}
# baseline 버퍼 μΆ”κ°€
self._baseline_buffer = initial_baseline or {emo: 0.0 for emo in EMOTION_LIST}
# 감정별 회볡 속도 (ms λ‹¨μœ„κ°€ μ•„λ‹Œ λ‹¨μœ„λ‹Ή κ°μ†Œ 속도)
self.decay_rate = decay_rate
self.personality = personality or {}
def update_emotion(self, emotion: str, strength: float = 1.0, context: str = "general"):
"""
νŠΉμ • 감정을 감정 μƒνƒœμ— 반영 (μΉ΄ν…Œκ³ λ¦¬ 기반)
"""
if emotion not in self._emotion_buffer:
print(f"[κ²½κ³ ] '{emotion}'은(λŠ”) μ •μ˜λœ 감정이 μ•„λ‹™λ‹ˆλ‹€.")
return
# κ°œμ„± κ³„μˆ˜ 반영
multiplier = self.personality.get("sensitive", 1.0)
category = EMOTION_CATEGORY_MAP.get(emotion, None)
if category == "core":
multiplier *= self.personality.get("affect_bias", 1.0)
elif category == "social":
# μ‚¬νšŒμ  감정은 social contextμ—μ„œλ§Œ 반영
if context != "social":
return # λ¬΄μ‹œ
multiplier *= self.personality.get("social_bias", 1.0)
elif category == "cognitive":
multiplier *= self.personality.get("cognitive_bias", 1.0)
elif category == "complex":
multiplier *= self.personality.get("complex_bias", 1.0)
# 감정 반영
self._emotion_buffer[emotion] += strength * multiplier
# clip 적용 (μ΅œλŒ€ 100)
self._emotion_buffer[emotion] = min(max(0.0, self._emotion_buffer[emotion]), 100.0)
def decay_emotions(self):
"""
μ‹œκ°„μ΄ 지남에 따라 λͺ¨λ“  감정이 μ„œμ„œνžˆ κ°μ†Œ
"""
for emotion in EMOTION_LIST:
rate = self.decay_rate.get(emotion, 0.5)
modifier = 1.0 - self.personality.get("stoic", 0.0)
self._emotion_buffer[emotion] = max(0.0, self._emotion_buffer[emotion] - rate * modifier)
def get_state(self):
"""
감정 μƒνƒœ λ°˜ν™˜ (좜λ ₯용, μ •μˆ˜λ‘œ λ³€ν™˜)
"""
return {emo: int(self._emotion_buffer[emo]) for emo in EMOTION_LIST}
def get_dominant_emotion(self, layer: str = None):
"""
ν˜„μž¬ κ°€μž₯ κ°•ν•œ 감정 λ°˜ν™˜ (전체 감정 쀑 μ΅œλŒ€κ°’ 1개)
"""
if layer:
# νŠΉμ • layer λŒ€μƒ
layer_emotions = [emo for emo, cat in EMOTION_CATEGORY_MAP.items() if cat == layer]
if not layer_emotions:
return None
dominant_emo, score = max(
((emo, self._emotion_buffer[emo]) for emo in layer_emotions),
key=lambda x: x[1],
default=(None, 0.0)
)
if score == 0.0:
return None
return dominant_emo
else:
# 전체 λŒ€μƒ
dominant_emo, score = max(self._emotion_buffer.items(), key=lambda x:x[1])
if score == 0.0:
return None
return dominant_emo
def get_buffer(self):
"""
emotion_buffer 볡사본 λ°˜ν™˜
"""
return self._emotion_buffer.copy()
def get_current_emotions_state(self):
"""
ν˜„μž¬ 감정 μƒνƒœ λ°˜ν™˜ (dict)
"""
return self._emotion_buffer
def get_top_emotions(self, top_n=5):
"""
ν˜„μž¬ 감정 λ²„νΌμ—μ„œ μƒμœ„ N개 감정 λ°˜ν™˜
:return: List of (emotion_name, value) tuples
"""
# μ •λ ¬ ν›„ μƒμœ„ N개 λ°˜ν™˜
sorted_emotions = sorted(self._emotion_buffer.items(), key=lambda x: x[1], reverse=True)
top_emotions = sorted_emotions[:top_n]
return top_emotions
def set_baseline(self, baseline_buffer):
"""
baseline bufferλ₯Ό μ™ΈλΆ€μ—μ„œ μ„€μ • (npc_base.py μ΄ˆκΈ°ν™” μ‹œ μ‚¬μš©)
"""
self._baseline_buffer = baseline_buffer.copy()