Spaces:
Sleeping
Sleeping
| #!/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() |