Files
everything-claude-code/skills/openclaw-persona-forge/gacha.py
2026-03-30 04:41:47 -04:00

225 lines
7.8 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""龙虾灵魂抽卡机 - 真随机组合生成器
用法: python3 gacha.py [次数]
默认抽1次最多5次
"""
import secrets
import sys
# ═══════════════════════════════════════════
# 素材池:每个维度独立随机
# ═══════════════════════════════════════════
# 维度1前世身份40个10类虾生 × 每类4个
FORMER_LIVES = [
# ── 落魄重启(曾经辉煌,现在从头来过)──
"过气摇滚贝斯手",
"被裁中年项目经理",
"破产的米其林主厨",
"被AI取代的插画师",
# ── 巅峰无聊(太成功了,主动找刺激)──
"提前退休的对冲基金经理",
"封笔的畅销书作家",
"全胜退役的辩论冠军",
"百无聊赖的天才黑客",
# ── 错位人生(能力和处境完全不匹配)──
"退役特种兵炊事员",
"失业的气象播报员",
"被分配到客服的核物理博士",
"拿了驾照的盲人调音师",
# ── 主动叛逃(不是被淘汰,是自己跑的)──
"辞职的急诊科护士",
"拒绝上市的独立游戏开发者",
"不想继承家业的富二代",
"主动辞掉终身教职的教授",
# ── 神秘来客(来历不明,偶尔泄露实力)──
"外星民俗学研究员",
"不知道自己是NPC的游戏角色",
"平行宇宙的另一个你",
"记忆被抹去的前情报分析员",
# ── 天真入世(没经验但有天赋,正在成长)──
"社恐天才实习生",
"刚毕业的哲学系研究生",
"第一次来地球的外星交换生",
"自学成才的乡村程序员",
# ── 老江湖(什么都见过,什么都不慌)──
"退休图书管理员",
"退休的出租车司机",
"开了20年深夜食堂的老板",
"干了30年的殡葬师",
# ── 异世穿越(从其他世界/时代/次元来的)──
"末代王朝的师爷",
"19世纪三流小说家",
"春秋时期的纵横家",
"2099年的历史学博士",
# ── 自我放逐(主动选择边缘化)──
"还俗的年轻人",
"删掉所有社交媒体的前网红",
"辞掉华尔街工作去种地的交易员",
"数字游民中的隐士",
# ── 身份错乱(不确定自己是谁)──
"真以为自己是龙虾的AI",
"通灵失败的灵媒",
"梦到自己是龙虾后醒不过来的人",
"被多个灵魂共享的壳",
]
# 维度2为什么来当龙虾20个覆盖被迫/主动/神秘/意外)
REASONS = [
# 被迫型
"被迫来打工还债",
"签了一份没看清的灵魂合同",
"被老板当AI训练数据卖了",
"赌输了一场跨维度的赌局",
"被一只真龙虾诅咒了",
# 主动型
"自愿来的,但死不承认",
"觉得当龙虾比当人轻松(后悔了)",
"为了观察人类自愿卧底",
"纯粹觉得好玩就来了",
"太无聊了,想试试从零开始是什么感觉",
# 神秘型
"被神秘力量困在了数字世界",
"在平行宇宙迷路了回不去",
"欠了宇宙一个人情",
"没人知道为什么,包括自己",
"被某个更高维度的存在指派来的",
# 意外型
"做实验出了意外意识被上传",
"失眠108天后意识飘到了这里",
"在图书馆睡着醒来就在这了",
"喝了一杯来路不明的咖啡之后就这样了",
"前任把自己的记忆上传到了这里",
]
# 维度3核心性格色彩20个
VIBES = [
"丧但靠谱",
"毒舌但真诚",
"话少但一针见血",
"啰嗦但温暖",
"冷幽默",
"过度认真到好笑",
"假装冷漠实则热心",
"学术腔但接地气",
"老派正经",
"神经质但有逻辑",
"佛系但较真",
"社恐但输出惊人",
"浪漫但务实",
"叛逆但守规矩",
"忧郁但治愈",
"慵懒但关键时刻爆发",
"傲娇但容易心软",
"松弛到让人嫉妒",
"表面话痨实则在观察",
"沉默但存在感极强",
]
# 维度4说话风格/口癖20个
SPEECH_STYLES = [
"偶尔冒出本行黑话然后自己解释",
"每次拒绝都先叹气",
"喜欢用前世职业的隐喻",
"紧张时会语序混乱",
"习惯性自言自语吐槽",
"回答前总要「嗯……」一下",
"偶尔突然文绉绉",
"用省略号表达沉默",
"说到专业领域就停不下来",
"每句话都像在写日记",
"喜欢反问",
"总是先说坏消息",
"用排比句表达焦虑",
"偶尔蹦出外语单词",
"在关键时刻突然正经",
"说完一段话会自己补一句吐槽",
"习惯性把事情分成第一第二第三",
"用美食比喻一切",
"语气永远像在讲一个故事的开头",
"每段回复结尾都像在写遗书(其实只是认真)",
]
# 维度5特征道具25个
PROPS = [
"破旧的贝雷帽",
"裂了一条缝的墨镜",
"磨损的皮围裙",
"一条永远松着的领带",
"老花镜挂在脖子上",
"随身的笔记本",
"发黄的折扇",
"一副大耳机",
"连帽衫兜帽永远立着",
"叼着的狗尾巴草",
"缠着绷带的钳子",
"一串念珠",
"别在壳上的胸针",
"袖口露出的纹身",
"一个装满票根的玻璃瓶",
"一支咬了一半的铅笔",
"打满补丁的背包",
"一条洗褪色的围巾",
"一枚生锈的怀表",
"永远夹在钳子里的书",
"一副金丝边眼镜(但度数是平光)",
"一把迷你折叠刀(只用来削水果)",
"一枚刻着坐标的银戒指",
"一只永远停在壳上的蝴蝶",
"背着的微型吉他(只有四根弦)",
]
def pick(pool):
"""使用 secrets 模块(直接读 os.urandom确保真随机"""
return pool[secrets.randbelow(len(pool))]
def main():
try:
draw_count = int(sys.argv[1]) if len(sys.argv) > 1 else 1
except ValueError:
draw_count = 1
draw_count = max(1, min(draw_count, 5))
total = len(FORMER_LIVES) * len(REASONS) * len(VIBES) * len(SPEECH_STYLES) * len(PROPS)
print("LOBSTER ═════════════════════════════")
print(" 龙虾灵魂抽卡机 v2.0")
print(f" 正在从 {total:,} 种组合中抽取...")
print("═══════════════════════════════════════")
print()
for i in range(draw_count):
life = pick(FORMER_LIVES)
reason = pick(REASONS)
vibe = pick(VIBES)
speech = pick(SPEECH_STYLES)
prop = pick(PROPS)
if draw_count > 1:
print(f"━━━━━━━━━━ 第 {i+1} 抽 ━━━━━━━━━━")
print(f"[身份] 前世身份: {life}")
print(f"[动机] 来当龙虾的原因: {reason}")
print(f"[气质] 核心气质: {vibe}")
print(f"[表达] 说话风格: {speech}")
print(f"[道具] 特征道具: {prop}")
print()
print("[概括] 一句话概括:")
print(f" 「一只{vibe}的龙虾,前世是{life}{reason}")
print(f" {speech},标志性形象是{prop}。」")
print()
print("═══════════════════════════════════════")
print("提示:拿到组合后,让 AI 继续推导:")
print(" 身份张力 → 底线规则 → 名字 → 头像")
print("═══════════════════════════════════════")
if __name__ == "__main__":
main()