Spaces:
Running
Running
Complete step 9: 감정 행동 시퀀스 구성
Browse files- npc_social_network/npc/emotion_config.py +11 -11
- npc_social_network/npc/npc_base.py +44 -16
- npc_social_network/npc/npc_behavior.py +45 -13
- test.ipynb +47 -2
npc_social_network/npc/emotion_config.py
CHANGED
@@ -46,13 +46,13 @@ EMOTION_STATE_TEMPLATE = {
|
|
46 |
# 감정별 회복 속도 (ms 단위가 아닌 단위당 감소 속도)
|
47 |
EMOTION_DECAY_RATE = {
|
48 |
# 기본 정서 (긍정)
|
49 |
-
"joy":
|
50 |
-
"satisfaction":
|
51 |
-
"gratitude":
|
52 |
-
"calm":
|
53 |
-
"anticipation":
|
54 |
-
"pride":
|
55 |
-
"connectedness":
|
56 |
|
57 |
# 기본 정서 (부정) - 느림
|
58 |
"sadness": 0.2, # 슬픔
|
@@ -67,16 +67,16 @@ EMOTION_DECAY_RATE = {
|
|
67 |
"jealousy": 0.4, # 질투
|
68 |
"shame": 0.4, # 수치심
|
69 |
"guilt": 0.4, # 죄책감
|
70 |
-
"compassion":
|
71 |
-
"awe":
|
72 |
"empathy": 1, # 공감
|
73 |
|
74 |
# 인지적 상태
|
75 |
"confusion": 0.8, # 혼란
|
76 |
"nervousness": 0.7, # 긴장
|
77 |
"apathy": 0.4, # 무관심
|
78 |
-
"excitement":
|
79 |
-
"immersion":
|
80 |
"skepticism": 0.5, # 회의
|
81 |
}
|
82 |
|
|
|
46 |
# 감정별 회복 속도 (ms 단위가 아닌 단위당 감소 속도)
|
47 |
EMOTION_DECAY_RATE = {
|
48 |
# 기본 정서 (긍정)
|
49 |
+
"joy": 0.7, # 기쁨
|
50 |
+
"satisfaction": 0.8, # 만족
|
51 |
+
"gratitude": 0.4, # 감사
|
52 |
+
"calm": 0.2, # 평온
|
53 |
+
"anticipation": 0.6, # 기대
|
54 |
+
"pride": 0.8, # 자부심
|
55 |
+
"connectedness": 0.5, # 유대감
|
56 |
|
57 |
# 기본 정서 (부정) - 느림
|
58 |
"sadness": 0.2, # 슬픔
|
|
|
67 |
"jealousy": 0.4, # 질투
|
68 |
"shame": 0.4, # 수치심
|
69 |
"guilt": 0.4, # 죄책감
|
70 |
+
"compassion": 0.8, # 동정심
|
71 |
+
"awe": 0.8, # 경외심
|
72 |
"empathy": 1, # 공감
|
73 |
|
74 |
# 인지적 상태
|
75 |
"confusion": 0.8, # 혼란
|
76 |
"nervousness": 0.7, # 긴장
|
77 |
"apathy": 0.4, # 무관심
|
78 |
+
"excitement": 0.9, # 흥분
|
79 |
+
"immersion": 0.6, # 몰입
|
80 |
"skepticism": 0.5, # 회의
|
81 |
}
|
82 |
|
npc_social_network/npc/npc_base.py
CHANGED
@@ -42,54 +42,74 @@ class NPC:
|
|
42 |
# self.emotion = "neutral"
|
43 |
# self.personality = {"kind": 0.5, "lazy": 0.2} # 예시
|
44 |
|
45 |
-
# 이동
|
46 |
def move(self):
|
|
|
|
|
|
|
47 |
self.current_index = (self.current_index + 1) % len(self.path)
|
48 |
|
49 |
-
# 현재 위치 좌표 반환
|
50 |
def get_position(self):
|
|
|
|
|
|
|
51 |
return self.path[self.current_index]
|
52 |
|
53 |
-
# NPC 이미지 화면에 렌더링
|
54 |
def draw(self, screen, tile_size):
|
|
|
|
|
|
|
55 |
x, y = self.get_position()
|
56 |
screen.blit(self.image, (x * tile_size, y * tile_size))
|
57 |
|
58 |
-
# 감정 상태와 직업에 따른 대사 생성 (대표 감정 하나 반영)
|
59 |
def generate_dialogue(self):
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
62 |
|
63 |
-
# NPC가 새로운 기억을 저장하고 감정 상태에 반영
|
64 |
def remember(self, content: str, importance: int = 5, emotion: str = None, strength: float = 1.0):
|
|
|
|
|
|
|
65 |
memory = Memory(content=content, importance = importance, emotion=emotion or "neutral")
|
66 |
self.memory_store.add_memory(memory)
|
67 |
if emotion:
|
68 |
self.update_emotion(emotion, strength) # strength = importance / 5.0으로도 가능
|
69 |
|
70 |
-
# 특정 감정을 감정 상태에 반영
|
71 |
def update_emotion(self, emotion:str, strength: float = 1.0):
|
|
|
|
|
|
|
72 |
self.emotion.update_emotion(emotion, strength)
|
73 |
self._emotion_buffer = self.emotion.get_buffer()
|
74 |
|
75 |
-
# 시간이 지남에 따라 모든 감정이 서서히 감소
|
76 |
def decay_emotion(self):
|
|
|
|
|
|
|
77 |
self.emotion.decay_emotion()
|
78 |
self._emotion_buffer = self.emotion.get_buffer()
|
79 |
|
80 |
-
# 저장된 모든 기억(단기+장기)을 리스트로 반환
|
81 |
def recall(self):
|
|
|
|
|
|
|
82 |
return [m.content for m in self.memory_store.get_all_memories()]
|
83 |
|
84 |
-
# 복합 감정 계산 (상위 N개 감정 반환)
|
85 |
def get_composite_emotion_state(self, top_n: int = 3):
|
|
|
|
|
|
|
86 |
buffer = self.emotion.get_buffer() # EmotionManager에서 최신 감정 상태 복사본 가져오기
|
87 |
sorted_emotions = sorted(buffer.items(), key=lambda x: x[1], reverse=True)
|
88 |
composite = [(emo,round(score, 2)) for emo, score in sorted_emotions[:top_n] if score > 0]
|
89 |
return composite # 예 [('fear', 2.0), ('anger'), 1.5]
|
90 |
|
91 |
-
# 감정 상태 요약 텍스트 생성
|
92 |
def summarize_emotional_state(self):
|
|
|
|
|
|
|
93 |
buffer = self.emotion.get_buffer() # EmotionManager에서 최신 감정 상태 복사본 가져오기
|
94 |
nonzero = [v for v in buffer.values() if v > 0]
|
95 |
avg_strength = round(sum(nonzero) / len(nonzero), 2) if nonzero else 0.0
|
@@ -98,13 +118,17 @@ class NPC:
|
|
98 |
composite_str = ", ".join(f"{emo}({val})" for emo, val in composite)
|
99 |
return f"감정 평균 강도: {avg_strength} / 대표 감정: {composite_str if composite else '없음' }"
|
100 |
|
101 |
-
# 다른 NPC와 상호작용 시 감정에 따른 관계 변화를 반영
|
102 |
def interact_with(self, other_npc_name: str, emotion: str, positive: bool):
|
|
|
|
|
|
|
103 |
delta = self._get_emotion_influence(emotion, positive)
|
104 |
self.relationships.update_relationship(other_npc_name, delta)
|
105 |
|
106 |
-
# 감정과 상호작용의 긍/부정 여부에 따른 관계 변화량 결정
|
107 |
def _get_emotion_influence(self, emotion: str, positive: bool) -> float:
|
|
|
|
|
|
|
108 |
base = 5.0 # 기본 영향력
|
109 |
|
110 |
# 감정 종류별 base 수정
|
@@ -120,12 +144,16 @@ class NPC:
|
|
120 |
# 정의되지 않은 감정 처리
|
121 |
return 0.0
|
122 |
|
123 |
-
# 상대방과의 현재 관계 설명 반환
|
124 |
def get_relationship_description(self, other_npc_name: str) -> str:
|
|
|
|
|
|
|
125 |
return self.relationships.describe_relationship(other_npc_name)
|
126 |
|
127 |
-
# 기억이 관계에 미치는 영향 반영
|
128 |
def reflect_memory_on_relationship(self, other_npc_name:str):
|
|
|
|
|
|
|
129 |
# 최근 기억 + 최근 감정을 기반으로 관계 변화량 결정
|
130 |
memories = self.memory_store.get_all_memories()
|
131 |
dominant_emotion = self.emotion.get_dominant_emotion()
|
|
|
42 |
# self.emotion = "neutral"
|
43 |
# self.personality = {"kind": 0.5, "lazy": 0.2} # 예시
|
44 |
|
|
|
45 |
def move(self):
|
46 |
+
"""
|
47 |
+
이동
|
48 |
+
"""
|
49 |
self.current_index = (self.current_index + 1) % len(self.path)
|
50 |
|
|
|
51 |
def get_position(self):
|
52 |
+
"""
|
53 |
+
현재 위치 좌표 반환
|
54 |
+
"""
|
55 |
return self.path[self.current_index]
|
56 |
|
|
|
57 |
def draw(self, screen, tile_size):
|
58 |
+
"""
|
59 |
+
NPC 이미지 화면에 렌더링
|
60 |
+
"""
|
61 |
x, y = self.get_position()
|
62 |
screen.blit(self.image, (x * tile_size, y * tile_size))
|
63 |
|
|
|
64 |
def generate_dialogue(self):
|
65 |
+
"""
|
66 |
+
감정 상태와 직업에 따른 복합 행동 시퀀스 기반 대사 생성
|
67 |
+
"""
|
68 |
+
composite = self.get_composite_emotion_state(top_n=3) # 상위 3개 감정 사용
|
69 |
+
return self.behavior.perform_sequence(self.name, self.job, composite)
|
70 |
|
|
|
71 |
def remember(self, content: str, importance: int = 5, emotion: str = None, strength: float = 1.0):
|
72 |
+
"""
|
73 |
+
NPC가 새로운 기억을 저장하고 감정 상태에 반영
|
74 |
+
"""
|
75 |
memory = Memory(content=content, importance = importance, emotion=emotion or "neutral")
|
76 |
self.memory_store.add_memory(memory)
|
77 |
if emotion:
|
78 |
self.update_emotion(emotion, strength) # strength = importance / 5.0으로도 가능
|
79 |
|
|
|
80 |
def update_emotion(self, emotion:str, strength: float = 1.0):
|
81 |
+
"""
|
82 |
+
특정 감정을 감정 상태에 반영
|
83 |
+
"""
|
84 |
self.emotion.update_emotion(emotion, strength)
|
85 |
self._emotion_buffer = self.emotion.get_buffer()
|
86 |
|
|
|
87 |
def decay_emotion(self):
|
88 |
+
"""
|
89 |
+
시간이 지남에 따라 모든 감정이 서서히 감소
|
90 |
+
"""
|
91 |
self.emotion.decay_emotion()
|
92 |
self._emotion_buffer = self.emotion.get_buffer()
|
93 |
|
|
|
94 |
def recall(self):
|
95 |
+
"""
|
96 |
+
저장된 모든 기억(단기 + 장기)을 리스트로 반환
|
97 |
+
"""
|
98 |
return [m.content for m in self.memory_store.get_all_memories()]
|
99 |
|
|
|
100 |
def get_composite_emotion_state(self, top_n: int = 3):
|
101 |
+
"""
|
102 |
+
복합 감정 계산 (상위 N개 감정 반환)
|
103 |
+
"""
|
104 |
buffer = self.emotion.get_buffer() # EmotionManager에서 최신 감정 상태 복사본 가져오기
|
105 |
sorted_emotions = sorted(buffer.items(), key=lambda x: x[1], reverse=True)
|
106 |
composite = [(emo,round(score, 2)) for emo, score in sorted_emotions[:top_n] if score > 0]
|
107 |
return composite # 예 [('fear', 2.0), ('anger'), 1.5]
|
108 |
|
|
|
109 |
def summarize_emotional_state(self):
|
110 |
+
"""
|
111 |
+
감정 상태 요약 텍스트 생성
|
112 |
+
"""
|
113 |
buffer = self.emotion.get_buffer() # EmotionManager에서 최신 감정 상태 복사본 가져오기
|
114 |
nonzero = [v for v in buffer.values() if v > 0]
|
115 |
avg_strength = round(sum(nonzero) / len(nonzero), 2) if nonzero else 0.0
|
|
|
118 |
composite_str = ", ".join(f"{emo}({val})" for emo, val in composite)
|
119 |
return f"감정 평균 강도: {avg_strength} / 대표 감정: {composite_str if composite else '없음' }"
|
120 |
|
|
|
121 |
def interact_with(self, other_npc_name: str, emotion: str, positive: bool):
|
122 |
+
"""
|
123 |
+
다른 NPC와 상호작용 시 감정에 따른 관계 변화를 반영
|
124 |
+
"""
|
125 |
delta = self._get_emotion_influence(emotion, positive)
|
126 |
self.relationships.update_relationship(other_npc_name, delta)
|
127 |
|
|
|
128 |
def _get_emotion_influence(self, emotion: str, positive: bool) -> float:
|
129 |
+
"""
|
130 |
+
감정과 상호작용의 긍/부정 여부에 따른 관계 변화량 결정
|
131 |
+
"""
|
132 |
base = 5.0 # 기본 영향력
|
133 |
|
134 |
# 감정 종류별 base 수정
|
|
|
144 |
# 정의되지 않은 감정 처리
|
145 |
return 0.0
|
146 |
|
|
|
147 |
def get_relationship_description(self, other_npc_name: str) -> str:
|
148 |
+
"""
|
149 |
+
상대방과의 현재 관계 설명 반환
|
150 |
+
"""
|
151 |
return self.relationships.describe_relationship(other_npc_name)
|
152 |
|
|
|
153 |
def reflect_memory_on_relationship(self, other_npc_name:str):
|
154 |
+
"""
|
155 |
+
기억이 관계에 미치는 영향 반영
|
156 |
+
"""
|
157 |
# 최근 기억 + 최근 감정을 기반으로 관계 변화량 결정
|
158 |
memories = self.memory_store.get_all_memories()
|
159 |
dominant_emotion = self.emotion.get_dominant_emotion()
|
npc_social_network/npc/npc_behavior.py
CHANGED
@@ -39,19 +39,51 @@ class BehaviorManager:
|
|
39 |
"skepticism": "raise_eyebrow", # 회의 : 의심스러운 듯 눈썹을 찌푸림
|
40 |
}
|
41 |
|
42 |
-
def
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
-
def
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
behavior_lines = {
|
48 |
-
"jump": f"
|
49 |
-
"shout": f"
|
50 |
-
"run_away": f"
|
51 |
-
"sit_down": f"
|
52 |
-
"wave": f"
|
53 |
-
"sigh": f"
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
"skepticism": "raise_eyebrow", # 회의 : 의심스러운 듯 눈썹을 찌푸림
|
40 |
}
|
41 |
|
42 |
+
def decide_sequence(self, composite_emotions):
|
43 |
+
"""
|
44 |
+
복합 감정 상태(composite_emotions: [(emotions, score), ...])에 따른 행동 시퀀스 결정
|
45 |
+
"""
|
46 |
+
sequence = []
|
47 |
+
for emo, score in composite_emotions:
|
48 |
+
action = self.mapping.get(emo)
|
49 |
+
if action:
|
50 |
+
sequence.append((action, score)) # (행동, 감정 강도 형태로 저장)
|
51 |
+
return sequence
|
52 |
|
53 |
+
def perform_sequence(self, name, job, composite_emotion):
|
54 |
+
"""
|
55 |
+
행동 시퀀스를 텍스트로 구성하여 출력
|
56 |
+
"""
|
57 |
+
sequence = self.decide_sequence(composite_emotion)
|
58 |
+
if not sequence:
|
59 |
+
return f"{name}은(는) 특별한 행동을 하지 않습니다."
|
60 |
+
|
61 |
+
# 행동 텍스트 템플릿
|
62 |
behavior_lines = {
|
63 |
+
"jump": f"기뻐서 깡충 뜁니다.",
|
64 |
+
"shout": f"화가 나서 소리를 지릅니다!",
|
65 |
+
"run_away": f"무서워 도망갑니다!",
|
66 |
+
"sit_down": f"슬퍼서 주저앉습니다....",
|
67 |
+
"wave": f"손을 흔듭니다.",
|
68 |
+
"sigh": f"한숨을 쉽니다...",
|
69 |
+
"thank": f"감사한 마음을 표현합니다.",
|
70 |
+
"console": f"상대방을 따듯하게 위로합니다.",
|
71 |
+
"avoid": f"뒤로 물러서 피하려 합니다.",
|
72 |
+
"show_off": "자랑스러운 모습을 보여줍니다.",
|
73 |
+
# 나머지는 기본 fallback 사용
|
74 |
}
|
75 |
+
|
76 |
+
# 행동 문장 생성
|
77 |
+
lines = []
|
78 |
+
for action, score in sequence:
|
79 |
+
msg = behavior_lines.get(action, f"{action} 행동을 합니다.")
|
80 |
+
lines.append(f"({round(score,1)}) {msg}")
|
81 |
+
|
82 |
+
# 직업 라인 추가
|
83 |
+
job_line = {
|
84 |
+
"farmer": "밭일도 해야 하겠군요.",
|
85 |
+
"blacksmith": "대장간 불도 지펴야죠.",
|
86 |
+
}.get(job, "오늘도 바쁜 하루네요.")
|
87 |
+
|
88 |
+
# 최종 출력 문장
|
89 |
+
return f"{name} 행동 시퀀스: \n" + "\n".join(lines) + f"\n{job_line}"
|
test.ipynb
CHANGED
@@ -2881,10 +2881,19 @@
|
|
2881 |
},
|
2882 |
{
|
2883 |
"cell_type": "code",
|
2884 |
-
"execution_count":
|
2885 |
"id": "53c994dd",
|
2886 |
"metadata": {},
|
2887 |
-
"outputs": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2888 |
"source": [
|
2889 |
"# 8단계 관계 + 감정 + 기억 연동\n",
|
2890 |
"from npc_social_network.npc.npc_base import NPC\n",
|
@@ -2906,6 +2915,42 @@
|
|
2906 |
"print(\"로다와의 관계 점수:\", npc1.relationships.get_relationship(\"로다\"))\n",
|
2907 |
"print(\"로다와의 관계 설명:\", npc1.get_relationship_description(\"로다\"))"
|
2908 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2909 |
}
|
2910 |
],
|
2911 |
"metadata": {
|
|
|
2881 |
},
|
2882 |
{
|
2883 |
"cell_type": "code",
|
2884 |
+
"execution_count": 3,
|
2885 |
"id": "53c994dd",
|
2886 |
"metadata": {},
|
2887 |
+
"outputs": [
|
2888 |
+
{
|
2889 |
+
"name": "stdout",
|
2890 |
+
"output_type": "stream",
|
2891 |
+
"text": [
|
2892 |
+
"로다와의 관계 점수: 9.5\n",
|
2893 |
+
"로다와의 관계 설명: 호감 있음\n"
|
2894 |
+
]
|
2895 |
+
}
|
2896 |
+
],
|
2897 |
"source": [
|
2898 |
"# 8단계 관계 + 감정 + 기억 연동\n",
|
2899 |
"from npc_social_network.npc.npc_base import NPC\n",
|
|
|
2915 |
"print(\"로다와의 관계 점수:\", npc1.relationships.get_relationship(\"로다\"))\n",
|
2916 |
"print(\"로다와의 관계 설명:\", npc1.get_relationship_description(\"로다\"))"
|
2917 |
]
|
2918 |
+
},
|
2919 |
+
{
|
2920 |
+
"cell_type": "code",
|
2921 |
+
"execution_count": null,
|
2922 |
+
"id": "69387020",
|
2923 |
+
"metadata": {},
|
2924 |
+
"outputs": [
|
2925 |
+
{
|
2926 |
+
"ename": "AttributeError",
|
2927 |
+
"evalue": "'BehaviorManager' object has no attribute 'decide'",
|
2928 |
+
"output_type": "error",
|
2929 |
+
"traceback": [
|
2930 |
+
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
2931 |
+
"\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)",
|
2932 |
+
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 12\u001b[39m\n\u001b[32m 9\u001b[39m npc.remember(\u001b[33m\"\u001b[39m\u001b[33m실망스러운 일 겪음\u001b[39m\u001b[33m\"\u001b[39m, importance=\u001b[32m8\u001b[39m, emotion=\u001b[33m\"\u001b[39m\u001b[33msadness\u001b[39m\u001b[33m\"\u001b[39m, strength=\u001b[32m1.8\u001b[39m)\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# 복합 감정 기반 행동 시퀀스 출력\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnpc\u001b[49m\u001b[43m.\u001b[49m\u001b[43mgenerate_dialogue\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m)\n",
|
2933 |
+
"\u001b[36mFile \u001b[39m\u001b[32me:\\Git-Repository\\Portfolio\\npc_social_network\\npc\\npc_base.py:69\u001b[39m, in \u001b[36mNPC.generate_dialogue\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 65\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 66\u001b[39m \u001b[33;03m감정 상태와 직업에 따른 복합 행동 시퀀스 기반 대사 생성\u001b[39;00m\n\u001b[32m 67\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 68\u001b[39m composite = \u001b[38;5;28mself\u001b[39m.get_composite_emotion_state(top_n=\u001b[32m3\u001b[39m) \u001b[38;5;66;03m# 상위 3개 감정 사용\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m69\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mbehavior\u001b[49m\u001b[43m.\u001b[49m\u001b[43mperform_sequence\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mjob\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomposite\u001b[49m\u001b[43m)\u001b[49m\n",
|
2934 |
+
"\u001b[36mFile \u001b[39m\u001b[32me:\\Git-Repository\\Portfolio\\npc_social_network\\npc\\npc_behavior.py:57\u001b[39m, in \u001b[36mBehaviorManager.perform_sequence\u001b[39m\u001b[34m(self, name, job, composite_emotion)\u001b[39m\n\u001b[32m 53\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mperform_sequence\u001b[39m(\u001b[38;5;28mself\u001b[39m, name, job, composite_emotion):\n\u001b[32m 54\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 55\u001b[39m \u001b[33;03m 행동 시퀀스를 텍스트로 구성하여 출력\u001b[39;00m\n\u001b[32m 56\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m57\u001b[39m sequence = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mdecide\u001b[49m(composite_emotion)\n\u001b[32m 58\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m sequence:\n\u001b[32m 59\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m은(는) 특별한 행동을 하지 않습니다.\u001b[39m\u001b[33m\"\u001b[39m\n",
|
2935 |
+
"\u001b[31mAttributeError\u001b[39m: 'BehaviorManager' object has no attribute 'decide'"
|
2936 |
+
]
|
2937 |
+
}
|
2938 |
+
],
|
2939 |
+
"source": [
|
2940 |
+
"# 9단계 복합 감정 - 행동 시퀀스 구성\n",
|
2941 |
+
"from npc_social_network.npc.npc_base import NPC\n",
|
2942 |
+
"\n",
|
2943 |
+
"npc = NPC(name=\"아린\", job=\"farmer\", path=[(0,0)], image=None)\n",
|
2944 |
+
"\n",
|
2945 |
+
"# 여러 감정 기억 등록\n",
|
2946 |
+
"npc.remember(\"칭찬받아 기쁨\", importance=7, emotion=\"joy\", strength=2.0)\n",
|
2947 |
+
"npc.remember(\"동료가 위로함\", importance=8, emotion=\"gratitude\", strength=1.5)\n",
|
2948 |
+
"npc.remember(\"실망스러운 일 겪음\", importance=8, emotion=\"sadness\", strength=1.8)\n",
|
2949 |
+
"print(npc.get_composite_emotion_state())\n",
|
2950 |
+
"\n",
|
2951 |
+
"# 복합 감정 기반 행동 시퀀스 출력\n",
|
2952 |
+
"print(npc.generate_dialogue())"
|
2953 |
+
]
|
2954 |
}
|
2955 |
],
|
2956 |
"metadata": {
|