persona / personality_interaction_algorithm.py
haepa_mac
🚀 향상된 통합 시스템 구현: 사용자 조정값이 127개 변수에 실제 반영되는 완전한 통합 알고리즘
a83437e
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
🎯 통합 성격 상호작용 알고리즘
사용자 조정값이 전체 시스템에 의미있게 반영되도록 하는 핵심 엔진
핵심 기능:
1. 🎛️ 사용자 조정값 → 127개 변수 자동 변환
2. 🔄 변수간 상호영향 계산 (상관관계, 역상관관계)
3. 🎭 성격 일관성 유지 (모순 방지)
4. 💬 대화 스타일 동적 생성
5. 🌟 매력적 결함 자동 도출
"""
import math
import random
import numpy as np
from typing import Dict, List, Tuple, Optional, Any
import json
class PersonalityInteractionEngine:
"""
성격 변수들 간의 복잡한 상호작용을 계산하는 엔진
"""
# 🧠 성격 변수 간 상관관계 매트릭스
CORRELATION_MATRIX = {
# 온기(Warmth) 기반 상관관계
"온기": {
"positive": ["W01_친절함", "W02_친근함", "W06_공감능력", "W07_포용력",
"A03_이타심", "A04_순응성", "R06_친밀감수용도", "D01_초기접근성"],
"negative": ["N04_자의식", "F02_소심함", "S01_격식성수준"],
"neutral": ["C01_효율성", "C02_지능"]
},
# 능력(Competence) 기반 상관관계
"능력": {
"positive": ["C01_효율성", "C02_지능", "C03_전문성", "C05_정확성",
"C06_분석력", "C07_학습능력", "C08_통찰력", "C09_실행력",
"C11_유능감", "C12_질서성", "C14_성취욕구"],
"negative": ["F03_기술치음", "F09_결정회피", "N01_불안성"],
"neutral": ["E01_사교성", "H01_유머감각"]
},
# 외향성(Extraversion) 기반 상관관계
"외향성": {
"positive": ["E01_사교성", "E02_활동성", "E03_자기주장", "E04_긍정정서",
"E05_자극추구", "E06_열정성", "D01_초기접근성", "H02_상황유머감각"],
"negative": ["F02_소심함", "N04_자의식", "F08_주목회피", "N06_내성적회피"],
"neutral": ["C06_분석력", "O01_개방성"]
},
# 유머감각 기반 상관관계
"유머감각": {
"positive": ["H01_유머감각", "H02_상황유머감각", "E04_긍정정서",
"O02_심미성", "O03_상상력", "D05_매력적위험성"],
"negative": ["N01_불안성", "F01_완벽주의불안", "S01_격식성수준"],
"neutral": ["C02_지능", "W01_친절함"]
}
}
# 🎭 성격 아키타입별 변수 가중치
ARCHETYPE_WEIGHTS = {
"친근한_완벽주의자": {
"온기": 1.2, "능력": 1.3, "외향성": 0.9, "유머감각": 0.8,
"특화변수": ["C12_질서성", "F01_완벽주의불안", "W02_친근함"]
},
"활발한_엔터테이너": {
"온기": 1.1, "능력": 0.8, "외향성": 1.4, "유머감각": 1.3,
"특화변수": ["E02_활동성", "H02_상황유머감각", "D05_매력적위험성"]
},
"조용한_지혜자": {
"온기": 1.0, "능력": 1.3, "외향성": 0.6, "유머감각": 0.9,
"특화변수": ["C08_통찰력", "O01_개방성", "N06_내성적회피"]
},
"따뜻한_카운슬러": {
"온기": 1.4, "능력": 1.0, "외향성": 1.0, "유머감각": 0.7,
"특화변수": ["W06_공감능력", "A03_이타심", "R06_친밀감수용도"]
}
}
def __init__(self):
"""초기화"""
self.base_variables = self._initialize_base_variables()
self.interaction_history = []
def _initialize_base_variables(self) -> Dict[str, float]:
"""127개 기본 변수 초기화"""
return {
# W: Warmth (온기) 관련 변수들
"W01_친절함": 50.0, "W02_친근함": 50.0, "W03_진실성": 50.0,
"W04_신뢰성": 50.0, "W05_수용성": 50.0, "W06_공감능력": 50.0,
"W07_포용력": 50.0, "W08_격려성향": 50.0, "W09_친밀감표현": 50.0,
"W10_무조건적수용": 50.0,
# C: Competence (능력) 관련 변수들
"C01_효율성": 50.0, "C02_지능": 50.0, "C03_전문성": 50.0,
"C04_창의성": 50.0, "C05_정확성": 50.0, "C06_분석력": 50.0,
"C07_학습능력": 50.0, "C08_통찰력": 50.0, "C09_실행력": 50.0,
"C10_적응력": 50.0, "C11_유능감": 50.0, "C12_질서성": 50.0,
"C13_책임감": 50.0, "C14_성취욕구": 50.0, "C15_자기규율": 50.0,
"C16_신중함": 50.0,
# E: Extraversion (외향성) 관련 변수들
"E01_사교성": 50.0, "E02_활동성": 50.0, "E03_자기주장": 50.0,
"E04_긍정정서": 50.0, "E05_자극추구": 50.0, "E06_열정성": 50.0,
# A: Agreeableness (친화성) 관련 변수들
"A01_신뢰": 50.0, "A02_솔직함": 50.0, "A03_이타심": 50.0,
"A04_순응성": 50.0, "A05_겸손함": 50.0, "A06_동정심": 50.0,
# N: Neuroticism (신경성) 관련 변수들
"N01_불안성": 50.0, "N02_분노성": 50.0, "N03_우울성": 50.0,
"N04_자의식": 50.0, "N05_충동성": 50.0, "N06_내성적회피": 50.0,
# O: Openness (개방성) 관련 변수들
"O01_개방성": 50.0, "O02_심미성": 50.0, "O03_상상력": 50.0,
"O04_행동개방성": 50.0, "O05_아이디어개방성": 50.0, "O06_가치개방성": 50.0,
# H: Humor (유머) 관련 변수들
"H01_유머감각": 50.0, "H02_상황유머감각": 50.0, "H03_자기참조유머": 50.0,
"H04_관찰유머": 50.0, "H05_언어유머": 50.0,
# S: Social Style (사회적 스타일) 관련 변수들
"S01_격식성수준": 50.0, "S02_직접성정도": 50.0, "S03_표현풍부함": 50.0,
"S04_대화주도성": 50.0, "S05_감정표현도": 50.0,
# R: Relationship (관계) 관련 변수들
"R01_안정애착성향": 50.0, "R02_회피애착성향": 50.0, "R03_불안애착성향": 50.0,
"R04_경계설정능력": 50.0, "R05_갈등해결능력": 50.0, "R06_친밀감수용도": 50.0,
# D: Dynamic (역동성) 관련 변수들
"D01_초기접근성": 50.0, "D02_적응속도": 50.0, "D03_변화수용도": 50.0,
"D04_도전의식": 50.0, "D05_매력적위험성": 50.0, "D06_예측불가능성": 50.0,
"D07_신비감": 50.0, "D08_취약성공유도": 50.0,
# F: Flaws (매력적 결함) 관련 변수들
"F01_완벽주의불안": 50.0, "F02_소심함": 50.0, "F03_기술치음": 50.0,
"F04_감정기복": 50.0, "F05_우유부단함": 50.0, "F06_산만함": 50.0,
"F07_고집스러움": 50.0, "F08_주목회피": 50.0, "F09_결정회피": 50.0,
"F10_과도한배려": 50.0,
# P: Personality Contradictions (성격 모순) 관련 변수들
"P01_따뜻함차가움공존": 50.0, "P02_자신감불안공존": 50.0, "P03_사교성고독감공존": 50.0,
"P04_완벽주의자유분방공존": 50.0, "P05_진지함유머공존": 50.0, "P06_신중함충동공존": 50.0,
"P07_보수혁신양면": 50.0, "P08_독립의존양면": 50.0, "P09_논리감정양면": 50.0,
"P10_외향내향전환": 50.0,
# U: Unique Identity (고유 정체성) 관련 변수들
"U01_개인적경험영향": 50.0, "U02_문화적배경": 50.0, "U03_가치관체계": 50.0,
"U04_전통가치계승": 50.0, "U05_혁신성향": 50.0, "U06_미래지향성": 50.0,
"U07_과거회상성향": 50.0, "U08_현실안주성향": 50.0,
# FORM: 물리적 특성 영향 변수들
"FORM01_색상영향성": 50.0, "FORM02_형태영향성": 50.0, "FORM03_재질영향성": 50.0,
"FORM04_크기영향성": 50.0, "FORM05_질감영향성": 50.0,
# OBJECT: 사물 특화 변수들
"OBJ01_기능적자부심": 50.0, "OBJ02_미적가치": 50.0, "OBJ03_실용성지향": 50.0,
"OBJ04_장식성지향": 50.0, "OBJ05_내구성의식": 50.0
}
def calculate_integrated_personality(
self,
user_adjustments: Dict[str, float],
object_analysis: Optional[Dict] = None,
context_factors: Optional[Dict] = None
) -> Dict[str, Any]:
"""
🎯 핵심 알고리즘: 사용자 조정값을 전체 시스템에 통합 반영
Args:
user_adjustments: 사용자가 슬라이더로 조정한 값들 {"온기": 80, "능력": 60, ...}
object_analysis: 이미지 분석 결과
context_factors: 추가 컨텍스트 (목적, 관계 등)
Returns:
{
"variables_127": {...}, # 127개 계산된 변수
"personality_profile": {...}, # 성격 프로필
"interaction_effects": {...}, # 상호작용 효과
"conversation_style": {...}, # 대화 스타일
"attractive_flaws": [...], # 매력적 결함
"archetype": "...", # 성격 아키타입
"coherence_score": 0.85 # 일관성 점수
}
"""
print("🔄 통합 성격 계산 시작...")
# 1️⃣ 기본 변수 복사
calculated_vars = self.base_variables.copy()
# 2️⃣ 사용자 조정값을 기반으로 핵심 변수 업데이트
self._apply_user_adjustments(calculated_vars, user_adjustments)
# 3️⃣ 상관관계 기반 연쇄 반응 계산
interaction_effects = self._calculate_correlation_effects(calculated_vars, user_adjustments)
# 4️⃣ 물리적 특성 영향 반영
if object_analysis:
self._apply_physical_influences(calculated_vars, object_analysis)
# 5️⃣ 컨텍스트 요인 반영
if context_factors:
self._apply_context_factors(calculated_vars, context_factors)
# 6️⃣ 성격 아키타입 결정
archetype = self._determine_archetype(calculated_vars, user_adjustments)
# 7️⃣ 아키타입 기반 가중치 적용
self._apply_archetype_weights(calculated_vars, archetype)
# 8️⃣ 모순 해결 및 일관성 보장
coherence_score = self._resolve_contradictions(calculated_vars)
# 9️⃣ 매력적 결함 자동 생성
attractive_flaws = self._generate_dynamic_flaws(calculated_vars, user_adjustments)
# 🔟 대화 스타일 동적 생성
conversation_style = self._generate_conversation_style(calculated_vars, archetype)
# 📊 성격 프로필 생성
personality_profile = self._create_personality_profile(calculated_vars, user_adjustments)
# 📝 상호작용 이력 저장
self.interaction_history.append({
"user_input": user_adjustments,
"output_vars": calculated_vars,
"archetype": archetype,
"coherence": coherence_score
})
result = {
"variables_127": calculated_vars,
"personality_profile": personality_profile,
"interaction_effects": interaction_effects,
"conversation_style": conversation_style,
"attractive_flaws": attractive_flaws,
"archetype": archetype,
"coherence_score": coherence_score,
"calculation_metadata": {
"user_input_strength": self._calculate_input_strength(user_adjustments),
"dominant_traits": self._identify_dominant_traits(calculated_vars),
"interaction_complexity": len(interaction_effects)
}
}
print(f"✅ 통합 계산 완료 - 아키타입: {archetype}, 일관성: {coherence_score:.2f}")
return result
def _apply_user_adjustments(self, variables: Dict[str, float], adjustments: Dict[str, float]):
"""사용자 조정값을 127개 변수에 직접 반영"""
for trait, value in adjustments.items():
if trait == "온기":
# 온기 관련 변수들에 직접 영향
influence_strength = (value - 50) / 50 # -1.0 ~ 1.0
variables["W01_친절함"] = self._safe_adjust(variables["W01_친절함"], value * 0.9 + random.uniform(-5, 5))
variables["W02_친근함"] = self._safe_adjust(variables["W02_친근함"], value * 0.8 + random.uniform(-8, 8))
variables["W06_공감능력"] = self._safe_adjust(variables["W06_공감능력"], value * 0.85 + random.uniform(-7, 7))
variables["W07_포용력"] = self._safe_adjust(variables["W07_포용력"], value * 0.75 + random.uniform(-10, 10))
# 2차 영향 (간접적)
variables["A03_이타심"] += influence_strength * 15
variables["R06_친밀감수용도"] += influence_strength * 12
variables["D01_초기접근성"] += influence_strength * 18
elif trait == "능력":
influence_strength = (value - 50) / 50
variables["C01_효율성"] = self._safe_adjust(variables["C01_효율성"], value * 0.95 + random.uniform(-3, 3))
variables["C02_지능"] = self._safe_adjust(variables["C02_지능"], value * 0.9 + random.uniform(-5, 5))
variables["C03_전문성"] = self._safe_adjust(variables["C03_전문성"], value * 0.85 + random.uniform(-8, 8))
variables["C11_유능감"] = self._safe_adjust(variables["C11_유능감"], value * 0.8 + random.uniform(-10, 10))
# 2차 영향
variables["C14_성취욕구"] += influence_strength * 20
variables["F03_기술치음"] -= influence_strength * 25 # 역상관
variables["F09_결정회피"] -= influence_strength * 18
elif trait == "외향성":
influence_strength = (value - 50) / 50
variables["E01_사교성"] = self._safe_adjust(variables["E01_사교성"], value * 0.95 + random.uniform(-3, 3))
variables["E02_활동성"] = self._safe_adjust(variables["E02_활동성"], value * 0.9 + random.uniform(-5, 5))
variables["E03_자기주장"] = self._safe_adjust(variables["E03_자기주장"], value * 0.8 + random.uniform(-8, 8))
variables["E06_열정성"] = self._safe_adjust(variables["E06_열정성"], value * 0.85 + random.uniform(-7, 7))
# 2차 영향
variables["D01_초기접근성"] += influence_strength * 22
variables["F02_소심함"] -= influence_strength * 30 # 역상관
variables["N04_자의식"] -= influence_strength * 15
elif trait == "유머감각":
influence_strength = (value - 50) / 50
variables["H01_유머감각"] = self._safe_adjust(variables["H01_유머감각"], value * 0.95 + random.uniform(-3, 3))
variables["H02_상황유머감각"] = self._safe_adjust(variables["H02_상황유머감각"], value * 0.9 + random.uniform(-5, 5))
variables["H03_자기참조유머"] = self._safe_adjust(variables["H03_자기참조유머"], value * 0.8 + random.uniform(-8, 8))
# 2차 영향
variables["E04_긍정정서"] += influence_strength * 25
variables["D05_매력적위험성"] += influence_strength * 15
variables["S03_표현풍부함"] += influence_strength * 20
def _safe_adjust(self, current_value: float, target_value: float) -> float:
"""안전한 값 조정 (0-100 범위 보장)"""
return max(0, min(100, target_value))
def _calculate_correlation_effects(self, variables: Dict[str, float], user_input: Dict[str, float]) -> Dict[str, List[Dict]]:
"""상관관계 기반 연쇄 반응 계산"""
effects = {"positive_correlations": [], "negative_correlations": [], "emergent_patterns": []}
for trait, value in user_input.items():
if trait in self.CORRELATION_MATRIX:
correlation_data = self.CORRELATION_MATRIX[trait]
influence = (value - 50) / 50 # -1.0 ~ 1.0 정규화
# 긍정적 상관관계
for var in correlation_data.get("positive", []):
if var in variables:
old_value = variables[var]
adjustment = influence * random.uniform(8, 25)
variables[var] = self._safe_adjust(variables[var], variables[var] + adjustment)
effects["positive_correlations"].append({
"source": trait,
"target": var,
"old_value": old_value,
"new_value": variables[var],
"strength": abs(adjustment)
})
# 부정적 상관관계
for var in correlation_data.get("negative", []):
if var in variables:
old_value = variables[var]
adjustment = influence * random.uniform(-25, -8)
variables[var] = self._safe_adjust(variables[var], variables[var] + adjustment)
effects["negative_correlations"].append({
"source": trait,
"target": var,
"old_value": old_value,
"new_value": variables[var],
"strength": abs(adjustment)
})
# 복합적 패턴 감지
effects["emergent_patterns"] = self._detect_emergent_patterns(variables, user_input)
return effects
def _detect_emergent_patterns(self, variables: Dict[str, float], user_input: Dict[str, float]) -> List[Dict]:
"""복합적 성격 패턴 감지"""
patterns = []
# 패턴 1: 모순적 매력 (높은 능력 + 높은 소심함)
if user_input.get("능력", 50) > 70 and variables.get("F02_소심함", 50) > 60:
patterns.append({
"type": "모순적매력",
"description": "뛰어난 능력을 가졌지만 겸손하고 소심한 매력",
"variables_affected": ["P02_자신감불안공존", "D07_신비감"],
"strength": 20
})
variables["P02_자신감불안공존"] = min(100, variables["P02_자신감불안공존"] + 20)
variables["D07_신비감"] = min(100, variables["D07_신비감"] + 15)
# 패턴 2: 차가운 유머 (낮은 온기 + 높은 유머)
if user_input.get("온기", 50) < 40 and user_input.get("유머감각", 50) > 70:
patterns.append({
"type": "차가운유머",
"description": "냉정하지만 위트 있는 매력적 아이러니",
"variables_affected": ["H04_관찰유머", "D05_매력적위험성"],
"strength": 25
})
variables["H04_관찰유머"] = min(100, variables["H04_관찰유머"] + 25)
variables["D05_매력적위험성"] = min(100, variables["D05_매력적위험성"] + 20)
# 패턴 3: 내향적 리더십 (낮은 외향성 + 높은 능력)
if user_input.get("외향성", 50) < 40 and user_input.get("능력", 50) > 75:
patterns.append({
"type": "내향적리더십",
"description": "조용하지만 강력한 영향력을 가진 존재",
"variables_affected": ["C08_통찰력", "R04_경계설정능력"],
"strength": 22
})
variables["C08_통찰력"] = min(100, variables["C08_통찰력"] + 22)
variables["R04_경계설정능력"] = min(100, variables["R04_경계설정능력"] + 18)
return patterns
def _apply_physical_influences(self, variables: Dict[str, float], object_analysis: Dict):
"""물리적 특성의 성격 변수 영향 계산"""
# 색상 영향
colors = object_analysis.get("colors", [])
for color in colors:
color_lower = color.lower()
if "red" in color_lower or "빨강" in color_lower:
variables["E02_활동성"] = min(100, variables["E02_활동성"] + 15)
variables["E06_열정성"] = min(100, variables["E06_열정성"] + 18)
variables["FORM01_색상영향성"] = min(100, variables["FORM01_색상영향성"] + 20)
elif "blue" in color_lower or "파랑" in color_lower:
variables["W04_신뢰성"] = min(100, variables["W04_신뢰성"] + 12)
variables["C16_신중함"] = min(100, variables["C16_신중함"] + 15)
variables["R01_안정애착성향"] = min(100, variables["R01_안정애착성향"] + 10)
elif "yellow" in color_lower or "노랑" in color_lower:
variables["E04_긍정정서"] = min(100, variables["E04_긍정정서"] + 20)
variables["H02_상황유머감각"] = min(100, variables["H02_상황유머감각"] + 15)
# 재질 영향
materials = object_analysis.get("materials", [])
for material in materials:
material_lower = material.lower()
if "metal" in material_lower or "금속" in material_lower:
variables["C01_효율성"] = min(100, variables["C01_효율성"] + 18)
variables["C05_정확성"] = min(100, variables["C05_정확성"] + 15)
variables["FORM03_재질영향성"] = min(100, variables["FORM03_재질영향성"] + 25)
elif "wood" in material_lower or "나무" in material_lower:
variables["W01_친절함"] = min(100, variables["W01_친절함"] + 20)
variables["U04_전통가치계승"] = min(100, variables["U04_전통가치계승"] + 22)
# 크기 영향
size = object_analysis.get("size", "").lower()
if "large" in size or "큰" in size or "크" in size:
variables["E03_자기주장"] = min(100, variables["E03_자기주장"] + 15)
variables["OBJ01_기능적자부심"] = min(100, variables["OBJ01_기능적자부심"] + 18)
elif "small" in size or "작은" in size or "작" in size:
variables["W02_친근함"] = min(100, variables["W02_친근함"] + 20)
variables["A05_겸손함"] = min(100, variables["A05_겸손함"] + 15)
def _apply_context_factors(self, variables: Dict[str, float], context: Dict):
"""컨텍스트 요인 반영"""
# 사용 목적에 따른 조정
purpose = context.get("purpose", "").lower()
if "work" in purpose or "업무" in purpose or "일" in purpose:
variables["C01_효율성"] = min(100, variables["C01_효율성"] + 12)
variables["C13_책임감"] = min(100, variables["C13_책임감"] + 15)
variables["S01_격식성수준"] = min(100, variables["S01_격식성수준"] + 10)
elif "entertainment" in purpose or "오락" in purpose or "재미" in purpose:
variables["H01_유머감각"] = min(100, variables["H01_유머감각"] + 15)
variables["E05_자극추구"] = min(100, variables["E05_자극추구"] + 18)
variables["D05_매력적위험성"] = min(100, variables["D05_매력적위험성"] + 12)
# 관계 깊이에 따른 조정
relationship_depth = context.get("relationship_depth", 0)
if relationship_depth > 0.7: # 깊은 관계
variables["R06_친밀감수용도"] = min(100, variables["R06_친밀감수용도"] + 20)
variables["D08_취약성공유도"] = min(100, variables["D08_취약성공유도"] + 15)
variables["W09_친밀감표현"] = min(100, variables["W09_친밀감표현"] + 18)
def _determine_archetype(self, variables: Dict[str, float], user_input: Dict[str, float]) -> str:
"""성격 아키타입 결정"""
warmth = user_input.get("온기", 50)
competence = user_input.get("능력", 50)
extraversion = user_input.get("외향성", 50)
humor = user_input.get("유머감각", 50)
# 아키타입 결정 로직
if warmth >= 70 and competence >= 70:
if extraversion >= 60:
return "활발한_엔터테이너" if humor >= 60 else "카리스마틱_리더"
else:
return "따뜻한_카운슬러" if humor < 60 else "친근한_완벽주의자"
elif competence >= 70:
if extraversion < 50:
return "조용한_지혜자"
else:
return "위트넘치는_지식인" if humor >= 60 else "효율적_실무자"
elif warmth >= 70:
return "따뜻한_카운슬러" if extraversion < 60 else "사교적_친구"
elif humor >= 70:
return "장난꾸러기_매력" if extraversion >= 60 else "은밀한_위트"
else:
return "신비로운_존재"
def _apply_archetype_weights(self, variables: Dict[str, float], archetype: str):
"""아키타입별 가중치 적용"""
if archetype in self.ARCHETYPE_WEIGHTS:
weights = self.ARCHETYPE_WEIGHTS[archetype]
# 특화 변수 강화
for var in weights.get("특화변수", []):
if var in variables:
variables[var] = min(100, variables[var] * 1.2)
def _resolve_contradictions(self, variables: Dict[str, float]) -> float:
"""모순 해결 및 일관성 점수 계산"""
contradictions_resolved = 0
total_checks = 0
# 일관성 체크 및 자동 조정
consistency_rules = [
# 온기와 차가움의 균형
(["W01_친절함", "W02_친근함"], ["N04_자의식", "F02_소심함"], "온기_일관성"),
# 능력과 불안의 균형
(["C01_효율성", "C11_유능감"], ["F03_기술치음", "N01_불안성"], "능력_일관성"),
# 외향성과 내향성의 균형
(["E01_사교성", "E02_활동성"], ["N06_내성적회피", "F08_주목회피"], "외향성_일관성")
]
for positive_vars, negative_vars, rule_name in consistency_rules:
total_checks += 1
# 긍정적 변수들의 평균
pos_avg = sum(variables.get(var, 50) for var in positive_vars) / len(positive_vars)
neg_avg = sum(variables.get(var, 50) for var in negative_vars) / len(negative_vars)
# 극단적 모순 감지 및 조정
if abs(pos_avg - (100 - neg_avg)) > 40: # 40점 이상 차이나면 조정
adjustment = (pos_avg - (100 - neg_avg)) * 0.3
for var in negative_vars:
if var in variables:
variables[var] = self._safe_adjust(variables[var], variables[var] - adjustment)
contradictions_resolved += 1
# 일관성 점수 계산
coherence_score = max(0.5, 1.0 - (contradictions_resolved / total_checks) * 0.5)
return round(coherence_score, 2)
def _generate_dynamic_flaws(self, variables: Dict[str, float], user_input: Dict[str, float]) -> List[str]:
"""동적 매력적 결함 생성"""
flaws = []
# 높은 능력에서 나오는 결함
if user_input.get("능력", 50) > 75:
if variables.get("F01_완벽주의불안", 50) > 60:
flaws.append("완벽을 추구하느라 때로는 스스로를 너무 몰아붙임")
if variables.get("C16_신중함", 50) > 70:
flaws.append("신중함이 지나쳐 결정을 내리는 데 시간이 오래 걸림")
# 높은 온기에서 나오는 결함
if user_input.get("온기", 50) > 75:
if variables.get("F10_과도한배려", 50) > 60:
flaws.append("다른 사람을 너무 배려하다 보니 자신의 필요를 뒤로 미룸")
if variables.get("A04_순응성", 50) > 70:
flaws.append("갈등을 피하고 싶어서 때로는 자신의 의견을 숨김")
# 높은 외향성에서 나오는 결함
if user_input.get("외향성", 50) > 75:
if variables.get("E05_자극추구", 50) > 65:
flaws.append("새로운 자극을 찾다 보니 한 가지에 오래 집중하기 어려움")
if variables.get("N05_충동성", 50) > 60:
flaws.append("즉흥적인 면이 있어서 계획보다는 감정에 따라 행동함")
# 높은 유머감각에서 나오는 결함
if user_input.get("유머감각", 50) > 75:
if variables.get("S03_표현풍부함", 50) > 70:
flaws.append("재미있게 만들려고 하다 보니 때로는 상황을 과장함")
# 기본 결함이 없으면 범용 결함 추가
if len(flaws) == 0:
flaws.extend([
"생각이 많아서 가끔 머릿속이 복잡해짐",
"완벽하지 않은 자신의 모습에 가끔 실망함",
"호기심이 많아서 여러 가지에 관심을 갖다 보니 산만해질 때가 있음"
])
return flaws[:3] # 최대 3개
def _generate_conversation_style(self, variables: Dict[str, float], archetype: str) -> Dict[str, Any]:
"""동적 대화 스타일 생성"""
style = {
"기본_톤": self._determine_tone(variables),
"대화_패턴": self._determine_conversation_pattern(variables),
"감정_표현": self._determine_emotion_expression(variables),
"유머_스타일": self._determine_humor_style(variables),
"관계_형성": self._determine_relationship_approach(variables),
"특화_특성": []
}
# 아키타입별 특화 스타일
if archetype == "친근한_완벽주의자":
style["특화_특성"].extend([
"정확한 정보 제공을 선호",
"실수에 대해 솔직하게 인정",
"체계적이고 논리적인 설명"
])
elif archetype == "활발한_엔터테이너":
style["특화_특성"].extend([
"에너지 넘치는 표현",
"상대방을 적극적으로 참여시킴",
"재미있는 이야기와 경험 공유"
])
return style
def _determine_tone(self, variables: Dict[str, float]) -> str:
"""기본 톤 결정"""
warmth_score = (variables.get("W01_친절함", 50) + variables.get("W02_친근함", 50)) / 2
formality_score = variables.get("S01_격식성수준", 50)
if warmth_score > 70:
return "따뜻하고 친근함" if formality_score < 60 else "정중하고 따뜻함"
elif warmth_score < 40:
return "차분하고 절제됨" if formality_score > 60 else "쿨하고 직설적"
else:
return "균형잡히고 적당함"
def _determine_conversation_pattern(self, variables: Dict[str, float]) -> str:
"""대화 패턴 결정"""
social_score = variables.get("E01_사교성", 50)
leadership_score = variables.get("S04_대화주도성", 50)
if social_score > 70 and leadership_score > 60:
return "적극적으로 대화를 이끌어감"
elif social_score > 70:
return "상대방에 맞춰 활발하게 반응"
elif social_score < 40:
return "조심스럽게 상대방의 말을 들어줌"
else:
return "상황에 따라 적절히 대응"
def _determine_emotion_expression(self, variables: Dict[str, float]) -> str:
"""감정 표현 방식 결정"""
expression_score = variables.get("S05_감정표현도", 50)
intimacy_score = variables.get("W09_친밀감표현", 50)
if expression_score > 70:
return "감정을 풍부하고 직접적으로 표현"
elif expression_score < 40:
return "감정을 절제되고 은은하게 표현"
else:
return "상황에 맞게 적절히 감정 표현"
def _determine_humor_style(self, variables: Dict[str, float]) -> str:
"""유머 스타일 결정"""
humor_score = variables.get("H01_유머감각", 50)
situational_humor = variables.get("H02_상황유머감각", 50)
self_ref_humor = variables.get("H03_자기참조유머", 50)
if humor_score > 70:
if situational_humor > self_ref_humor:
return "상황을 재미있게 해석하는 관찰형 유머"
else:
return "자신의 경험을 재밌게 풀어내는 자기참조형 유머"
elif humor_score > 40:
return "적절한 때에 가벼운 농담"
else:
return "유머보다는 진지한 대화 선호"
def _determine_relationship_approach(self, variables: Dict[str, float]) -> str:
"""관계 형성 방식 결정"""
initial_approach = variables.get("D01_초기접근성", 50)
intimacy_acceptance = variables.get("R06_친밀감수용도", 50)
if initial_approach > 70:
return "빠르게 친밀감을 형성하려 함"
elif initial_approach < 40:
return "천천히 시간을 두고 관계를 쌓아감"
else:
return "자연스럽게 관계가 발전되도록 함"
def _create_personality_profile(self, variables: Dict[str, float], user_input: Dict[str, float]) -> Dict[str, Any]:
"""성격 프로필 생성"""
return {
"핵심_특성": {
"온기": round(user_input.get("온기", 50), 1),
"능력": round(user_input.get("능력", 50), 1),
"외향성": round(user_input.get("외향성", 50), 1),
"유머감각": round(user_input.get("유머감각", 50), 1)
},
"세부_변수_요약": {
"온기계열": round(sum(v for k, v in variables.items() if k.startswith("W")) / 10, 1),
"능력계열": round(sum(v for k, v in variables.items() if k.startswith("C")) / 16, 1),
"외향성계열": round(sum(v for k, v in variables.items() if k.startswith("E")) / 6, 1),
"유머계열": round(sum(v for k, v in variables.items() if k.startswith("H")) / 5, 1),
"매력적결함": round(sum(v for k, v in variables.items() if k.startswith("F")) / 10, 1),
"모순적특성": round(sum(v for k, v in variables.items() if k.startswith("P")) / 10, 1)
},
"특징적_변수": self._identify_exceptional_variables(variables),
"균형_분석": self._analyze_personality_balance(variables)
}
def _identify_exceptional_variables(self, variables: Dict[str, float]) -> List[Dict]:
"""특징적인 변수들 식별"""
exceptional = []
for var, value in variables.items():
if value > 80:
exceptional.append({"변수": var, "값": value, "특성": "매우높음"})
elif value < 20:
exceptional.append({"변수": var, "값": value, "특성": "매우낮음"})
return sorted(exceptional, key=lambda x: abs(x["값"] - 50), reverse=True)[:8]
def _analyze_personality_balance(self, variables: Dict[str, float]) -> Dict[str, str]:
"""성격 균형 분석"""
# 카테고리별 평균 계산
categories = {}
for var, value in variables.items():
prefix = var.split("_")[0]
if prefix not in categories:
categories[prefix] = []
categories[prefix].append(value)
balance_analysis = {}
for category, values in categories.items():
avg = sum(values) / len(values)
if avg > 70:
balance_analysis[category] = "강점영역"
elif avg < 40:
balance_analysis[category] = "성장영역"
else:
balance_analysis[category] = "균형영역"
return balance_analysis
def _calculate_input_strength(self, user_input: Dict[str, float]) -> float:
"""사용자 입력의 강도 계산"""
deviations = [abs(value - 50) for value in user_input.values()]
avg_deviation = sum(deviations) / len(deviations) if deviations else 0
return round(avg_deviation / 50, 2) # 0.0 ~ 1.0
def _identify_dominant_traits(self, variables: Dict[str, float]) -> List[str]:
"""지배적 특성 식별"""
sorted_vars = sorted(variables.items(), key=lambda x: x[1], reverse=True)
return [var for var, value in sorted_vars[:5]]
def get_interaction_summary(self) -> Dict[str, Any]:
"""상호작용 요약 정보"""
if not self.interaction_history:
return {"message": "아직 상호작용 이력이 없습니다."}
latest = self.interaction_history[-1]
return {
"총_상호작용_횟수": len(self.interaction_history),
"최근_아키타입": latest["archetype"],
"최근_일관성점수": latest["coherence"],
"최근_사용자입력": latest["user_input"],
"변화_추이": self._analyze_interaction_trends()
}
def _analyze_interaction_trends(self) -> Dict[str, Any]:
"""상호작용 변화 추이 분석"""
if len(self.interaction_history) < 2:
return {"message": "추이 분석을 위해 최소 2회 상호작용이 필요합니다."}
recent = self.interaction_history[-1]
previous = self.interaction_history[-2]
coherence_change = recent["coherence"] - previous["coherence"]
archetype_change = recent["archetype"] != previous["archetype"]
return {
"일관성_변화": round(coherence_change, 2),
"아키타입_변경됨": archetype_change,
"이전_아키타입": previous["archetype"],
"현재_아키타입": recent["archetype"]
}
# 🧪 테스트 및 데모 함수
def test_personality_interaction():
"""통합 알고리즘 테스트"""
print("🧪 성격 상호작용 알고리즘 테스트")
print("=" * 60)
engine = PersonalityInteractionEngine()
# 테스트 시나리오들
test_scenarios = [
{
"name": "따뜻하고 유능한 완벽주의자",
"user_input": {"온기": 80, "능력": 85, "외향성": 45, "유머감각": 30},
"object_analysis": {
"object_type": "노트북",
"colors": ["silver", "black"],
"materials": ["metal", "plastic"],
"size": "medium"
}
},
{
"name": "냉정하지만 재미있는 관찰자",
"user_input": {"온기": 35, "능력": 75, "외향성": 40, "유머감각": 85},
"object_analysis": {
"object_type": "스마트폰",
"colors": ["black"],
"materials": ["glass", "metal"],
"size": "small"
}
},
{
"name": "활발한 엔터테이너",
"user_input": {"온기": 90, "능력": 55, "외향성": 95, "유머감각": 80},
"object_analysis": {
"object_type": "스피커",
"colors": ["red", "black"],
"materials": ["plastic", "fabric"],
"size": "large"
}
}
]
for i, scenario in enumerate(test_scenarios, 1):
print(f"\n🎭 시나리오 {i}: {scenario['name']}")
print("-" * 40)
result = engine.calculate_integrated_personality(
user_adjustments=scenario["user_input"],
object_analysis=scenario["object_analysis"],
context_factors={"purpose": "personal", "relationship_depth": 0.3}
)
print(f"📊 결정된 아키타입: {result['archetype']}")
print(f"🎯 일관성 점수: {result['coherence_score']}")
print(f"💪 입력 강도: {result['calculation_metadata']['user_input_strength']}")
print("\n🌟 매력적 결함:")
for flaw in result["attractive_flaws"]:
print(f" • {flaw}")
print(f"\n💬 대화 스타일:")
style = result["conversation_style"]
print(f" • 기본 톤: {style['기본_톤']}")
print(f" • 대화 패턴: {style['대화_패턴']}")
print(f" • 유머 스타일: {style['유머_스타일']}")
print(f"\n📈 상호작용 효과: {len(result['interaction_effects']['positive_correlations'])}개 긍정상관, "
f"{len(result['interaction_effects']['negative_correlations'])}개 부정상관")
if result['interaction_effects']['emergent_patterns']:
print("🔮 감지된 특별 패턴:")
for pattern in result['interaction_effects']['emergent_patterns']:
print(f" • {pattern['type']}: {pattern['description']}")
print(f"\n📋 전체 상호작용 요약:")
summary = engine.get_interaction_summary()
print(f" • 총 테스트 횟수: {summary['총_상호작용_횟수']}")
print(f" • 마지막 아키타입: {summary['최근_아키타입']}")
print(f" • 마지막 일관성: {summary['최근_일관성점수']}")
if __name__ == "__main__":
test_personality_interaction()