import type { Pad } from './types' export const clamp = (x: number, lo = -1, hi = 1) => Math.max(lo, Math.min(hi, x)) export const MOOD_EVENTS = { thanks: { p: 0.15, a: 0.05, d: 0.05 }, scold: { p: -0.2, a: 0.15, d: -0.1 }, success: { p: 0.08, a: 0.03, d: 0.05 }, toolFail: { p: -0.08, a: 0.1, d: -0.08 }, return: { p: 0.1, a: 0.08, d: 0 }, lateNight: { p: -0.05, a: -0.1, d: 0 }, favorite: { p: 0.12, a: 0.08, d: 0.03 }, ignored: { p: -0.05, a: -0.03, d: -0.03 }, } as const satisfies Record export type MoodEvent = keyof typeof MOOD_EVENTS // 八分區(Mehrabian 的 PAD 八分類)→ 情緒標籤與顏文字 const OCTANTS: Record = { '+++': { label: '興奮', kaomoji: '(≧▽≦)' }, '++-': { label: '撒嬌', kaomoji: '(๑>ᴗ<๑)' }, '+-+': { label: '放鬆', kaomoji: '(´ᴗ`)' }, '+--': { label: '溫順', kaomoji: '(︶ᴗ︶)' }, '---': { label: '無聊', kaomoji: '(-_-)' }, '--+': { label: '不屑', kaomoji: '(¬_¬)' }, '-++': { label: '生氣', kaomoji: '(╬`益´)' }, '-+-': { label: '焦慮', kaomoji: '(;´Д`)' }, } const CALM = { label: '平靜', kaomoji: '(・ω・)' } const CALM_RADIUS = 0.1 export function moodLabel(m: Pad): { label: string; kaomoji: string } { if (Math.abs(m.p) < CALM_RADIUS && Math.abs(m.a) < CALM_RADIUS && Math.abs(m.d) < CALM_RADIUS) return CALM const s = (x: number) => (x >= 0 ? '+' : '-') return OCTANTS[s(m.p) + s(m.a) + s(m.d)]! } const KEYWORDS: [MoodEvent, RegExp][] = [ ['scold', /笨|白痴|廢物|爛|你很煩|閉嘴|stupid|useless|idiot/i], ['thanks', /謝謝|感謝|太棒|好棒|厲害|讚|thanks?|thank you|great job|awesome/i], ['success', /成功|完成了|通過|搞定|passed|done|fixed/i], ] /** 以使用者文字的關鍵字對應心情事件 */ export function keywordEvent(text: string): MoodEvent | null { for (const [ev, re] of KEYWORDS) if (re.test(text)) return ev return null }