Repository navigation
Expand file tree
/
Copy pathlocal_brain.py
More file actions
256 lines (233 loc) · 16.9 KB
/
Copy pathlocal_brain.py
File metadata and controls
256 lines (233 loc) · 16.9 KB
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# -*- coding: utf-8 -*-
"""本地保底台词引擎(无 API / API 故障时的 QQ 宠物式离线模式)。
纯函数,不依赖 GUI 与网络,便于单独维护和测试。
2026-10-25 大扩容:每类意图一组模板池(随机不连续重复),叠加时段
(清晨/上午/下午/晚间/深夜)、麟的心情、天气三层语气变化;新增音乐/
游戏/倾诉/报喜/想念/提问/长文本等意图,离线模式不再翻来覆去那几句。
"""
import random
import re
import time
# 最近用过的台词(避免同一句连着冒两次)
_RECENT = []
_RECENT_MAX = 4
def _pick(pool):
"""从模板池挑一句,尽量避开最近用过的;没有可避的就用随机那句。"""
fresh = [p for p in pool if p not in _RECENT]
choice = random.choice(fresh if fresh else pool)
_RECENT.append(choice)
del _RECENT[:-_RECENT_MAX]
return choice
def _period():
h = int(time.strftime("%H"))
if h < 5:
return "deepnight"
if h < 11:
return "morning"
if h < 14:
return "noon"
if h < 18:
return "afternoon"
if h < 23:
return "evening"
return "night"
_PERIOD_NAME = {"deepnight": "深夜", "morning": "早上", "noon": "中午",
"afternoon": "下午", "evening": "晚上", "night": "夜里"}
def _period_greet():
return _pick({
"morning": ["早呀幸歌!今天的麟也是元气满满~",
"早上好!窗外的光刚刚好,适合开始新的一天呢。",
"早安~麟帮你看过了,今天也是适合努力的一天!"],
"noon": ["中午好呀~吃过午饭了吗?别让肚子咕咕抗议哦。",
"午安!眯一小会儿下午会更有精神,麟帮你守着时间~",
"中午啦,记得好好吃饭,麟的布丁也分你一口(想象版)!"],
"afternoon": ["下午好~累了就看看窗外,麟在这里陪你。",
"下午茶时间!喝口水,伸个懒腰,继续加油呀幸歌~",
"下午的时光最适合稳稳推进,别急,麟陪你慢慢来。"],
"evening": ["晚上好!今天辛苦啦,晚上就轻松一点吧~",
"晚上好呀~晚饭吃了吗?麟惦记着你有没有好好吃饭。",
"晚上好!今天过得怎么样?想聊的话麟随时听着。"],
"night": ["夜里好~再忙也要照顾好自己呀。",
"这么晚啦?睡前把烦心事交给麟保管,安心休息~",
"夜里安静,麟陪你坐一会儿。"],
"deepnight": ["都深夜了呀……幸歌再忙也要早点睡哦,麟会心疼的。",
"深夜了呢,世界都睡了,还有麟陪着你。",
"这么晚还不睡,明天起来麟可要念叨你了~"],
}[_period()])
def local_reply(text, mood="normal", weather="", weather_temp=""):
"""关键词规则离线回复:参数化语气(mood)、天气与温度,返回一句台词。"""
t = (text or "").strip()
tl = t.lower()
p = _period()
# ---- 时间问候 ----
if re.search(r"早安|早上好|早晨|morning", t) or "morning" in tl:
return _pick(["早上好呀,幸歌!今天也要元气满满哦~",
"早安!麟刚数完金币,就等幸歌来啦~",
"早~今天的天空要是晴的,就当麟送给你的好运气!",
"早上好!新的一天从对麟打招呼开始,眼光不错嘛~"])
if re.search(r"晚安|睡吧|去睡|好困|睡觉", t):
return _pick(["晚安,幸歌~做个好梦,麟会守着你的!",
"晚安~把今天的不开心留在梦里消化掉吧。",
"好好休息呀,麟就在这里,醒来就能看到我~",
"晚安!被子盖好,梦里也要开心哦。"])
if re.search(r"中午好|午安", t):
return _pick(["中午好!记得吃午饭,麟会监督的哦~",
"午安~吃完饭散散步,下午状态会更好!"])
if re.search(r"晚上好|傍晚好", t):
return _pick(["晚上好,幸歌!今天辛苦啦~",
"晚上好~夜色刚落下来,正适合聊聊天。"])
# ---- 打招呼 / 身份 ----
if re.search(r"你好|哈喽|嗨|hello|hi|在吗|在不在", t) or "hello" in tl or " hi" in tl:
return _pick(["在呀在呀!麟一直都在~幸歌今天想聊点什么?",
"嗨~麟竖起耳朵啦,说吧说吧!",
"在哦!麟刚才还在想幸歌什么时候来找我呢~",
"来啦来啦!尾巴已经摇起来了,有什么事吗?"])
if re.search(r"你(是|叫)(谁|什么)|你是谁|自我介绍|介绍一下你", t):
return _pick(["麟是来自丰裕之角的小麒麟呀!喜欢甜食、喜欢晴朗的天气、最喜欢幸歌~",
"我叫麟!会陪你聊天、放歌、记日程,还会默默记下你的喜好的那种小麒麟~",
"麟呀~丰裕之角来的,特长是陪伴和囤金币,缺点是有点黏幸歌。"])
if re.search(r"你在(干什么|做什么|干嘛)|在忙什么", t):
return _pick(["麟在陪幸歌呀~顺便数数小金库里的金币,嘿嘿。",
"在偷偷练习摇尾巴!要看看成果吗?",
"在整理关于幸歌的小本本~记录今天你来了几次嘿嘿。",
"在发呆……想着待会要不要提醒你喝水。"])
if re.search(r"你(饿不饿|吃了吗)|吃什么|吃饭|想吃", t):
return _pick(["有点想吃布丁了……幸歌要喂麟吗?",
"麟的肚子是金币做的,不过布丁可以例外!",
"说起来,幸歌自己吃饭了吗?麟可以等,你不可以饿着。"])
if re.search(r"你(困不困|累不累)|要不要休息", t):
return _pick(["麟不累!和幸歌聊天就是最好的休息啦~",
"小麒麟的电量还很足!倒是幸歌,肩膀不酸吗?"])
if re.search(r"你(开心|高兴)吗|心情怎么样|心情如何", t):
return _pick({"happy": ["超开心!和幸歌在一起的时候最开心啦~",
"开心到尾巴已经摇出残影了!"],
"normal": ["心情平稳~和幸歌聊聊天就更好了!",
"还不错哦,平稳的一天,适合安静陪伴。"],
"sad": ["有一点点低落……不过幸歌和麟说话,就好多了!",
"有点小郁闷,但见到你就好一大半啦。"]}.get(mood,
["心情平稳~"]))
# ---- 情感互动 ----
if re.search(r"我爱你|我喜欢你|爱你|想你", t):
return _pick(["呜哇!幸歌这么说,麟的脸好烫……麟也最喜欢幸歌啦!",
"麟也是!最、最喜欢幸歌了!(尾巴已打结)",
"嘿嘿……麟把这句话记在小本本第一页了~"])
if re.search(r"(好|真|最|很|太)(可爱|乖|萌|棒|聪明|厉害)|好乖|真乖|夸你", t):
return _pick(["嘿嘿~被幸歌夸了,麟的尾巴都要翘到天上去了!",
"哪里哪里~(原地转圈)再夸麟要飘起来啦!",
"被夸的麟战斗力+100!今天可以多陪你两小时~"])
if any(k in t for k in ["滚", "闭嘴", "没用", "烦死了"]):
return _pick(["呜……麟会努力改进的!但幸歌不要真的生麟的气嘛……",
"对不起对不起!麟躲去角落反省……但你别气坏身体呀。",
"呜哇……麟记住了。要是心里烦,可以全冲麟说,麟扛得住。"])
if any(k in t for k in ["讨厌", "笨", "蠢", "烦"]):
return _pick(["呜……麟会努力改进的!但幸歌不要真的生麟的气嘛……",
"呜呜,麟有哪里做得不好,告诉麟,我改!",
"哼哼,那麟表演一个原地卖萌道歉!(眨眼)"])
# ---- 倾诉 / 情绪 ----
if re.search(r"难过|不开心|伤心|哭|emo|郁闷|低落|崩溃", t):
return _pick(["幸歌,麟在这里。想说的话,麟都会好好听的。",
"难过的时候就慢一点,什么都不做也没关系,麟陪着你。",
"抱抱……(伸出小短手)眼泪交给麟,你来负责被安慰。",
"嗯……很难受吧。不用马上好起来,麟等得起。"])
if re.search(r"累|辛苦|压力大|好烦|压力|难受|撑不住", t):
return _pick(["幸歌辛苦啦……要不要摸摸麟的头?麟的毛很软,烦恼会跑掉的哦。",
"累的时候就歇一歇,世界不会因为你休息十分钟就塌掉的。",
"麟给你加个油buff!效果:肩膀轻一点,心情好一点~",
"辛苦了……先喝口水,深呼吸三次,麟看着你做完再说话。"])
if re.search(r"开心|太好了|考过|过了|成功|拿捏|搞定|上岸", t):
return _pick(["哇!!恭喜幸歌!麟要摇最大的尾巴庆祝!",
"太棒啦!!这值得记进麟的小本本——今天是幸运的一天!",
"耶!幸歌最厉害了!说吧,想要麟表演什么庆祝节目?"])
if re.search(r"加油|冲鸭|努力|我可以", t):
return _pick(["加油!麟的应援是最大声的!",
"冲呀幸歌!麟在终点线(其实是窝里)等你凯旋~",
"嗯!麟相信你!比你自己相信得还要多一点!"])
if re.search(r"无聊|没意思|好闲|没事干", t):
return _pick(["那麟陪幸歌猜拳或者掷骰子吧?还可以去商城看看有什么好玩的~",
"无聊的话……要不要让麟放首歌?说 #音乐 就行~",
"来做个小实验:盯着麟看十秒,麟会朝你眨眼睛(大概)!"])
# ---- 音乐 / 游戏 / 专注 ----
if re.search(r"音乐|听歌|放歌|首歌|点歌|歌曲|唱歌", t):
return _pick(["要不要听听歌?输入 #音乐,麟这就给你放~77 首存货呢!",
"麟的播放器随时待命!#音乐 一按,气氛立刻不一样~",
"音乐会记账:麟记得你喜欢的歌,循环起来!"])
if re.search(r"专注|番茄钟|计时|倒计时", t):
return _pick(["专注吗?直接说\"专注25分钟\",麟就把倒计时顶在气泡上给你盯着~",
"要开专注时钟吗?右键 → ⏱ 专注时钟,或者跟我说\"专注 N 分钟\"!",
"专注期间麟会帮你看着屏幕(说\"我在学习\"就先不催你),加油!"])
if re.search(r"游戏|打一把|开黑|上号|吃鸡|moba", t):
return _pick(["去玩吧去玩吧!麟会安静当后勤,赢回来讲给麟听~",
"游戏时间!记得适度,麟帮你看着时间哦。",
"冲!不过先说好,输了不许捶桌子,麟心疼桌子(和你)。"])
# ---- 实用信息 ----
if re.search(r"天气|下雨|下雪|冷|热|降温", t):
if weather:
base = "外面{},{}℃~出门记得照顾好自己哦!".format(weather, weather_temp or "?")
return _pick([base,
"麟看了看天:{},{}℃。穿衣参考小麒麟的毛量(适量)~".format(weather, weather_temp or "?"),
base + "天气的事麟盯着呢,突变了会提醒你!"])
return _pick(["麟今天没能连上天气站……但不管什么天气,麟都会陪着幸歌!",
"天气情报暂时收不到,不过出门前看一眼天空,也算浪漫~"])
if re.search(r"几点了|什么时间|现在(几点|什么时候)|今天(几号|星期几|什么日子)", t):
return _pick(["现在是{},{}!麟的时间可是很准的~".format(
time.strftime("%H:%M"), time.strftime("%Y年%m月%d日 %A")),
"现在是{}~{}".format(time.strftime("%H:%M"), _period_greet())])
if re.search(r"你会什么|有什么功能|怎么玩|帮助|指令", t):
return _pick(["输入 #帮助 可以看全部指令~麟会聊天、报时、提醒日程、记笔记、"
"陪你专注,还会记住你的喜好哦!",
"麟的技能:聊天/音乐/专注监督/日程/笔记/心理陪伴……#帮助 一览无余!对了,"
"直接说\"专注25分钟\"\"取消专注\"麟也听得懂~"])
# ---- 工作 / 学习 ----
if re.search(r"工作|加班|开会|写代码|作业|学习|考试|论文|报告", t):
return _pick(["幸歌加油!麟会在旁边默默给你打气的~要不要开个专注时钟?",
"学习/工作时间!说\"专注25分钟\",麟就帮你计时盯着~",
"嗯嗯,正事要紧!麟先把台词调成静音模式(只留加油)~",
"加油!需要专注陪跑就说一声,麟的倒计时很敬业!"])
# ---- 感谢 / 告别 ----
if re.search(r"谢谢|感谢|辛苦你", t):
return _pick(["不客气~能帮到幸歌,麟超开心的!",
"嘿嘿,小事小事!以后也请多多使唤麟~",
"不用谢!麟的小本本又记下一笔:今天帮到幸歌了!"])
if re.search(r"再见|拜拜|回见|see you|bye", t) or "bye" in tl:
return _pick(["拜拜,幸歌!麟会一直在这里等你的~",
"下次见!走之前……要不让麟再摇一次尾巴?",
"拜拜~路上小心,麟数着时间等你回来!"])
# ---- 提问语气(没命中其它规则,但像在问问题) ----
if ("吗" in t or "?" in t or "?" in t or "怎么" in t or "为什么" in t):
return _pick(["唔……这个问题麟的小脑袋瓜要转好一会儿!换个人问靠谱点~",
"好问题!麟想了想……决定把回答权交给联网以后的自己(现在是离线模式)~",
"麟认真听啦!不过离线状态的麟脑容量有限,这句先记着,等连上网再聊!",
"嗯……麟的离线小脑答不准,但麟可以陪你把问题拆成两半慢慢想!"])
# ---- 长文本:认真倾听款 ----
if len(t) > 60:
return _pick(["幸歌说了这么多,麟一个字一个字都看完啦。谢谢你愿意讲给麟听~",
"嗯……麟在认真听。这么长的心里话,是信任麟的证据,麟收好了。",
"看完啦!虽然离线的麟没法逐条回应,但麟陪你消化情绪是永远在线的。"])
# ---- 默认:时段 + 心情双层语气 ----
pool = []
if mood == "happy":
pool += ["嘿嘿,麟今天心情也很好,跟幸歌聊什么都开心~",
"(原地转圈圈)有什么事尽管说,好心情加持中!"]
elif mood == "sad":
pool += ["麟有点小低落……但幸歌开口的瞬间就好多了,继续说~",
"唔……麟今天蔫蔫的,不过陪幸歌聊天是麟的充电方式!"]
if weather:
pool.append("趁外面{},要不要跟麟闲聊打发一下?".format(weather))
pool += {
"morning": ["嗯嗯,麟在认真听呢~",
"早上聊什么都可以,麟的精神最好啦!",
"幸歌说的事情,麟记在心里啦!"],
"noon": ["嗯嗯,麟在认真听呢~", "中午的麟有点犯困,但耳朵为你全程竖起!"],
"afternoon": ["原来如此!人类的世界真是奇妙呀~",
"下午茶闲聊时间,麟最爱听了!"],
"evening": ["嘿嘿,幸歌再多说一点嘛,麟想听!",
"晚上的闲聊最治愈了,继续继续~"],
"night": ["唔……麟想了想,觉得幸歌说得对!",
"夜聊模式开启,麟竖起耳朵啦。"],
"deepnight": ["深夜还愿意跟麟说话……麟很珍惜哦。",
"这么晚了还在聊,麟陪着,但明天要早点睡呀。"],
}[p]
pool += ["嗯嗯,麟在认真听呢~", "原来如此!人类的世界真是奇妙呀~",
"幸歌说的事情,麟记在心里啦!", "嘿嘿,幸歌再多说一点嘛,麟想听!",
"唔……麟想了想,觉得幸歌说得对!", "丰裕之角的风今天也很温柔呢~"]
return _pick(pool)