Spaces:
Running
Running
File size: 8,537 Bytes
ef82d45 0482473 ef82d45 0482473 ef82d45 0482473 ef82d45 0482473 ef82d45 0482473 ef82d45 96692cf 0482473 785b76a 0482473 785b76a 0482473 785b76a ef82d45 0482473 785b76a 0482473 785b76a 0482473 785b76a 0482473 96692cf 0482473 785b76a ef82d45 0482473 785b76a 0482473 ef82d45 785b76a 96692cf 785b76a 96692cf 785b76a 0482473 785b76a 0482473 96692cf 0482473 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# κ°μ -νλ μ°λ λ§€ν λ° νλ μμ±
# portfolio/npc_social_network/npc/npc_behavior.py
from .emotion_config import EMOTION_CATEGORY_MAP
class BehaviorManager:
def __init__(self):
self.mapping = {
# Core (κΈ°λ³Έ κ°μ )
"joy": "jump", # κΈ°μ¨ : μ ν λ°λ€
"sadness": "sit_down", # μ¬ν : μ£Όμ μλ€
"anger": "shout", # λΆλ
Έ : μ리μΉλ€
"fear": "run_away", # κ³΅ν¬ : λλ§μΉλ€
"disgust": "avoid", # νμ€ : νΌνλ€
"surprise": "gasp", # λλ : κ°ννλ©° μ¨μ λ€μ΄μΌ
"neutral": "idle", # μ€λ¦½ : μ무κ²λ νμ§ μμ
# Social (μ¬νμ κ°μ )
"gratitude": "thank", # κ°μ¬ : κ°μ¬νλ€
"shame": "hide_face", # μμΉμ¬ : μΌκ΅΄μ κ°μΆλ€
"guilt": "apologize", # μ£μ±
κ° : λ―Έμνλ€κ³ λ§ν¨
"pride": "show_off", # μλΆμ¬ : μλνλ€
"jealousy": "glare", # μ§ν¬ : λ
Έλ €λ³΄λ€
"compassion": "console", # μ°λ―Ό/λμ : μλ‘νλ€
"love": "embrace", # μ¬λ/μ μ : ν¬μΉνλ€
"admiration": "cheer", # μ‘΄κ²½/κ°ν : ννΈνλ€
"empathy": "listen_carefully", # κ³΅κ° : μ§μ€νλ€
"awe": "gasp", # κ²½μΈμ¬ : κ°ννλ©° μ¨μ λ€μ΄μΌ
"attachment": "hold_hands", # μ μ°© : μμ νλ€
"comfort": "pat", # μλ‘ μΆκ΅¬ : ν λ₯거리λ€
# Cognitive (μΈμ§μ μν)
"anticipation": "prepare", # κΈ°λ : μ€λΉνλ€
"curiosity": "inspect", # νΈκΈ°μ¬ : μ΄ν΄λ³΄λ€
"confusion": "scratch_head", # νΌλ : 머리λ₯Ό κΈλ€
"interest": "lean_forward", # ν₯λ―Έ : μ§μ€νλ€
"engagement": "focus", # λͺ°μ
: μ§μ€νλ€
"boredom": "idle", # μ§λ£¨ν¨ : μ무κ²λ νμ§ μμ
"relief": "exhale", # μλ : μ¨μ λ΄μ¬λ€
"anxiety": "fidget", # λΆμ/κΈ΄μ₯ : μμ λΆμ λͺ»νλ€
"calm": "relax", # νμ¨ : μ§μ νλ€
"skepticism": "raise_eyebrow", # νμ : λμΉμ μ¬λ¦¬λ€
# Complex (λ³΅ν© κ°μ )
"nostalgia": "stare_into_distance", # ν₯μ
"bittersweet": "smile_then_look_down", # λ¬μ½€μμΈλ¦ν¨
"schadenfreude": "smirk", # λ¨μ λΆνμμ λλΌλ κΈ°μ¨
"hope": "brighten_up", # ν¬λ§
"resentment": "scowl", # λΆκ°
"anticipatory_joy": "rub_hands", # κΈ°λ μμ κΈ°μ¨
"regret": "look_down", # νν
"rumination": "mutter_to_self", # λ°μΆ
"groundedness": "steady_posture", # μμ κ°
}
# νλμ λ°λ₯Έ κ°μ (μλ§€ν)
self.action_to_emotion = {v: k for k, v in self.mapping.items()}
# Layer μ°μ μμ / weight μ€μ (νλ κ°λ₯)
self.layer_priority = ["core", "social", "cognitive", "complex"]
self.layer_weights = {
"core" : 1.0,
"social" : 0.8,
"cognitive" : 0.6,
"complex" : 0.4,
}
def get_layer_dominant_emotions(self, buffer):
"""
layerλ³ dominant emotion κ³μ°
"""
layer_emotions = {layer: [] for layer in self.layer_priority}
for emo, val in buffer.items():
if val > 0:
layer = EMOTION_CATEGORY_MAP.get(emo)
if layer:
layer_emotions[layer].append((emo, val))
# κ° layerμμ κ°μ₯ κ°ν κ°μ μΆμΆ
layer_dominant = {}
for layer, emos in layer_emotions.items():
if emos:
dominant_emo = max(emos, key=lambda x: x[1])
layer_dominant[layer] = dominant_emo
return layer_dominant
def decide_layered_sequence(self, layer_dominant_emotions):
"""
layer priority + weight κΈ°λ° μνμ€ μμ±
"""
sequence = []
for layer in self.layer_priority:
if layer in layer_dominant_emotions:
emo, score = layer_dominant_emotions[layer]
weighted_score = round(score * self.layer_weights[layer], 2)
action = self.mapping.get(emo)
if action:
sequence.append((action, weighted_score))
return sequence
def perform_sequence(self, name, job, emotion_buffer, return_trace=False):
"""
Layer-aware Behavior μνμ€ κ΅¬μ± + Behavior Trace λ°ν
"""
layer_dominant_emotions = self.get_layer_dominant_emotions(emotion_buffer)
sequence = self.decide_layered_sequence(layer_dominant_emotions)
if not sequence:
behavior_output = f"{name}μ(λ) νΉλ³ν νλμ νμ§ μμ΅λλ€."
if return_trace:
return behavior_output, []
else:
return behavior_output
# νλ ν
μ€νΈ ν
νλ¦Ώ
behavior_lines = {
# Core
"jump": "κΈ°λ»μ κΉ‘μΆ© λλλ€.",
"sit_down": "μ¬νΌμ μ£Όμ μμ΅λλ€....",
"shout": "νκ° λμ μ리λ₯Ό μ§λ¦
λλ€!",
"run_away": "무μμ λλ§κ°λλ€!",
"avoid": "λ€λ‘ λ¬Όλ¬μ νΌνλ € ν©λλ€.",
"gasp": "κΉμ§ λλλλ€.",
"idle": "κ°λ§ν μμ΅λλ€.",
# Social
"thank": "κ°μ¬ν λ§μμ ννν©λλ€.",
"hide_face": "μμΉμ¬μ μΌκ΅΄μ κ°λ¦½λλ€.",
"apologize": "λ―Έμνλ€κ³ λ§ν©λλ€.",
"show_off": "μλμ€λ¬μ΄ λͺ¨μ΅μ 보μ¬μ€λλ€.",
"glare": "μλλ₯Ό λ
Έλ €λ΄
λλ€.",
"console": "μλλ°©μ λ°λ»νκ² μλ‘ν©λλ€.",
"embrace": "μλλ₯Ό ν¬μΉν©λλ€.",
"cheer": "κ°ννλ©° μμν©λλ€.",
"listen_carefully": "μλμ λ§μ μ§μ€ν΄μ λ£μ΅λλ€.",
"hold_hands": "μμ μ‘μ΅λλ€.",
"pat": "κ°λ³κ² λ±μ λλλ € μλ‘ν©λλ€.",
# Cognitive
"prepare": "무μΈκ°λ₯Ό μ€λΉν©λλ€.",
"inspect": "μ μ¬ν κ΄μ°°ν©λλ€.",
"scratch_head": "머리λ₯Ό κΈμ μ
λλ€.",
"lean_forward": "μμΌλ‘ μμ΄λ©° μ§μ€ν©λλ€.",
"focus": "λͺ°μ
νμ¬ μ§μ€ν©λλ€.",
"exhale": "μλνλ©° μ¨μ μ½λλ€.",
"fidget": "λΆμνκ² λͺΈμ μμ§μ
λλ€.",
"relax": "νμ¨νκ² ν΄μν©λλ€.",
"raise_eyebrow": "μμ¬μ€λ½κ² λμΉμ μΉμΌλΉλλ€.",
# Complex
"stare_into_distance": "λ¨Ό κ³³μ λ°λΌλ³΄λ©° νμμ μ κΉλλ€.",
"smile_then_look_down": "λ―Έμλ₯Ό μ§λ€κ° κ³ κ°λ₯Ό μμ
λλ€.",
"smirk": "λΉμλ νμ μ μ§μ΅λλ€.",
"brighten_up": "κΈ°λκ°μ λλΉμ΄ λΉλ©λλ€.",
"scowl": "μΈμμ μ°νΈλ¦½λλ€.",
"rub_hands": "λ€λ¬ λ§μμ μμ λΉλΉλλ€.",
"look_down": "κ³ κ°λ₯Ό μμ΄λ©° ννν©λλ€.",
"mutter_to_self": "νΌμ£λ§μ μ€μΌκ±°λ¦½λλ€.",
"steady_posture": "μμ λ μμΈλ₯Ό μ μ§ν©λλ€.",
}
# νλ λ¬Έμ₯ μμ±
lines = []
trace_pairs = []
for action, score in sequence:
msg = behavior_lines.get(action, f"{action} νλμ ν©λλ€.")
lines.append(f"({round(score,1)}) {msg}")
trace_pairs.append((action, round(score, 1)))
# μ§μ
λΌμΈ μΆκ°
job_line = {
"farmer": "λ°μΌλ ν΄μΌ νκ² κ΅°μ.",
"blacksmith": "λμ₯κ° λΆλ μ§ν΄μΌμ£ .",
}.get(job, "μ€λλ λ°μ ν루λ€μ.")
behavior_output = f"{name} νλ μνμ€: \n" + "\n".join(lines) + f"\n{job_line}"
# μ΅μ’
μΆλ ₯ λ¬Έμ₯
if return_trace:
return behavior_output, trace_pairs
else:
return behavior_output |