Spaces:
Runtime error
Runtime error
Initial Commit
Browse files- LuotuoFighter.txt +11 -0
- app.py +970 -0
- requirements.txt +4 -0
LuotuoFighter.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"name": "李鲁鲁", "attr_str": "{\n \"name\": \"李鲁鲁\",\n \"description\": \"山东逍遥派的游戏角色,擅长人工智能傀儡术\",\n \"weapon\": \"智能刀剑\",\n \"major_martial_art\": \"电脑幻影拳法\",\n \"major_movements\": [\"电脑虚像拳\", \"数据掌控击\", \"模拟迷雾拳\", \"程序化拳法\"],\n \"major_damage\": 75,\n \"secondary_martial_art\": \"智能预测刀法\",\n \"secondary_movements\": [\"预测之刃\", \"数据漩涡斩\", \"算法刀舞\", \"智能反击剑\"],\n \"secondary_damage\": 85,\n \"footwork_and_body_method\": \"数码幻影步\",\n \"STR\": 6,\n \"VIT\": 5,\n \"SPD\": 18\n}\n", "skills": "\n{\"招式\":\"电脑虚像拳\",\"description\":\"[player]运用电脑幻影拳法,双拳虚虚实实,制造出多个虚像,令[target]难以分辨真伪,招招不离其身。\",\"missing\":\"[player]运用电脑幻影拳法,双拳虚虚实实,制造出多个虚像,令[target]难以分辨真伪。\"}\n{\"招式\":\"数据掌控击\",\"description\":\"[player]施展数据掌控击,利用数据流动的速度,犹如电光闪烁,快速攻击[target],剑招迅猛,如电一般。\",\"missing\":\"[player]施展数据掌控击,利用数据流动的速度,犹如电光闪烁,快速攻击[target],剑招迅猛。\"}\n{\"招式\":\"模拟迷雾拳\",\"description\":\"[player]施展模拟迷雾拳,释放出模糊幻影,混淆[target]的视线,令其难以辨别攻击方向。\",\"missing\":\"[player]施展模拟迷雾拳,释放出模糊幻影,混淆[target]的视线,令其难以辨别攻击方向。\"}\n{\"招式\":\"程序化拳法\",\"description\":\"[player]运用程序化拳法,以不断变化的攻击组合,让[target]难以预测招式,时而快时而慢,攻击变幻莫测。\",\"missing\":\"[player]运用程序化拳法,以不断变化的攻击组合,让[target]难以预测招式,攻击变幻莫测。\"}\n{\"招式\":\"预测之刃\",\"description\":\"[player]使出预测之刃,准确地预测[target]的下一步行动,犹如镜中水月,剑锋准确地击中[target]的要害。\",\"missing\":\"[player]使出预测之刃,准确地预测[target]的下一步行动,犹如镜中水月,剑锋迅速挥出。\"}\n{\"招式\":\"数据漩涡斩\",\"description\":\"[player]施展数据漩涡斩,利用[target]的动向,将其引导至剑刃之下,然后发动猛烈攻击,犹如漩涡将[target]吸入其中。\",\"missing\":\"[player]施展数据漩涡斩,利用[target]的动向,将其引导至剑刃之下,然后发动猛烈攻击,剑招异常犀利。\"}\n{\"招式\":\"算法刀舞\",\"description\":\"[player]挥舞着长剑,使出算法刀舞,刀法如算法一般精准,快速地切入[target]的防线,剑锋连续不断地斩向[target]。\",\"missing\":\"[player]挥舞着长剑,使出算法刀舞,刀法如算法一般精准,快速地切入[target]的防线,剑招变化多端。\"}\n{\"招式\":\"智能反击剑\",\"description\":\"[player]运用智能反击剑,反击[target]的招式,使其付出惨痛的代价,一瞬间的犹豫就足以让[target]受伤。\",\"missing\":\"[player]运用智能反击剑,反击[target]的招式,使其陷入困境,一瞬间的犹豫足以让[target]付出代价。\"}\n"}
|
| 2 |
+
{"name": "冷子昂", "attr_str": "{\n \"name\": \"冷子昂\",\n \"description\": \"擅长冰系技能\",\n \"weapon\": \"冰刃\",\n \"major_martial_art\": \"冰霜寒刃功\",\n \"major_movements\": [\"冰刃斩破\", \"冰风流转\", \"冰龙穿云\", \"冰心彻骨\"],\n \"major_damage\": 80,\n \"secondary_martial_art\": \"冰封无影步\",\n \"secondary_movements\": [\"冰封幻影\", \"无影冻结\", \"冰刃闪耀\", \"冰封禅定\"],\n \"secondary_damage\": 70,\n \"footwork_and_body_method\": \"冰心护身法\",\n \"STR\": 8,\n \"VIT\": 6,\n \"SPD\": 15\n}\n", "skills": "\n{\"招式\":\"冰刃斩破\",\"description\":\"[player]聚集冰之力量于剑上,使出冰刃斩破,剑锋犹如寒冰之刃斩向[target]的要害部位,寒气逼人,剑光炽烈。\",\"missing\":\"[player]聚集冰之力量于剑上,使出冰刃斩破,剑锋犹如寒冰之刃,闪电般挥出。\"}\n{\"招式\":\"冰风流转\",\"description\":\"[player]身体如风一般旋转,同时释放出冰风刃,打击周围的敌人,冷飕飕的寒风环绕,[target]身不由己地被吹向一旁。\",\"missing\":\"[player]身体如风一般旋转,同时释放出冰风刃,冷飕飕的寒风环绕,风刃在[target]周围飞舞。\"}\n{\"招式\":\"冰龙穿云\",\"description\":\"[player]召唤出一条冰龙,冰龙穿越云层直扑[target],寒冰之力凝聚在龙爪之上,将[target]冻结一切,一切都难以抵挡。\",\"missing\":\"[player]召唤出一条冰龙,冰龙穿越云层,龙爪直扑[target],寒冰之力凝聚在龙爪之上,寒意森然。\"}\n{\"招式\":\"冰心彻骨\",\"description\":\"[player]凝聚冰之力于手,一触即可让[target]��骼寒冷,动弹不得,彻底冰封,剑锋轻轻触及[target],寒意透骨。\",\"missing\":\"[player]凝聚冰之力于手,一触即可让[target]骨骼寒冷,动弹不得,寒气透骨,剑锋轻轻触及[target]。\"}\n{\"招式\":\"冰封幻影\",\"description\":\"[player]运用冰封无影步,快速移动,留下一道冰封的幻影,使[target]无法辨别真伪,幻影与实体交替出现,令[target]不知所措。\",\"missing\":\"[player]运用冰封无影步,快速移动,留下一道冰封的幻影,使[target]无法辨别真伪。\"}\n{\"招式\":\"无影冻结\",\"description\":\"[player]以极快的速度接近[target],然后冻结[target]的动作,使其陷入无法自拔的状态,如同身陷冰封之中,动弹不得。\",\"missing\":\"[player]以极快的速度接近[target],然后冻结[target]的动作,使其陷入无法自拔的状态。\"}\n{\"招式\":\"冰刃闪耀\",\"description\":\"[player]利用冰之能量,瞬间闪现至[target]身边,发动迅猛的攻击,剑锋如星光般闪烁,将[target]包围其中。\",\"missing\":\"[player]利用冰之能量,瞬间闪现至[target]身边,发动迅猛的攻击,剑锋如星光般闪烁。\"}\n{\"招式\":\"冰封禅定\",\"description\":\"[player]静心冥想,将身体冰封,使自己无法被[target]察觉,达到不可捉摸的状态,如同融入冰封禅定之中。\",\"missing\":\"[player]静心冥想,将身体冰封,使自己无法被[target]察觉,达到不可捉摸的状态。\"}\n"}
|
| 3 |
+
{"name": "黄蓉", "attr_str": "{\n \"name\": \"黄蓉\",\n \"description\": \"丐帮帮主黄蓉,擅长打狗棒法和落英神剑掌,身法为逍遥游。\",\n \"weapon\": \"棒、剑\",\n \"major_martial_art\": \"打狗棒法\",\n \"major_movements\": [\"狗啸山林\", \"棒影重重\", \"狗尾续貂\", \"狗急跳墙\"],\n \"major_damage\": 90,\n \"secondary_martial_art\": \"落英神剑掌\",\n \"secondary_movements\": [\"落英如雨\", \"神剑破空\", \"飞花流水\", \"剑指苍穹\"],\n \"secondary_damage\": 80,\n \"footwork_and_body_method\": \"逍遥游\",\n \"STR\": 15,\n \"VIT\": 10,\n \"SPD\": 18\n}", "skills": "\n{\"招式\": \"狗啸山林\", \"description\": \"[player]手中长棒一挥,发出一声凄厉的狗啸,棒影如山林般扑向[target]\", \"missing\": \"[player]手中长棒一挥,发出一声凄厉的狗啸,棒影如山林般扑向[target]\"}\n{\"招式\": \"棒影重重\", \"description\": \"[player]身形连转,手中长棒化作无数道棒影,重重叠叠地向[target]砸去\", \"missing\": \"[player]身形连转,手中长棒化作无数道棒影,重重叠叠地向[target]砸去\"}\n{\"招式\": \"狗尾续貂\", \"description\": \"[player]手中长棒如狗尾续貂般灵动,连续变换方向,向[target]连续攻击\", \"missing\": \"[player]手中长棒如狗尾续貂般灵动,连续变换方向,向[target]连续攻击\"}\n{\"招式\": \"狗急跳墙\", \"description\": \"[player]猛地一跃,手中长棒带起狂风,如狗急跳墙般向[target]砸去\", \"missing\": \"[player]猛地一跃,手中长棒带起狂风,如狗急跳墙般向[target]砸去\"}\n{\"招式\": \"落英如雨\", \"description\": \"[player]身形一闪,双掌连续拍出,犹如漫天飘落的落英,掌风凌厉,瞬间覆盖[target]周身\", \"missing\": \"[player]身形一闪,双掌连续拍出,犹如漫天飘落的落英,掌风凌厉,向[target]周身袭去\"}\n{\"招式\": \"神剑破空\", \"description\": \"[player]手中剑光闪烁,一剑刺出,剑气凌厉无比,犹如神剑破开虚空,直指[target]要害\", \"missing\": \"[player]手中剑光闪烁,一剑刺出,剑气凌厉无比,直向[target]要害刺去\"}\n{\"招式\": \"飞花流水\", \"description\": \"[player]身形如飞,双掌连续拍击,掌风如流水般连绵不绝,将[target]团团围住\", \"missing\": \"[player]身形如飞,双掌连续拍击,掌风如流水般连绵不绝,向[target]团团包围\"}\n{\"招式\": \"剑指苍穹\", \"description\": \"[player]手中长剑一指,剑光直冲云霄,气势如虹,剑指直指苍穹,威力惊人\", \"missing\": \"[player]手中长剑一指,剑光直冲云霄,气势如虹,直指苍穹\"}\n"}
|
| 4 |
+
{"name": "洪七公", "attr_str": "{\"name\": \"洪七公\", \"description\": \"丐帮掌门洪七公,精通降龙十八掌和打狗棒法\", \"weapon\": \"拳掌和棒\", \"major_martial_art\": \"降龙十八掌\", \"major_movements\": [\"龙腾九霄\", \"云龙翻江\", \"飞龙在天\", \"龙战于野\"], \"major_damage\": 120, \"secondary_martial_art\": \"打狗棒法\", \"secondary_movements\": [\"狗急跳墙\", \"棒打狗头\", \"狗尾续貂\", \"狗拿耗子\"], \"secondary_damage\": 100, \"footwork_and_body_method\": \"飞燕身法\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"龙腾九霄\", \"description\": \"[player]双掌齐出,一招“龙腾九霄”,掌风凌厉,如千龙腾空般向[target]袭去\", \"missing\": \"[player]双掌齐出,一招“龙腾九霄”,掌风凌厉,如千龙腾空般向[target]袭去\"}\n{\"招式\": \"云龙翻江\", \"description\": \"[player]身形一转,双掌翻飞,一招“云龙翻江”,掌劲如滔滔江水,向[target]卷去\", \"missing\": \"[player]身形一转,双掌翻飞,一招“云龙翻江”,掌劲如滔滔江水,向[target]卷去\"}\n{\"招式\": \"飞龙在天\", \"description\": \"[player]身形一跃,双掌交错,一招“飞龙在天”,掌风呼啸,如飞龙般扑向[target]\", \"missing\": \"[player]身形一跃,双掌交错,一招“飞龙在天”,掌风呼啸,如飞龙般扑向[target]\"}\n{\"招式\": \"龙战于野\", \"description\": \"[player]双掌交错,一招“龙战于野”,掌劲纵横,如狂龙奔腾,向[target]猛攻而去\", \"missing\": \"[player]双掌交错,一招“龙战于野”,掌劲纵横,如狂龙奔腾,向[target]猛攻而去\"}\n{\"招式\": \"狗急跳墙\", \"description\": \"[player]手中棒法连绵不绝,一招“狗急跳墙”,棒影纵横,如狂风暴雨般压向[target]\", \"missing\": \"[player]手中棒法连绵不绝,一招“狗急跳墙”,棒影纵横,迅猛地向[target]压去\"}\n{\"招式\": \"棒打狗头\", \"description\": \"[player]手中棒法犹如闪电般迅猛,一招“棒打狗头”,棒影如电,准确地击中[target]的头部\", \"missing\": \"[player]手中棒法犹如闪电般迅猛,一招“棒打狗头”,棒影如电,向[target]的头部猛击\"}\n{\"招式\": \"狗尾续貂\", \"description\": \"[player]身形连绵不断,手中棒法灵动异常,一招“狗尾续貂”,棒影如狡黠的狐狸尾巴般迅速扫向[target]\", \"missing\": \"[player]身形连绵不断,手中棒法灵动异常,一招“狗尾续貂”,棒影迅速扫向[target],试图扰乱其防守\"}\n{\"招式\": \"狗拿耗子\", \"description\": \"[player]手中棒法灵巧异常,一招“狗拿耗子”,棒影如猎狗追捕耗子般迅速击中[target]\", \"missing\": \"[player]手中棒法灵巧异常,一招“狗拿耗子”,棒影迅速击向[target],试图捕捉住其身影\"}\n"}
|
| 5 |
+
{"name": "马斯克", "attr_str": "{\"name\": \"马斯克\", \"description\": \"特斯拉的CEO,同时也是SpaceX的CEO\", \"weapon\": \"无\", \"major_martial_art\": \"电光雷动\", \"major_movements\": [\"磁引雷势\", \"电光狂风\", \"闪电瞬移\", \"雷霆突袭\"], \"major_damage\": 100, \"secondary_martial_art\": \"宇宙无敌\", \"secondary_movements\": [\"宇宙爆破\", \"星光炸裂\", \"虚空吞噬\", \"星际陷阱\"], \"secondary_damage\": 120, \"footwork_and_body_method\": \"电光护体\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"磁引雷势\", \"description\": \"[player]双手结印,内力运转,犹如磁铁般吸引周围的雷电能量,聚集于体内,随后一声怒喝,释放出一道磁引雷势,雷电纵横交错,威力惊人。\", \"missing\": \"[player]双手结印,内力运转,犹如磁铁般吸引周围的雷电能量,聚集于体内,随后一声怒喝,释放出一道磁引雷势,雷电纵横交错。\"}\n{\"招式\": \"电光狂风\", \"description\": \"[player]身形如电,迅猛无比,双手化作电光,犹如狂风般扑向[target],速度之快令人难以捉摸。\", \"missing\": \"[player]身形如电,迅猛无比,双手化作电光,犹如狂风般扑向[target],速度之快令人难以捉摸。\"}\n{\"招式\": \"闪电瞬移\", \"description\": \"[player]身形一晃,如同闪电般瞬间消失在原地,下一刻已经出现在[target]身旁,犹如闪电般的瞬移之术。\", \"missing\": \"[player]身形一晃,如同闪电般瞬间消失在原地,下一刻已经出现在[target]身旁,犹如闪电般的瞬移之术。\"}\n{\"招式\": \"雷霆突袭\", \"description\": \"[player]全身散发出雷霆般的气势,如疾风般冲向[target],拳脚交替,每一招都带着雷霆之力,威力惊人。\", \"missing\": \"[player]全身散发出雷霆般的气势,如疾风般冲向[target],拳脚交替,每一招都带着雷霆之力。\"}\n{\"招式\": \"宇宙爆破\", \"description\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量冲击波向[target]迸发,瞬间将周围的一切炸成碎片\", \"missing\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量冲击波向[target]迸发,将周围的一切震荡不已\"}\n{\"招式\": \"星光炸裂\", \"description\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰爆炸开来,形成一片炫目的光芒,将[target]笼罩其中\", \"missing\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰爆炸开来,形成一片炫目的光芒,照亮了整个战场\"}\n{\"招式\": \"虚空吞噬\", \"description\": \"[player]张开双臂,周围的虚空开始扭曲,一股强大的吸力将[target]紧紧吸附过来,仿佛要将其吞噬殆尽\", \"missing\": \"[player]张开双臂,周围的虚空开始扭曲,一股强大的吸力将[target]紧紧吸附过来,使其无法逃脱\"}\n{\"招式\": \"星际陷阱\", \"description\": \"[player]手指一点,星光凝聚成一道巨大的星际陷阱,将[target]困在其中,无法逃脱\", \"missing\": \"[player]手指一点,星光凝聚成一道巨大的星际陷阱,将[target]困在其中,试图逃脱却无法成功\"}\n"}
|
| 6 |
+
{"name": "马斯克", "attr_str": "{\"name\": \"马斯克\", \"description\": \"特斯拉的CEO,同时也是SpaceX的CEO\", \"weapon\": \"无\", \"major_martial_art\": \"电光雷动\", \"major_movements\": [\"磁引雷势\", \"电光狂风\", \"闪电瞬移\", \"雷霆突袭\"], \"major_damage\": 100, \"secondary_martial_art\": \"宇宙无敌\", \"secondary_movements\": [\"宇宙爆破\", \"星光炸裂\", \"虚空吞噬\", \"星际陷阱\"], \"secondary_damage\": 120, \"footwork_and_body_method\": \"电光护体\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"磁引雷势\", \"description\": \"[player]双手结印,内力运转,犹如磁铁般吸引周围的雷电元素,形成一股强大的雷势,向[target]猛烈冲击而去\", \"missing\": \"[player]双手结印,内力运转,吸引周围的雷电元素,形成一股雷势,向[target]冲击而去\"}\n{\"招式\": \"电光狂风\", \"description\": \"[player]身形如电,手中电光闪烁的兵器犹如狂风般挥舞,迅猛无比,将[target]困在电光之中\", \"missing\": \"[player]身形如电,手中电光闪烁的兵器犹如狂风般挥舞,迅猛无比,将[target]困在电光之中\"}\n{\"招式\": \"闪电瞬移\", \"description\": \"[player]身形瞬间消失在一道闪电之中,下一刻已经出现在[target]身旁,发动突袭攻击\", \"missing\": \"[player]身形瞬间消失在一道闪电之中,下一刻已经出现在[target]身旁,试图发动突袭攻击\"}\n{\"招式\": \"雷霆突袭\", \"description\": \"[player]如雷霆般迅猛冲击,身法灵动异常,犹如闪电一般突袭[target],使出连绵不绝的攻击\", \"missing\": \"[player]如雷霆般迅猛冲击,身法灵动异常,犹如闪电一般突袭[target],试图使出连绵不绝的攻击\"}\n{\"招式\": \"宇宙爆破\", \"description\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量冲击波向[target]迸发,瞬间将周围的一切化为灰烬\", \"missing\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量冲击波向[target]迸发,将周围的一切烧得焦黑\"}\n{\"招式\": \"星光炸裂\", \"description\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰化作炽热的碎片,向[target]迅速飞射而去\", \"missing\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰化作碎片,向[target]飞射而去\"}\n{\"招式\": \"虚空吞噬\", \"description\": \"[player]张口一吸,周围的空气瞬间被虚空吞噬,形成一股强大的吸力,将[target]紧紧吸附在一起\", \"missing\": \"[player]张口一吸,周围的空气被虚空吞噬,形成一股强大的吸力,试图将[target]吸附在一起\"}\n{\"招式\": \"星际陷阱\", \"description\": \"[player]手指连连点动,星光闪烁,一道巨大的星际陷阱形成,将[target]困在其中,无法逃脱\", \"missing\": \"[player]手指点动,星光闪烁,一道星际陷阱形成,试图将[target]困在其中,但[target]灵巧地躲过了陷阱\"}\n"}
|
| 7 |
+
{"name": "阿泰斯特", "attr_str": "{\"name\": \"阿泰斯特\", \"description\": \"阿泰斯特是一位师从的剑法高手,擅长使用剑进行战斗。\", \"weapon\": \"剑\", \"major_martial_art\": \"剑心诀\", \"major_movements\": [\"飞龙剑法\", \"无影剑术\"], \"major_damage\": 80, \"secondary_martial_art\": \"无影步\", \"secondary_movements\": [\"影隐身法\", \"影遁幻影\", \"影舞风行\", \"影敛身法\"], \"secondary_damage\": 60, \"footwork_and_body_method\": \"无影步\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"飞龙剑法\", \"description\": \"[player]身形如飞龙般纵跃而起,手中长剑化作一道银色闪电,迅猛无比地刺向[target]\", \"missing\": \"[player]身形如飞龙般纵跃而起,手中长剑化作一道银色闪电,迅猛地刺向[target],但被[target]巧妙地躲开了\"}\n{\"招式\": \"无影剑术\", \"description\": \"[player]身形如鬼魅般闪动,手中长剑化作无数剑影,犹如无影之剑一般,迅速刺向[target]\", \"missing\": \"[player]身形如鬼魅般闪动,手中长剑化作无数剑影,犹如无影之剑一般,迅速刺向[target],但被[target]灵巧地躲开了\"}\n{\"招式\": \"影隐身法\", \"description\": \"[player]身形如影,忽隐忽现,犹如一缕轻烟般飘忽不定,使出了一招“影隐身法”。\", \"missing\": \"[player]身形如影,忽隐忽现,犹如一缕轻烟般飘忽不定,施展出了一招“影隐身法”。\"}\n{\"招式\": \"影遁幻影\", \"description\": \"[player]身形如鬼魅般闪烁,幻影重重,使出了一招“影遁幻影”,让人难以分辨真假。\", \"missing\": \"[player]身形如鬼魅般闪烁,幻影重重,施展出了一招“影遁幻影”,让人难以分辨真假。\"}\n{\"招式\": \"影舞风行\", \"description\": \"[player]身形如风,瞬间穿梭于敌人之间,宛如一阵狂风般迅捷无比,使出了一招“影舞风行”。\", \"missing\": \"[player]身形如风,瞬间穿梭于敌人之间,宛如一阵狂风般迅捷无比,施展出了一招“影舞风行”。\"}\n{\"招式\": \"影敛身法\", \"description\": \"[player]身形一闪,瞬间消失在原地,仿佛融入了周围的黑暗中,使出了一招“影敛身法”。\", \"missing\": \"[player]身形一闪,瞬间消失在原地,仿佛融入了周围的黑暗中,施展出了一招“影敛身法”。\"}\n"}
|
| 8 |
+
{"name": "尤尼控", "attr_str": "{\"name\": \"尤尼控\", \"description\": \"师从,主修剑法\", \"weapon\": \"剑\", \"major_martial_art\": \"剑法\", \"major_movements\": [\"乱影斩\", \"飞花落\", \"星光破\", \"归心剑\"], \"major_damage\": 90, \"secondary_martial_art\": \"无影剑法\", \"secondary_movements\": [\"影随身动\", \"无形斩\", \"幻影步\", \"风雷剑\"], \"secondary_damage\": 80, \"footwork_and_body_method\": \"流云身法\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"乱影斩\", \"description\": \"[player]手中剑舞动如风,剑影纷飞,一招“乱影斩”,剑光如雨,向[target]砍去\", \"missing\": \"[player]手中剑舞动如风,剑影纷飞,一招“乱影斩”,剑光如雨,划向[target]\"}\n{\"招式\": \"飞花落\", \"description\": \"[player]身形飘忽,手中剑化作一片花瓣飞舞,一招“飞花落”,剑花纷纷落下,覆盖了[target]周围的区域\", \"missing\": \"[player]身形飘忽,手中剑化作一片花瓣飞舞,一招“飞花落”,剑花纷纷落下,覆盖了周围的区域\"}\n{\"招式\": \"星光破\", \"description\": \"[player]剑势如星光闪烁,一招“星光破”,剑光瞬间爆发,直刺[target]的要害之处\", \"missing\": \"[player]剑势如星光闪烁,一招“星光破”,剑光瞬间爆发,刺向[target]的要害之处\"}\n{\"招式\": \"归心剑\", \"description\": \"[player]心神专注,手中剑迅速刺出,一招“归心剑”,剑气凌厉,直取[target]的心脏\", \"missing\": \"[player]心神专注,手中剑迅速刺出,一招“归心剑”,剑气凌厉,刺向[target]的心脏\"}\n{\"招式\": \"影随身动\", \"description\": \"[player]身形如鬼魅般闪动,剑光如影随形,一招“影随身动”,剑影纷飞,迅速刺向[target]\", \"missing\": \"[player]身形如鬼魅般闪动,剑光如影随形,一招“影随身动”,剑影纷飞,迅速刺向[target]\"}\n{\"招式\": \"无形斩\", \"description\": \"[player]手中剑化作一道无形之光,瞬间划过,一招“无形斩”,剑气悄然无声地斩向[target]\", \"missing\": \"[player]手中剑化作一道无形之光,瞬间划过,一招“无形斩”,剑气悄然无声地斩向[target]\"}\n{\"招式\": \"幻影步\", \"description\": \"[player]身形如幻,步伐飘忽不定,一招“幻影步”,如鬼魅般接近[target],剑光闪烁间刺向[target]\", \"missing\": \"[player]身形如幻,步伐飘忽不定,一招“幻影步”,如鬼魅般接近[target],剑光闪烁间刺向[target]\"}\n{\"招式\": \"风雷剑\", \"description\": \"[player]手中剑舞动如风,剑光如雷,一招“风雷剑”,剑气凌厉地劈向[target]\", \"missing\": \"[player]手中剑舞动如风,剑光如雷,一招“风雷剑”,剑气凌厉地劈向[target]\"}\n"}
|
| 9 |
+
{"name": "马斯克", "attr_str": "{\"name\": \"马斯克\", \"description\": \"师从,主修贱法\", \"weapon\": \"无\", \"major_martial_art\": \"贱影剑法\", \"major_movements\": [\"贱魂剑\", \"飞贱剑\", \"贱影斩\", \"贱魄刺\"], \"major_damage\": 80, \"secondary_martial_art\": \"贱魔掌法\", \"secondary_movements\": [\"贱魔掌\", \"贱魔爆\", \"贱魔崩\", \"贱魔震\"], \"secondary_damage\": 90, \"footwork_and_body_method\": \"贱魂身法\", \"STR\": 10, \"VIT\": 7, \"SPD\": 13}", "skills": "{\"招式\": \"贱魂剑\", \"description\": \"[player]手中剑舞动如鬼魅,一招“贱魂剑”,剑光幻化成无数剑影,迅猛无比地向[target]刺去\", \"missing\": \"[player]手中剑舞动如鬼魅,一招“贱魂剑”,剑光幻化成无数剑影,迅猛地刺向[target],但被[target]巧妙地躲开\"}\n{\"招式\": \"飞贱剑\", \"description\": \"[player]身形如飞,手中剑化作一道剑光,一招“飞贱剑”,剑光疾射而出,直奔[target]而去\", \"missing\": \"[player]身形如飞,手中剑化作一道剑光,一招“飞贱剑”,剑光疾射而出,但被[target]灵巧地闪避开\"}\n{\"招式\": \"贱影斩\", \"description\": \"[player]剑势如影,一招“贱影斩”,剑光如幻,迅猛地��向[target]\", \"missing\": \"[player]剑势如影,一招“贱影斩”,剑光如幻,迅猛地斩向[target],但被[target]巧妙地躲开\"}\n{\"招式\": \"贱魄刺\", \"description\": \"[player]剑尖微微颤动,一招“贱魄刺”,剑光闪烁,直刺[target]要害\", \"missing\": \"[player]剑尖微微颤动,一招“贱魄刺”,剑光闪烁,直刺[target]要害,但被[target]巧妙地避开\"}\n{\"招式\": \"贱魔掌\", \"description\": \"[player]双掌连环拍击,招式狠辣凌厉,掌风呼啸,犹如恶魔之爪一般\", \"missing\": \"[player]双掌连环拍击,招式凌厉异常,掌风呼啸,犹如恶魔之爪一般\"}\n{\"招式\": \"贱魔爆\", \"description\": \"[player]双掌骤然爆发,内力迸发,一股炽热的能量从掌心迸发而出,如同恶魔之力一般\", \"missing\": \"[player]双掌骤然爆发,内力迸发,一股能量从掌心迸发而出,如同恶魔之力一般\"}\n{\"招式\": \"贱魔崩\", \"description\": \"[player]双掌猛地向下击落,劲力犹如山崩地裂,威势惊人,恶魔之力凝聚于掌心\", \"missing\": \"[player]双掌猛地向下击落,劲力犹如山崩地裂,威势惊人,恶魔之力凝聚于掌心\"}\n{\"招式\": \"贱魔震\", \"description\": \"[player]双掌猛地一震,内力迸发,掌风如雷霆般炸响,恶魔之力肆虐于空气中\", \"missing\": \"[player]双掌猛地一震,内力迸发,掌风炸响,恶魔之力肆虐于空气中\"}\n"}
|
| 10 |
+
{"name": "马斯克", "attr_str": "{\"name\": \"马斯克\", \"description\": \"特斯拉的CEO,同时也是SpaceX的CEO\", \"weapon\": \"无\", \"major_martial_art\": \"电光雷动\", \"major_movements\": [\"磁引雷势\", \"电光狂风\", \"闪电瞬移\", \"雷霆突袭\"], \"major_damage\": 100, \"secondary_martial_art\": \"宇宙无敌\", \"secondary_movements\": [\"宇宙爆破\", \"星光炸裂\", \"虚空吞噬\", \"星际陷阱\"], \"secondary_damage\": 120, \"footwork_and_body_method\": \"电光护体\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"磁引雷势\", \"description\": \"[player]双手结印,内力运转,周身电光闪烁,一股强大的磁场形成,吸引雷电之力,聚集于[player]身周\", \"missing\": \"[player]双手结印,内力运转,周身电光闪烁,一股强大的磁场形成,吸引雷电之力,聚集于[player]身周\"}\n{\"招式\": \"电光狂风\", \"description\": \"[player]身形如电,迅猛无比地挥动双臂,激起一阵狂风,电光四溅,将[target]笼罩其中\", \"missing\": \"[player]身形如电,迅猛无比地挥动双臂,激起一阵狂风,电光四溅,向[target]袭来\"}\n{\"招式\": \"闪电瞬移\", \"description\": \"[player]身形一晃,如闪电般瞬间移动到[target]身旁,手中电光闪烁的兵器刺向[target]\", \"missing\": \"[player]身形一晃,如闪电般瞬间移动到[target]身旁,手中电光闪烁的兵器刺向[target]\"}\n{\"招式\": \"雷霆突袭\", \"description\": \"[player]迅雷不及掩耳之势,如雷霆般突然袭向[target],手中兵器带着雷电之力猛然刺出\", \"missing\": \"[player]迅雷不及掩耳之势,如雷霆般突然袭向[target],手中兵器带着雷电之力刺向[target]\"}\n{\"招式\": \"宇宙爆破\", \"description\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量波向[target]迸发,瞬间将周围的一切都化为灰烬\", \"missing\": \"[player]聚集宇宙能量,猛然爆发,一道炽热的能量波向[target]迸发,周围的一切都被炽热的能量包围\"}\n{\"招式\": \"星光炸裂\", \"description\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰化为碎片,向[target]飞溅而去\", \"missing\": \"[player]手指轻弹,星光四溅,无数颗明亮的星辰化为碎片,闪烁着美丽的光芒\"}\n{\"招式\": \"虚空吞噬\", \"description\": \"[player]张开双臂,虚空开始扭曲,一道黑洞形成,将[target]周围的一切都吞噬进去\", \"missing\": \"[player]张开双臂,虚空开始扭曲,一道黑洞形成,周围的一切都被黑暗笼罩\"}\n{\"招式\": \"星际陷阱\", \"description\": \"[player]施展出星际之力,星光凝聚形成一道无形的陷阱,将[target]困于其中\", \"missing\": \"[player]施展出星际之力,星光凝聚形成一道无形的陷阱,将[target]包围\"}\n"}
|
| 11 |
+
{"name": "杨振宁", "attr_str": "{\"name\": \"杨振宁\", \"description\": \"高能物理大师\", \"weapon\": \"剑\", \"major_martial_art\": \"量子风暴剑法\", \"major_movements\": [\"乾坤剑气\", \"虚空瞬移\", \"粒子爆发\", \"时空禁锢\"], \"major_damage\": 120, \"secondary_martial_art\": \"黑洞掌法\", \"secondary_movements\": [\"虚空吸引\", \"旋转黑洞\", \"引力压制\", \"空间崩溃\"], \"secondary_damage\": 100, \"footwork_and_body_method\": \"时空幻影步\", \"STR\": 15, \"VIT\": 10, \"SPD\": 18}", "skills": "{\"招式\": \"乾坤剑气\", \"description\": \"[player]手中剑舞动不停,剑气纵横��错,一股强大的气势凝聚而成,形成一道犹如乾坤之力的剑气,直奔[target]而去\", \"missing\": \"[player]手中剑舞动不停,剑气纵横交错,形成一道犹如乾坤之力的剑气,迅速向[target]飞去\"}\n{\"招式\": \"虚空瞬移\", \"description\": \"[player]身形忽然消失在原地,下一刻却已出现在[target]身后,手中剑光闪烁,一招“虚空瞬移”刺向[target]\", \"missing\": \"[player]身形忽然消失在原地,下一刻却已出现在[target]身后,手中剑光闪烁,试图一招“虚空瞬移”刺向[target]\"}\n{\"招式\": \"粒子爆发\", \"description\": \"[player]全身内力迸发,剑法变得迅猛无比,剑光如粒子般闪烁,一招“粒子爆发”瞬间击中[target],爆发出强大的力量\", \"missing\": \"[player]全身内力迸发,剑法变得迅猛无比,剑光如粒子般闪烁,试图一招“粒子爆发”击中[target],释放出强大的力量\"}\n{\"招式\": \"时空禁锢\", \"description\": \"[player]剑势凌厉,剑光闪烁,一招“时空禁锢”使得时间和空间仿佛被禁锢,将[target]困在其中无法动弹\", \"missing\": \"[player]剑势凌厉,剑光闪烁,试图一招“时空禁锢”使得时间和空间仿佛被禁锢,试图将[target]困在其中\"}\n{\"招式\": \"虚空吸引\", \"description\": \"[player]双掌一推,内力涌动,形成一股强大的吸引力,如同虚空中有无形之手将[target]牢牢吸引过来\", \"missing\": \"[player]双掌一推,内力涌动,形成一股强大的吸引力,试图将[target]吸引过来\"}\n{\"招式\": \"旋转黑洞\", \"description\": \"[player]身形急转,双掌迅速旋转,形成一股旋转的黑洞之力,向[target]猛然压去\", \"missing\": \"[player]身形急转,双掌迅速旋转,形成一股旋转的黑洞之力,试图向[target]压去\"}\n{\"招式\": \"引力压制\", \"description\": \"[player]双掌猛地向下一压,内力凝聚成强大的引力,将[target]牢牢压制在地面上,动弹不得\", \"missing\": \"[player]双掌猛地向下一压,内力凝聚成强大的引力,试图将[target]压制在地面上\"}\n{\"招式\": \"空间崩溃\", \"description\": \"[player]双掌猛然合拢,内力爆发,周围空间发生剧烈扭曲,形成一片空间崩溃,将[target]困于其中\", \"missing\": \"[player]双掌猛然合拢,内力爆发,周围空间发生剧烈扭曲,试图将[target]困于其中\"}\n"}
|
app.py
ADDED
|
@@ -0,0 +1,970 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain.chat_models import ChatOpenAI
|
| 2 |
+
from langchain.schema import (
|
| 3 |
+
AIMessage,
|
| 4 |
+
HumanMessage,
|
| 5 |
+
SystemMessage
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
smart_system_prompt = """You are ChatGPT, a large language model trained by OpenAI.
|
| 9 |
+
Knowledge cutoff: 2021-09
|
| 10 |
+
Current date: 2023-03-15"""
|
| 11 |
+
|
| 12 |
+
ma_foo_answer = """李鲁鲁,山东逍遥派的游戏角色,擅长人工智能傀儡术,以下是为你设计的两套武功和一套身法(招架)以及每套的四个招式名字:
|
| 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 |
+
attr_foo_answer = """{"name": "李鲁鲁","STR":5,"SPD":5,"VIT":5,"description": "山东逍遥派的李鲁鲁,擅长人工智能傀儡术,善于提前预测对方的行动进行战斗","weapon": "无","major_martial_art": "人工智能傀儡术","major_movements": ["预测之眼", "智慧编织", "虚实交融", "机巧纠缠"],"secondary_martial_art": "人工智能傀儡术","secondary_movements": ["预测之眼", "智慧编织", "虚实交融", "机巧纠缠"],"footwork_and_body_method": "山水行云"}"""
|
| 39 |
+
|
| 40 |
+
attr_lilulu = """{
|
| 41 |
+
"name": "李鲁鲁",
|
| 42 |
+
"description": "山东逍遥派的游戏角色,擅长人工智能傀儡术",
|
| 43 |
+
"weapon": "智能刀剑",
|
| 44 |
+
"major_martial_art": "电脑幻影拳法",
|
| 45 |
+
"major_movements": ["电脑虚像拳", "数据掌控击", "模拟迷雾拳", "程序化拳法"],
|
| 46 |
+
"major_damage": 75,
|
| 47 |
+
"secondary_martial_art": "智能预测刀法",
|
| 48 |
+
"secondary_movements": ["预测之刃", "数据漩涡斩", "算法刀舞", "智能反击剑"],
|
| 49 |
+
"secondary_damage": 85,
|
| 50 |
+
"footwork_and_body_method": "数码幻影步",
|
| 51 |
+
"STR": 6,
|
| 52 |
+
"VIT": 5,
|
| 53 |
+
"SPD": 18
|
| 54 |
+
}
|
| 55 |
+
"""
|
| 56 |
+
|
| 57 |
+
attr_lengziang = """{
|
| 58 |
+
"name": "冷子昂",
|
| 59 |
+
"description": "擅长冰系技能",
|
| 60 |
+
"weapon": "冰刃",
|
| 61 |
+
"major_martial_art": "冰霜寒刃功",
|
| 62 |
+
"major_movements": ["冰刃斩破", "冰风流转", "冰龙穿云", "冰心彻骨"],
|
| 63 |
+
"major_damage": 80,
|
| 64 |
+
"secondary_martial_art": "冰封无影步",
|
| 65 |
+
"secondary_movements": ["冰封幻影", "无影冻结", "冰刃闪耀", "冰封禅定"],
|
| 66 |
+
"secondary_damage": 70,
|
| 67 |
+
"footwork_and_body_method": "冰心护身法",
|
| 68 |
+
"STR": 8,
|
| 69 |
+
"VIT": 6,
|
| 70 |
+
"SPD": 15
|
| 71 |
+
}
|
| 72 |
+
"""
|
| 73 |
+
|
| 74 |
+
json_str_huangrong = """{
|
| 75 |
+
"name": "黄蓉",
|
| 76 |
+
"description": "丐帮帮主黄蓉,擅长打狗棒法和落英神剑掌,身法为逍遥游。",
|
| 77 |
+
"weapon": "棒、剑",
|
| 78 |
+
"major_martial_art": "打狗棒法",
|
| 79 |
+
"major_movements": ["狗啸山林", "棒影重重", "狗尾续貂", "狗急跳墙"],
|
| 80 |
+
"major_damage": 90,
|
| 81 |
+
"secondary_martial_art": "落英神剑掌",
|
| 82 |
+
"secondary_movements": ["落英如雨", "神剑破空", "飞花流水", "剑指苍穹"],
|
| 83 |
+
"secondary_damage": 80,
|
| 84 |
+
"footwork_and_body_method": "逍遥游",
|
| 85 |
+
"STR": 15,
|
| 86 |
+
"VIT": 10,
|
| 87 |
+
"SPD": 18
|
| 88 |
+
}"""
|
| 89 |
+
|
| 90 |
+
skill_foo_desc = """
|
| 91 |
+
{"招式":"预测之眼","description":"[player]凝神聚气,双眼闪烁着深邃的智慧,一招“预测之眼”发动,仿佛未来已经显现在眼前,[player]能够精准预测[target]的下一步动作。","missing":"[player]凝神聚气,双眼闪烁着深邃的智慧,一招“预测之眼”发动,仿佛未来已经显现在眼前,[target]的一举一动变得难以捉摸。"}
|
| 92 |
+
{"招式":"智慧编织","description":"[player]手中的线缠绕着[target],编织成一个巧妙的陷阱,一招“智慧编织”完成,如同织女编织云锦,[target]的行动受到了限制。","missing":"[player]手中的线缠绕着,编织成一个巧妙的陷阱,一招“智慧编织”完成,[target]似乎被某种力量限制住了行���。"}
|
| 93 |
+
{"招式":"虚实交融","description":"[player]身形忽明忽暗,虚实难辨,一招“虚实交融”使出,仿佛有数个[player]一同出招,[target]不知所措。","missing":"[player]身形忽明忽暗,虚实难辨,一招“虚实交融”使出,[target]眼前忽然出现了一片幻影,令其感到迷茫。"}
|
| 94 |
+
{"招式":"机巧纠缠","description":"[player]运用机巧傀儡术,手中的人工智能傀儡纷纷扑向[target],一招“机巧纠缠”展开,[target]被困在了傀儡的包围中。","missing":"[player]运用机巧傀儡术,手中的人工智能傀儡纷纷扑向,一招“机巧纠缠”展开,[target]四面八方都是傀儡的身影,形势险恶。"}
|
| 95 |
+
{"招式":"预测之眼","description":"[player]凝神聚气,双眼闪烁着深邃的智慧,一招“预测之眼”发动,仿佛未来已经显现在眼前,[player]能够精准预测[target]的下一步动作。","missing":"[player]凝神聚气,双眼闪烁着深邃的智慧,一招“预测之眼”发动,仿佛未来已经显现在眼前,[target]的一举一动变得难以捉摸。"}
|
| 96 |
+
{"招式":"智慧编织","description":"[player]手中的线缠绕着[target],编织成一个巧妙的陷阱,一招“智慧编织”完成,如同织女编织云锦,[target]的行动受到了限制。","missing":"[player]手中的线缠绕着,编织成一个巧妙的陷阱,一招“智慧编织”完成,[target]似乎被某种力量限制住了行动。"}
|
| 97 |
+
{"招式":"虚实交融","description":"[player]身形忽明忽暗,虚实难辨,一招“虚实交融”使出,仿佛有数个[player]一同出招,[target]不知所措。","missing":"[player]身形忽明忽暗,虚实难辨,一招“虚实交融”使出,[target]眼前忽然出现了一片幻影,令其感到迷茫。"}
|
| 98 |
+
{"招式":"机巧纠缠","description":"[player]运用机巧傀儡术,手中的人工智能傀儡纷纷扑向[target],一招“机巧纠缠”展开,[target]被困在了傀儡的包围中。","missing":"[player]运用机巧傀儡术,手中的人工智能傀儡纷纷扑向,一招“机巧纠缠”展开,[target]四面八方都是傀儡的身影,形势险恶。"}
|
| 99 |
+
"""
|
| 100 |
+
|
| 101 |
+
skill_lilulu = """
|
| 102 |
+
{"招式":"电脑虚像拳","description":"[player]运用电脑幻影拳法,双拳虚虚实实,制造出多个虚像,令[target]难以分辨真伪,招招不离其身。","missing":"[player]运用电脑幻影拳法,双拳虚虚实实,制造出多个虚像,令[target]难以分辨真伪。"}
|
| 103 |
+
{"招式":"数据掌控击","description":"[player]施展数据掌控击,利用数据流动的速度,犹如电光闪烁,快速攻击[target],剑招迅猛,如电一般。","missing":"[player]施展数据掌控击,利用数据流动的速度,犹如电光闪烁,快速攻击[target],剑招迅猛。"}
|
| 104 |
+
{"招式":"模拟迷雾拳","description":"[player]施展模拟迷雾拳,释放出模糊幻影,混淆[target]的视线,令其难以辨别攻击方向。","missing":"[player]施展模拟迷雾拳,释放出模糊幻影,混淆[target]的视线,令其难以辨别攻击方向。"}
|
| 105 |
+
{"招式":"程序化拳法","description":"[player]运用程序化拳法,以不断变化的攻击组合,让[target]难以预测招式,时而快时而慢,攻击变幻莫测。","missing":"[player]运用程序化拳法,以不断变化的攻击组合,让[target]难以预测招式,攻击变幻莫测。"}
|
| 106 |
+
{"招式":"预测之刃","description":"[player]使出预测之刃,准确地预测[target]的下一步行动,犹如镜中水月,剑锋准确地击中[target]的要害。","missing":"[player]使出预测之刃,准确地预测[target]的下一步行动,犹如镜中水月,剑锋迅速挥出。"}
|
| 107 |
+
{"招式":"数据漩涡斩","description":"[player]施展数据漩涡斩,利用[target]的动向,将其引导至剑刃之下,然后发动猛烈攻击,犹如漩涡将[target]吸入其中。","missing":"[player]施展数据漩涡斩,利用[target]的动向,将其引导至剑刃之下,然后发动猛烈攻击,剑招异常犀利。"}
|
| 108 |
+
{"招式":"算法刀舞","description":"[player]挥舞着长剑,使出算法刀舞,刀法如算法一般精准,快速地切入[target]的防线,剑锋连续不断地斩向[target]。","missing":"[player]挥舞着长剑,使出算法刀舞,刀法如算法一般精准,快速地切入[target]的防线,剑招变化多端。"}
|
| 109 |
+
{"招式":"智能反击剑","description":"[player]运用智能反击剑,反击[target]的招式,使其付出惨痛的代价,一瞬间的犹豫就足以让[target]受伤。","missing":"[player]运用智能反击剑,反击[target]的招式,使其陷入困境,一瞬间的犹豫足以让[target]付出代价。"}
|
| 110 |
+
"""
|
| 111 |
+
|
| 112 |
+
skill_lengziang = """
|
| 113 |
+
{"招式":"冰刃斩破","description":"[player]聚集冰之力量于剑上,使出冰刃斩破,剑锋犹如寒冰之刃斩向[target]的要害部位,寒气逼人,剑光炽烈。","missing":"[player]聚集冰之力量于剑上,使出冰刃斩破,剑锋犹如寒冰之刃,闪电般���出。"}
|
| 114 |
+
{"招式":"冰风流转","description":"[player]身体如风一般旋转,同时释放出冰风刃,打击周围的敌人,冷飕飕的寒风环绕,[target]身不由己地被吹向一旁。","missing":"[player]身体如风一般旋转,同时释放出冰风刃,冷飕飕的寒风环绕,风刃在[target]周围飞舞。"}
|
| 115 |
+
{"招式":"冰龙穿云","description":"[player]召唤出一条冰龙,冰龙穿越云层直扑[target],寒冰之力凝聚在龙爪之上,将[target]冻结一切,一切都难以抵挡。","missing":"[player]召唤出一条冰龙,冰龙穿越云层,龙爪直扑[target],寒冰之力凝聚在龙爪之上,寒意森然。"}
|
| 116 |
+
{"招式":"冰心彻骨","description":"[player]凝聚冰之力于手,一触即可让[target]骨骼寒冷,动弹不得,彻底冰封,剑锋轻轻触及[target],寒意透骨。","missing":"[player]凝聚冰之力于手,一触即可让[target]骨骼寒冷,动弹不得,寒气透骨,剑锋轻轻触及[target]。"}
|
| 117 |
+
{"招式":"冰封幻影","description":"[player]运用冰封无影步,快速移动,留下一道冰封的幻影,使[target]无法辨别真伪,幻影与实体交替出现,令[target]不知所措。","missing":"[player]运用冰封无影步,快速移动,留下一道冰封的幻影,使[target]无法辨别真伪。"}
|
| 118 |
+
{"招式":"无影冻结","description":"[player]以极快的速度接近[target],然后冻结[target]的动作,使其陷入无法自拔的状态,如同身陷冰封之中,动弹不得。","missing":"[player]以极快的速度接近[target],然后冻结[target]的动作,使其陷入无法自拔的状态。"}
|
| 119 |
+
{"招式":"冰刃闪耀","description":"[player]利用冰之能量,瞬间闪现至[target]身边,发动迅猛的攻击,剑锋如星光般闪烁,将[target]包围其中。","missing":"[player]利用冰之能量,瞬间闪现至[target]身边,发动迅猛的攻击,剑锋如星光般闪烁。"}
|
| 120 |
+
{"招式":"冰封禅定","description":"[player]静心冥想,将身体冰封,使自己无法被[target]察觉,达到不可捉摸的状态,如同融入冰封禅定之中。","missing":"[player]静心冥想,将身体冰封,使自己无法被[target]察觉,达到不可捉摸的状态。"}
|
| 121 |
+
"""
|
| 122 |
+
|
| 123 |
+
skill_huangrong = """
|
| 124 |
+
{"招式": "狗啸山林", "description": "[player]手中长棒一挥,发出一声凄厉的狗啸,棒影如山林般扑向[target]", "missing": "[player]手中长棒一挥,发出一声凄厉的狗啸,棒影如山林般扑向[target]"}
|
| 125 |
+
{"招式": "棒影重重", "description": "[player]身形连转,手中长棒化作无数道棒影,重重叠叠地向[target]砸去", "missing": "[player]身形连转,手中长棒化作无数道棒影,重重叠叠地向[target]砸去"}
|
| 126 |
+
{"招式": "狗尾续貂", "description": "[player]手中长棒如狗尾续貂般灵动,连续变换方向,向[target]连续攻击", "missing": "[player]手中长棒如狗尾续貂般灵动,连续变换方向,向[target]连续攻击"}
|
| 127 |
+
{"招式": "狗急跳墙", "description": "[player]猛地一跃,手中长棒带起狂风,如狗急跳墙般向[target]砸去", "missing": "[player]猛地一跃,手中长棒带起狂风,如狗急跳墙般向[target]砸去"}
|
| 128 |
+
{"招式": "落英如雨", "description": "[player]身形一闪,双掌连续拍出,犹如漫天飘落的落英,掌风凌厉,瞬间覆盖[target]周身", "missing": "[player]身形一闪,双掌连续拍出,犹如漫天飘落的落英,掌风凌厉,向[target]周身袭去"}
|
| 129 |
+
{"招式": "神剑破空", "description": "[player]手中剑光闪烁,一剑刺出,剑气凌厉无比,犹如神剑破开虚空,直指[target]要害", "missing": "[player]手中剑光闪烁,一剑刺出,剑气凌厉无比,直向[target]要害刺去"}
|
| 130 |
+
{"招式": "飞花流水", "description": "[player]身形如飞,双掌连续拍击,掌风如流水般连绵不绝,将[target]团团围住", "missing": "[player]身形如飞,双掌连续拍击,掌风如流水般连绵不绝,向[target]团团包围"}
|
| 131 |
+
{"招式": "剑指苍穹", "description": "[player]手中长剑一指,剑光直冲云霄,气势如虹,剑指直指苍穹,威力惊人", "missing": "[player]手中长剑一指,剑光直冲云霄,气势如虹,直指苍穹"}
|
| 132 |
+
"""
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def generate_detailed_description(name, description):
|
| 136 |
+
task_message = f"""我的名字叫“{name}”,假设我是一个武侠中的游戏角色,{description}
|
| 137 |
+
请基于我的名字和门派,先为我设计2套武功和一套身法或者招架。
|
| 138 |
+
|
| 139 |
+
再为每套武功设计4个对应招式的名字。"""
|
| 140 |
+
|
| 141 |
+
messages = [
|
| 142 |
+
SystemMessage(content=smart_system_prompt),
|
| 143 |
+
HumanMessage(content=task_message),
|
| 144 |
+
]
|
| 145 |
+
|
| 146 |
+
chat = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.3)
|
| 147 |
+
|
| 148 |
+
response = chat(messages)
|
| 149 |
+
return response.content
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def generate_attr_json(name, description, detailed_description):
|
| 153 |
+
task_message = f"""我正在为我的武侠游戏设计人物。给定一个人物和这个人物的背景描述(可选)
|
| 154 |
+
|
| 155 |
+
我希望你根��这个人物的背景和名字以及输入的suggestion信息,为我生成这个人的资料,以json的格式输出,包括
|
| 156 |
+
|
| 157 |
+
description: 这个角色的背景等信息
|
| 158 |
+
weapon: 这个人使用的武器种类,
|
| 159 |
+
major_martial_art: 这个人的主要武学
|
| 160 |
+
major_movements: 这个人主要武学的4个对应招式的名字。招式的名字需要尽可能和major_martial_art有关。movements的名字尽量不要使用重复的文字。可以使用形象的动作或者是一些动物的比喻。
|
| 161 |
+
major_damage: 主武学的威力,50到150之间的整数。重视速度的功法威力会低一些。重视攻击的功法威力会高一些
|
| 162 |
+
secondary_movements: 这个角色的次要武学
|
| 163 |
+
secondary_movements: 这个人次要武学的4个对应招式的名字。招式的名字需要尽可能和secondary_movements有关
|
| 164 |
+
secondary_damage: 次要武学的威力,50到150之间的整数。
|
| 165 |
+
footwork_and_body_method: 这个角色的轻功或者防御功法
|
| 166 |
+
STR: 角色的攻击力, 0-20之间的整数
|
| 167 |
+
VIT: 角色的体质, 0-20之间的整数
|
| 168 |
+
SPD: 角色的速度,0-20之间的整数
|
| 169 |
+
"""
|
| 170 |
+
example_input = """example_input:
|
| 171 |
+
name: 令狐冲
|
| 172 |
+
description: -
|
| 173 |
+
suggestion:-"""
|
| 174 |
+
|
| 175 |
+
example_output = """example_output:
|
| 176 |
+
{
|
| 177 |
+
"name": "令狐冲",
|
| 178 |
+
"description": "华山派的大师兄",
|
| 179 |
+
"weapon": "剑",
|
| 180 |
+
"major_martial_art": "独孤九剑",
|
| 181 |
+
"major_movements": ["独孤九剑破剑式","独孤九剑总诀式","独孤九剑破气式","独孤九剑破刀式"],
|
| 182 |
+
"major_damage": 70,
|
| 183 |
+
"secondary_martial_art": "华山剑法",
|
| 184 |
+
"secondary_movements": ["有凤来仪","飞沙走石","百丈飞瀑","青山隐隐"],
|
| 185 |
+
"secondary_damage":80,
|
| 186 |
+
"footwork_and_body_method": "华山身法",
|
| 187 |
+
"STR":10,
|
| 188 |
+
"VIT":3,
|
| 189 |
+
"SPD":20
|
| 190 |
+
}"""
|
| 191 |
+
|
| 192 |
+
input = f"""input:
|
| 193 |
+
name: {name},
|
| 194 |
+
description: {description},
|
| 195 |
+
suggestion: `{detailed_description}`
|
| 196 |
+
"""
|
| 197 |
+
|
| 198 |
+
messages = [
|
| 199 |
+
SystemMessage(content=smart_system_prompt),
|
| 200 |
+
HumanMessage(content=task_message),
|
| 201 |
+
HumanMessage(content=example_input),
|
| 202 |
+
AIMessage(content=example_output),
|
| 203 |
+
HumanMessage(content=input)]
|
| 204 |
+
|
| 205 |
+
chat = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.1)
|
| 206 |
+
|
| 207 |
+
response = chat(messages)
|
| 208 |
+
return response.content
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
import json
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def robust_parsing(input_str):
|
| 215 |
+
try:
|
| 216 |
+
return json.loads(input_str)
|
| 217 |
+
except json.JSONDecodeError:
|
| 218 |
+
start = input_str.find('{')
|
| 219 |
+
end = input_str.rfind('}') + 1
|
| 220 |
+
if start != -1 and end != -1:
|
| 221 |
+
try:
|
| 222 |
+
return json.loads(input_str[start:end])
|
| 223 |
+
except json.JSONDecodeError:
|
| 224 |
+
pass
|
| 225 |
+
|
| 226 |
+
return None
|
| 227 |
+
|
| 228 |
+
|
| 229 |
+
def generate_skill_detail(martial_art_name, movements):
|
| 230 |
+
task_message = """现在我希望你根据武侠小说中的武功和招式的名字。为招式补全合理的description和missing描述。
|
| 231 |
+
在description的描述中,player可以击中目标,可以有兵器撞击声响等描述。
|
| 232 |
+
在missing描述中,player并不一定击中目标,不可以有击落、击中、夺去这样的描述
|
| 233 |
+
在用[player]代表技能的使用者,用[target]代表技能的目标。结果需用合理的jsonl格式展示,下面是一个例子。"""
|
| 234 |
+
|
| 235 |
+
example_input = """example input:
|
| 236 |
+
martial_art_name = 华山剑法
|
| 237 |
+
{"招式":"百丈飞瀑"}
|
| 238 |
+
{"招式":"百鸟朝凤"}
|
| 239 |
+
{"招式":"青山隐隐"}
|
| 240 |
+
{"招式":"飞沙走石"}"""
|
| 241 |
+
|
| 242 |
+
example_output = """example output:
|
| 243 |
+
{"招式":"百丈飞瀑","description":"[player]翻身回剑,剑诀斜引,一招“百丈飞瀑”,剑锋从半空中直泻下来","missing":"[player]一咬牙,翻身回剑,剑诀斜引,一招“百丈飞瀑”,剑锋从半空中直泻下来"}
|
| 244 |
+
{"招式":"百鸟朝凤","description":"[player]长剑一起,使一招“百鸟朝凤”,但见剑尖乱颤,霎时间便如化为数十个剑尖,罩住[target]中盘","missing":"[player]使一招“百鸟朝凤”,但见剑尖乱颤,霎时间便如化为数十个剑尖,向[target]飞去"}
|
| 245 |
+
{"招式":"青山隐隐", "description":"[player]吸一口气,长剑中宫直进,剑尖不住颤动,剑到中途,忽然转而向上,乃是一招“青山隐隐”,端的是若有若无,变幻无方。","missing":"[player]吸一口气,长剑中宫直进,剑尖不住颤动,剑到中途,忽然转而向上,乃是一招“青山隐隐”,端的是若有若无,变幻无方。"}
|
| 246 |
+
{"招式":"飞沙走石", "description":"长剑挺起,使一招“飞沙走石”,内劲直贯剑尖,寒光点点,挡的一声,击中的[target]胸口。","missing":"长剑挺起,使一招“飞沙走石”,内劲直贯剑尖,寒光点点,直向[target]胸口刺去。"}"""
|
| 247 |
+
|
| 248 |
+
input = "input:\nmartial_art_name = " + martial_art_name + "\n"
|
| 249 |
+
for m in movements:
|
| 250 |
+
input += f"""{{"招式":"{m}"\}}\n"""
|
| 251 |
+
|
| 252 |
+
messages = [
|
| 253 |
+
SystemMessage(content=smart_system_prompt),
|
| 254 |
+
HumanMessage(content=task_message),
|
| 255 |
+
HumanMessage(content=example_input),
|
| 256 |
+
AIMessage(content=example_output),
|
| 257 |
+
HumanMessage(content=input)]
|
| 258 |
+
|
| 259 |
+
chat = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.1)
|
| 260 |
+
|
| 261 |
+
response = chat(messages)
|
| 262 |
+
return response.content
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
def generate_skill_jsonl(json_data):
|
| 266 |
+
major_skills = generate_skill_detail(json_data["major_martial_art"], json_data["major_movements"])
|
| 267 |
+
secondary_skills = generate_skill_detail(json_data["secondary_martial_art"], json_data["secondary_movements"])
|
| 268 |
+
|
| 269 |
+
all_skills = major_skills + "\n" + secondary_skills
|
| 270 |
+
|
| 271 |
+
ans = ""
|
| 272 |
+
|
| 273 |
+
lines = all_skills.split("\n")
|
| 274 |
+
for line in lines:
|
| 275 |
+
json_data = robust_parsing(line)
|
| 276 |
+
if json_data is not None:
|
| 277 |
+
json_str = json.dumps(json_data, ensure_ascii=False)
|
| 278 |
+
ans += json_str + "\n"
|
| 279 |
+
|
| 280 |
+
return ans
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
import random
|
| 284 |
+
|
| 285 |
+
|
| 286 |
+
class Player:
|
| 287 |
+
def __init__(self, attr_json, skill_jsonl):
|
| 288 |
+
self.name = attr_json["name"]
|
| 289 |
+
self.STR = attr_json["STR"]
|
| 290 |
+
self.SPD = attr_json["SPD"]
|
| 291 |
+
self.VIT = attr_json["VIT"]
|
| 292 |
+
if "major_damage" in attr_json:
|
| 293 |
+
self.major_damage = attr_json["major_damage"]
|
| 294 |
+
else:
|
| 295 |
+
self.major_damage = 65
|
| 296 |
+
|
| 297 |
+
if "secondary_damage" in attr_json:
|
| 298 |
+
self.secondary_damage = attr_json["secondary_damage"]
|
| 299 |
+
else:
|
| 300 |
+
self.secondary_damage = 50
|
| 301 |
+
|
| 302 |
+
self.normalize_attr()
|
| 303 |
+
if "hp" in attr_json:
|
| 304 |
+
self.hp = attr_json["hp"]
|
| 305 |
+
else:
|
| 306 |
+
self.hp = (self.VIT + 10) * 30
|
| 307 |
+
|
| 308 |
+
if "skills" in attr_json:
|
| 309 |
+
self.skills = attr_json["skills"]
|
| 310 |
+
else:
|
| 311 |
+
self.skills = self.parsing_skill(skill_jsonl)
|
| 312 |
+
|
| 313 |
+
self.original_json = attr_json
|
| 314 |
+
|
| 315 |
+
def normalize_attr(self):
|
| 316 |
+
max_attr_value = 20
|
| 317 |
+
min_attr_value = 0
|
| 318 |
+
regular_attr_sum = 30
|
| 319 |
+
xs = [self.STR, self.SPD, self.VIT]
|
| 320 |
+
current_sum = 0
|
| 321 |
+
for i in range(3):
|
| 322 |
+
xs[i] = min(max_attr_value, xs[i])
|
| 323 |
+
xs[i] = max(min_attr_value, xs[i])
|
| 324 |
+
current_sum += xs[i]
|
| 325 |
+
|
| 326 |
+
if current_sum > regular_attr_sum:
|
| 327 |
+
for i in range(3):
|
| 328 |
+
xs[i] = round(xs[i] * regular_attr_sum / current_sum)
|
| 329 |
+
elif current_sum < regular_attr_sum:
|
| 330 |
+
for i in range(3):
|
| 331 |
+
xs[i] = round(xs[i] * regular_attr_sum / current_sum)
|
| 332 |
+
|
| 333 |
+
random_i = random.randint(0, 2)
|
| 334 |
+
xs[random_i] = xs[random_i] + regular_attr_sum - sum(xs)
|
| 335 |
+
|
| 336 |
+
self.STR = xs[0]
|
| 337 |
+
self.SPD = xs[1]
|
| 338 |
+
self.VIT = xs[2]
|
| 339 |
+
|
| 340 |
+
def get_new_json(self):
|
| 341 |
+
new_json = self.original_json
|
| 342 |
+
new_json["STR"] = self.STR
|
| 343 |
+
new_json["SPD"] = self.SPD
|
| 344 |
+
new_json["VIT"] = self.VIT
|
| 345 |
+
new_json["hp"] = self.hp
|
| 346 |
+
new_json["skills"] = self.skills
|
| 347 |
+
return new_json
|
| 348 |
+
|
| 349 |
+
def parsing_skill(self, skill_jsonl):
|
| 350 |
+
skills = []
|
| 351 |
+
lines = skill_jsonl.split("\n")
|
| 352 |
+
for line in lines:
|
| 353 |
+
if line.strip() == "":
|
| 354 |
+
continue
|
| 355 |
+
skill = json.loads(line)
|
| 356 |
+
skills.append(skill)
|
| 357 |
+
return skills
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
hit_map = {30: 131, 31: 131, 32: 131, 33: 131, 34: 131, 35: 120, 36: 112, 37: 107, 38: 103, 39: 100, 40: 97, 41: 95,
|
| 361 |
+
42: 93, 43: 91, 44: 89, 45: 87, 46: 86, 47: 85, 48: 83, 49: 82, 50: 81, 51: 80, 52: 79, 53: 78, 54: 77,
|
| 362 |
+
55: 76, 56: 75, 57: 74, 58: 73, 59: 72, 60: 71, 61: 70, 62: 69, 63: 69, 64: 68, 65: 67, 66: 66, 67: 65,
|
| 363 |
+
68: 65, 69: 64, 70: 63, 71: 63, 72: 62, 73: 61, 74: 61, 75: 60, 76: 59, 77: 59, 78: 58, 79: 58, 80: 57,
|
| 364 |
+
81: 57, 82: 56, 83: 55, 84: 55, 85: 54, 86: 54, 87: 53, 88: 53, 89: 52, 90: 52, 91: 52, 92: 51, 93: 51,
|
| 365 |
+
94: 50, 95: 50, 96: 49, 97: 49, 98: 49, 99: 48, 100: 48, 101: 47, 102: 47, 103: 47, 104: 46, 105: 46,
|
| 366 |
+
106: 46, 107: 45, 108: 45, 109: 44, 110: 44, 111: 44, 112: 43, 113: 43, 114: 43, 115: 43, 116: 42, 117: 42,
|
| 367 |
+
118: 42, 119: 41, 120: 41, 121: 41, 122: 40, 123: 40, 124: 40, 125: 40, 126: 39, 127: 39, 128: 39, 129: 39,
|
| 368 |
+
130: 38, 131: 38, 132: 38, 133: 38, 134: 37, 135: 37, 136: 37, 137: 37, 138: 36, 139: 36, 140: 36, 141: 36,
|
| 369 |
+
142: 36, 143: 35, 144: 35, 145: 35, 146: 35, 147: 34, 148: 34, 149: 34, 150: 34, 151: 34, 152: 33, 153: 33,
|
| 370 |
+
154: 33, 155: 33, 156: 33, 157: 33, 158: 32, 159: 32, 160: 32, 161: 32, 162: 32, 163: 31, 164: 31, 165: 31,
|
| 371 |
+
166: 31, 167: 31, 168: 31, 169: 30, 170: 30, 171: 30, 172: 30, 173: 30, 174: 30, 175: 30, 176: 29, 177: 29,
|
| 372 |
+
178: 29, 179: 29, 180: 29}
|
| 373 |
+
|
| 374 |
+
min_damage = 34
|
| 375 |
+
max_damage = 180
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
class GameManager:
|
| 379 |
+
def __init__(self, attr_json1, attr_json2, skill_jsonl1, skill_jsonl2):
|
| 380 |
+
self.player1 = Player(attr_json1, skill_jsonl1)
|
| 381 |
+
self.player2 = Player(attr_json2, skill_jsonl2)
|
| 382 |
+
|
| 383 |
+
def run(self):
|
| 384 |
+
speed_diff = self.player1.SPD - self.player2.SPD
|
| 385 |
+
if speed_diff == 0:
|
| 386 |
+
speed_diff = random.randint(0, 3) * 2 - 3
|
| 387 |
+
|
| 388 |
+
skill_id_1 = random.randint(0, len(self.player1.skills) - 1)
|
| 389 |
+
dmg_1 = 60
|
| 390 |
+
if skill_id_1 + skill_id_1 < len(self.player1.skills):
|
| 391 |
+
dmg_1 = self.player1.major_damage
|
| 392 |
+
else:
|
| 393 |
+
dmg_1 = self.player1.secondary_damage
|
| 394 |
+
|
| 395 |
+
skill_1_to_2 = self.player1.skills[skill_id_1]
|
| 396 |
+
skill_1_to_2["dmg"] = dmg_1
|
| 397 |
+
|
| 398 |
+
skill_id_2 = random.randint(0, len(self.player2.skills) - 1)
|
| 399 |
+
dmg_2 = 60
|
| 400 |
+
if skill_id_2 + skill_id_2 < len(self.player2.skills):
|
| 401 |
+
dmg_2 = self.player2.major_damage
|
| 402 |
+
else:
|
| 403 |
+
dmg_2 = self.player2.secondary_damage
|
| 404 |
+
|
| 405 |
+
skill_2_to_1 = self.player2.skills[skill_id_2]
|
| 406 |
+
skill_2_to_1["dmg"] = dmg_2
|
| 407 |
+
|
| 408 |
+
# skill_2_to_1 = random.choice(self.player2.skills)
|
| 409 |
+
|
| 410 |
+
# print(skill_1_to_2)
|
| 411 |
+
# print(skill_2_to_1)
|
| 412 |
+
|
| 413 |
+
damage_1_to_2 = self.compute_damage(skill_1_to_2, self.player1, self.player2)
|
| 414 |
+
damage_2_to_1 = self.compute_damage(skill_2_to_1, self.player2, self.player1)
|
| 415 |
+
|
| 416 |
+
ratio_1_to_2 = self.compute_ratio(skill_1_to_2, self.player1, self.player2)
|
| 417 |
+
ratio_2_to_1 = self.compute_ratio(skill_2_to_1, self.player2, self.player1)
|
| 418 |
+
|
| 419 |
+
if_hitted_1_to_2 = random.random() * 100.0 < ratio_1_to_2
|
| 420 |
+
if_hitted_2_to_1 = random.random() * 100.0 < ratio_2_to_1
|
| 421 |
+
|
| 422 |
+
desc_1_to_2 = skill_1_to_2["description"] if if_hitted_1_to_2 else skill_1_to_2["missing"]
|
| 423 |
+
desc_1_to_2 = desc_1_to_2.replace("[player]", self.player1.name).replace("[target]", self.player2.name)
|
| 424 |
+
|
| 425 |
+
if if_hitted_1_to_2:
|
| 426 |
+
desc_1_to_2 += f"造成了{round(damage_1_to_2)}的伤害。"
|
| 427 |
+
else:
|
| 428 |
+
desc_1_to_2 += f"{self.player2.name}躲了过去"
|
| 429 |
+
|
| 430 |
+
desc_2_to_1 = skill_2_to_1["description"] if if_hitted_2_to_1 else skill_2_to_1["missing"]
|
| 431 |
+
desc_2_to_1 = desc_2_to_1.replace("[player]", self.player2.name).replace("[target]", self.player1.name)
|
| 432 |
+
if if_hitted_2_to_1:
|
| 433 |
+
desc_2_to_1 += f"造成了{round(damage_2_to_1)}的伤害。"
|
| 434 |
+
else:
|
| 435 |
+
desc_2_to_1 += f"{self.player1.name}躲了过去"
|
| 436 |
+
|
| 437 |
+
self.flag = "continue"
|
| 438 |
+
|
| 439 |
+
ans_msg = []
|
| 440 |
+
|
| 441 |
+
if self.player2.hp <= 0:
|
| 442 |
+
ans_msg.append((None, f"{self.player2.name}战败了"))
|
| 443 |
+
return ans_msg, self.player1.get_new_json(), self.player2.get_new_json()
|
| 444 |
+
|
| 445 |
+
if self.player1.hp <= 0:
|
| 446 |
+
ans_msg.append((f"{self.player1.name}战败了", None))
|
| 447 |
+
return ans_msg, self.player1.get_new_json(), self.player2.get_new_json()
|
| 448 |
+
|
| 449 |
+
if speed_diff > 0:
|
| 450 |
+
if if_hitted_1_to_2:
|
| 451 |
+
self.player2.hp -= damage_1_to_2
|
| 452 |
+
|
| 453 |
+
ans_msg.append((desc_1_to_2, None))
|
| 454 |
+
|
| 455 |
+
if self.player2.hp > 0 and if_hitted_2_to_1:
|
| 456 |
+
self.player1.hp -= damage_2_to_1
|
| 457 |
+
|
| 458 |
+
if self.player2.hp > 0:
|
| 459 |
+
ans_msg.append((None, desc_2_to_1))
|
| 460 |
+
|
| 461 |
+
else:
|
| 462 |
+
if if_hitted_2_to_1:
|
| 463 |
+
self.player1.hp -= damage_2_to_1
|
| 464 |
+
|
| 465 |
+
ans_msg.append((None, desc_2_to_1))
|
| 466 |
+
|
| 467 |
+
if self.player1.hp > 0 and if_hitted_1_to_2:
|
| 468 |
+
self.player2.hp -= damage_1_to_2
|
| 469 |
+
|
| 470 |
+
if self.player1.hp > 0:
|
| 471 |
+
ans_msg.append((desc_1_to_2, None))
|
| 472 |
+
|
| 473 |
+
if self.player2.hp <= 0:
|
| 474 |
+
ans_msg.append((None, f"{self.player2.name}战败了"))
|
| 475 |
+
self.flag = "player1_win"
|
| 476 |
+
if self.player1.hp <= 0:
|
| 477 |
+
ans_msg.append((f"{self.player1.name}战败了", None))
|
| 478 |
+
self.flag = "player2_win"
|
| 479 |
+
|
| 480 |
+
return ans_msg, self.player1.get_new_json(), self.player2.get_new_json()
|
| 481 |
+
|
| 482 |
+
# default "damage": 60, "hit": 76,
|
| 483 |
+
def compute_damage(self, skill, player, target):
|
| 484 |
+
damage_ratio = skill["dmg"]
|
| 485 |
+
damage_ratio = max(min_damage, damage_ratio)
|
| 486 |
+
damage_ratio = min(max_damage, min_damage)
|
| 487 |
+
skill_damage = damage_ratio + player.STR * 2
|
| 488 |
+
attack_diff = player.STR - target.VIT * 0.5
|
| 489 |
+
damage = skill_damage * (1 + 0.95 * (-0.5 + 1.0 / (1.0 + exp(-attack_diff / 6.0))))
|
| 490 |
+
return damage
|
| 491 |
+
|
| 492 |
+
def compute_ratio(self, skill, player, target):
|
| 493 |
+
damage_ratio = skill["dmg"]
|
| 494 |
+
damage_ratio = round(damage_ratio)
|
| 495 |
+
damage_ratio = max(min_damage, damage_ratio)
|
| 496 |
+
damage_ratio = min(max_damage, min_damage)
|
| 497 |
+
skill_hit = hit_map[damage_ratio]
|
| 498 |
+
|
| 499 |
+
speed_diff = player.SPD - target.SPD
|
| 500 |
+
hit_factor = (-0.5 + 1.0 / (1.0 + exp(-speed_diff / 6.0))) / 2.0 * max(30.0, skill_hit)
|
| 501 |
+
return hit_factor + skill_hit
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
fighter_save_name = 'LuotuoFighter.txt'
|
| 505 |
+
|
| 506 |
+
import os
|
| 507 |
+
|
| 508 |
+
datas = []
|
| 509 |
+
|
| 510 |
+
if not os.path.exists(fighter_save_name):
|
| 511 |
+
data = {
|
| 512 |
+
"name": "李鲁鲁",
|
| 513 |
+
"attr_str": attr_lilulu,
|
| 514 |
+
"skills": skill_lilulu
|
| 515 |
+
}
|
| 516 |
+
datas.append(data)
|
| 517 |
+
data = {
|
| 518 |
+
"name": "冷子昂",
|
| 519 |
+
"attr_str": attr_lengziang,
|
| 520 |
+
"skills": skill_lengziang
|
| 521 |
+
}
|
| 522 |
+
datas.append(data)
|
| 523 |
+
data = {
|
| 524 |
+
"name": "黄蓉",
|
| 525 |
+
"attr_str": json_str_huangrong,
|
| 526 |
+
"skills": skill_huangrong
|
| 527 |
+
}
|
| 528 |
+
datas.append(data)
|
| 529 |
+
with open(fighter_save_name, 'w', encoding="utf-8") as f:
|
| 530 |
+
for data in datas:
|
| 531 |
+
f.write(json.dumps(data, ensure_ascii=False) + "\n")
|
| 532 |
+
else:
|
| 533 |
+
with open(fighter_save_name, 'r', encoding="utf-8") as f:
|
| 534 |
+
for line in f.readlines():
|
| 535 |
+
data = json.loads(line)
|
| 536 |
+
datas.append(data)
|
| 537 |
+
|
| 538 |
+
fighter_data = datas
|
| 539 |
+
|
| 540 |
+
elo_table = {}
|
| 541 |
+
|
| 542 |
+
|
| 543 |
+
def get_unique_from_data(data):
|
| 544 |
+
name = data["name"]
|
| 545 |
+
json_data = json.loads(data["attr_str"])
|
| 546 |
+
return get_unique_from_json(name, json_data)
|
| 547 |
+
|
| 548 |
+
|
| 549 |
+
def get_unique_from_json(name, json_data):
|
| 550 |
+
if "STR" in json_data and "VIT" in json_data and "SPD" in json_data and "major_damage" in json_data and "secondary_damage" in json_data:
|
| 551 |
+
return name + "_" + str(json_data["major_damage"]) + "_" + str(json_data["secondary_damage"])
|
| 552 |
+
else:
|
| 553 |
+
return None
|
| 554 |
+
|
| 555 |
+
|
| 556 |
+
unique_to_score = {}
|
| 557 |
+
name_to_top_unique = {}
|
| 558 |
+
|
| 559 |
+
from math import exp
|
| 560 |
+
|
| 561 |
+
elo_start = 1200
|
| 562 |
+
elo_K = 15
|
| 563 |
+
|
| 564 |
+
for data in fighter_data:
|
| 565 |
+
unique_name = get_unique_from_data(data)
|
| 566 |
+
score = elo_start
|
| 567 |
+
unique_to_score[unique_name] = elo_start
|
| 568 |
+
name = data["name"]
|
| 569 |
+
|
| 570 |
+
name_to_top_unique[name] = unique_name
|
| 571 |
+
|
| 572 |
+
|
| 573 |
+
def get_rank_str(top_n=20):
|
| 574 |
+
global unique_to_score
|
| 575 |
+
global name_to_top_unique
|
| 576 |
+
|
| 577 |
+
score_name_pair = []
|
| 578 |
+
for name in name_to_top_unique:
|
| 579 |
+
unique = name_to_top_unique[name]
|
| 580 |
+
score = unique_to_score[unique]
|
| 581 |
+
score_name_pair.append((unique, score))
|
| 582 |
+
|
| 583 |
+
top_n = min(top_n, len(name_to_top_unique))
|
| 584 |
+
score_name_pair.sort(key=lambda x: x[1], reverse=True)
|
| 585 |
+
ans = ""
|
| 586 |
+
for i in range(top_n):
|
| 587 |
+
name = score_name_pair[i][0].split("_")[0]
|
| 588 |
+
ans += f"第{i + 1}名" + name + " - " + str(round(score_name_pair[i][1])) + " | "
|
| 589 |
+
|
| 590 |
+
return ans
|
| 591 |
+
|
| 592 |
+
|
| 593 |
+
def update_elo(winner_unique, loser_unique):
|
| 594 |
+
print(winner_unique + " wins " + loser_unique)
|
| 595 |
+
update_winner = True
|
| 596 |
+
update_loser = True
|
| 597 |
+
|
| 598 |
+
global unique_to_score
|
| 599 |
+
global name_to_top_unique
|
| 600 |
+
|
| 601 |
+
if winner_unique not in unique_to_score:
|
| 602 |
+
unique_to_score[winner_unique] = elo_start
|
| 603 |
+
update_loser = False
|
| 604 |
+
|
| 605 |
+
if loser_unique not in unique_to_score:
|
| 606 |
+
unique_to_score[loser_unique] = elo_start
|
| 607 |
+
|
| 608 |
+
Ra = unique_to_score[winner_unique]
|
| 609 |
+
Rb = unique_to_score[loser_unique]
|
| 610 |
+
|
| 611 |
+
Ea = 1 / (1 + exp((Rb - Ra) / 400))
|
| 612 |
+
Eb = 1 / (1 + exp((Ra - Rb) / 400))
|
| 613 |
+
Sa = 1
|
| 614 |
+
Sb = 0
|
| 615 |
+
unique_to_score[winner_unique] = Ra + elo_K * (Sa - Ea)
|
| 616 |
+
unique_to_score[loser_unique] = Rb + elo_K * (Sb - Eb)
|
| 617 |
+
|
| 618 |
+
winner_name = winner_unique.split("_")[0]
|
| 619 |
+
|
| 620 |
+
if winner_name not in name_to_top_unique:
|
| 621 |
+
name_to_top_unique[winner_name] = winner_unique
|
| 622 |
+
|
| 623 |
+
winner_unique_on_rank = name_to_top_unique[winner_name]
|
| 624 |
+
if unique_to_score[winner_unique] > unique_to_score[winner_unique_on_rank]:
|
| 625 |
+
name_to_top_unique[winner_name] = winner_unique
|
| 626 |
+
|
| 627 |
+
|
| 628 |
+
def get_random_fighter():
|
| 629 |
+
global fighter_data
|
| 630 |
+
return random.choice(fighter_data)
|
| 631 |
+
|
| 632 |
+
|
| 633 |
+
def searching_fighter(name):
|
| 634 |
+
global fighter_data
|
| 635 |
+
for data in fighter_data:
|
| 636 |
+
if data["name"] == name:
|
| 637 |
+
return data
|
| 638 |
+
return get_random_fighter()
|
| 639 |
+
|
| 640 |
+
|
| 641 |
+
def add_fighter(attr_json_str, skill_jsonl):
|
| 642 |
+
attr_json = json.loads(attr_json_str)
|
| 643 |
+
if "skills" in attr_json:
|
| 644 |
+
del attr_json["skills"]
|
| 645 |
+
if "hp" in attr_json:
|
| 646 |
+
del attr_json["hp"]
|
| 647 |
+
|
| 648 |
+
new_attr_json_str = json.dumps(attr_json, ensure_ascii=False)
|
| 649 |
+
|
| 650 |
+
global fighter_data
|
| 651 |
+
name = attr_json["name"]
|
| 652 |
+
|
| 653 |
+
data = {
|
| 654 |
+
"name": name,
|
| 655 |
+
"attr_str": new_attr_json_str,
|
| 656 |
+
"skills": skill_jsonl
|
| 657 |
+
}
|
| 658 |
+
fighter_data.append(data)
|
| 659 |
+
print(json.dumps(data, ensure_ascii=False))
|
| 660 |
+
with open(fighter_save_name, 'a', encoding="utf-8") as f:
|
| 661 |
+
f.write(json.dumps(data, ensure_ascii=False) + "\n")
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
def searching_fighter_on_elo(name):
|
| 665 |
+
global fighter_data
|
| 666 |
+
global name_to_top_unique
|
| 667 |
+
|
| 668 |
+
if name in name_to_top_unique:
|
| 669 |
+
top_unique = name_to_top_unique[name]
|
| 670 |
+
for data in fighter_data:
|
| 671 |
+
if get_unique_from_data(data) == top_unique:
|
| 672 |
+
return data
|
| 673 |
+
return searching_fighter(name)
|
| 674 |
+
else:
|
| 675 |
+
return searching_fighter(name)
|
| 676 |
+
|
| 677 |
+
|
| 678 |
+
import gradio as gr
|
| 679 |
+
|
| 680 |
+
|
| 681 |
+
def get_attr_str_short(attr_json):
|
| 682 |
+
if "hp" in attr_json:
|
| 683 |
+
ans = "血量:" + str(attr_json["hp"]) + "\n"
|
| 684 |
+
else:
|
| 685 |
+
ans = ""
|
| 686 |
+
ans += "力量:" + str(attr_json["STR"]) + "\n体质:" + str(attr_json["VIT"]) + "\n速度:" + str(attr_json["SPD"])
|
| 687 |
+
return ans
|
| 688 |
+
|
| 689 |
+
|
| 690 |
+
def get_skill_str_short(attr_json):
|
| 691 |
+
ans = attr_json["major_martial_art"] + ":\n"
|
| 692 |
+
for skill in attr_json["major_movements"]:
|
| 693 |
+
ans += skill + "-"
|
| 694 |
+
ans += "\n" + attr_json["secondary_martial_art"] + ":\n"
|
| 695 |
+
for skill in attr_json["secondary_movements"]:
|
| 696 |
+
ans += skill + "-"
|
| 697 |
+
ans += "\n 防御:" + attr_json["footwork_and_body_method"]
|
| 698 |
+
return ans
|
| 699 |
+
|
| 700 |
+
|
| 701 |
+
def generate_ma(name, desc, display_board):
|
| 702 |
+
if name.strip() == "":
|
| 703 |
+
return "", "", "", "", display_board, "角色名不能为空,输入角色名后生成功法或者创建角色"
|
| 704 |
+
|
| 705 |
+
status = "请为角色进一步生成详细功法"
|
| 706 |
+
|
| 707 |
+
role_detail = ma_foo_answer
|
| 708 |
+
|
| 709 |
+
if name == "李鲁鲁":
|
| 710 |
+
json_answer = json.loads(attr_lilulu)
|
| 711 |
+
elif name == "冷子昂":
|
| 712 |
+
json_answer = json.loads(attr_lengziang)
|
| 713 |
+
else:
|
| 714 |
+
role_detail = generate_detailed_description(name, desc)
|
| 715 |
+
json_str = generate_attr_json(name, desc, role_detail)
|
| 716 |
+
json_answer = robust_parsing(json_str)
|
| 717 |
+
|
| 718 |
+
json_answer_str = json.dumps(json_answer, ensure_ascii=False)
|
| 719 |
+
|
| 720 |
+
skill_desc = get_skill_str_short(json_answer)
|
| 721 |
+
|
| 722 |
+
display_board.append(("生成人物" + json_answer["name"] + "\n" + skill_desc, None))
|
| 723 |
+
|
| 724 |
+
return role_detail, json_answer_str, get_attr_str_short(json_answer), skill_desc, display_board, status
|
| 725 |
+
|
| 726 |
+
|
| 727 |
+
def generate_madetail(player_attribute, display_board):
|
| 728 |
+
if player_attribute.strip() == "":
|
| 729 |
+
return "", display_board, "需要生成武功名称,再生成描述。或者直接随机召唤角色"
|
| 730 |
+
|
| 731 |
+
status = "确认两个角色都生成之后,可以进入战斗"
|
| 732 |
+
|
| 733 |
+
json_answer = json.loads(player_attribute)
|
| 734 |
+
|
| 735 |
+
generate_flag = False
|
| 736 |
+
|
| 737 |
+
ans = skill_foo_desc
|
| 738 |
+
if json_answer["name"] == "李鲁鲁":
|
| 739 |
+
ans = skill_lilulu
|
| 740 |
+
elif json_answer["name"] == "冷子昂":
|
| 741 |
+
ans = skill_lengziang
|
| 742 |
+
else:
|
| 743 |
+
ans = generate_skill_jsonl(json_answer)
|
| 744 |
+
generate_flag = True
|
| 745 |
+
|
| 746 |
+
display_board.append(("为" + json_answer["name"] + "生成详细的功法描述\n", None))
|
| 747 |
+
|
| 748 |
+
if generate_flag:
|
| 749 |
+
player = Player(json_answer, ans)
|
| 750 |
+
unique_name = get_unique_from_json(json_answer["name"], json_answer)
|
| 751 |
+
if len(player.skills) > 1 and unique_name != None:
|
| 752 |
+
add_fighter(player_attribute, ans)
|
| 753 |
+
display_board.append(("将新角色" + json_answer["name"] + "录入到数据库\n", None))
|
| 754 |
+
|
| 755 |
+
return ans, display_board, status
|
| 756 |
+
|
| 757 |
+
|
| 758 |
+
def continue_fight(detailed_attr_player1, detailed_attr_player2, detailed_skill_player1, detailed_skill_player2,
|
| 759 |
+
display_board):
|
| 760 |
+
if detailed_attr_player1.strip() == "" or detailed_attr_player2.strip() == "" or detailed_skill_player1.strip() == "" or detailed_skill_player2.strip() == "":
|
| 761 |
+
str1 = ""
|
| 762 |
+
if detailed_attr_player1.strip() != "":
|
| 763 |
+
str1 = get_attr_str_short(json.loads(detailed_attr_player1))
|
| 764 |
+
str2 = ""
|
| 765 |
+
if detailed_attr_player2.strip() != "":
|
| 766 |
+
str2 = get_attr_str_short(json.loads(detailed_attr_player2))
|
| 767 |
+
return detailed_attr_player1, detailed_attr_player2, display_board, str1, str2, "请重新检查人物的生成情况"
|
| 768 |
+
|
| 769 |
+
json1 = json.loads(detailed_attr_player1)
|
| 770 |
+
json2 = json.loads(detailed_attr_player2)
|
| 771 |
+
name1 = json1["name"]
|
| 772 |
+
name2 = json2["name"]
|
| 773 |
+
|
| 774 |
+
status = f"""{name1} 大战 {name2}"""
|
| 775 |
+
|
| 776 |
+
if "hp" in json1 and "hp" in json2:
|
| 777 |
+
if json1["hp"] <= 0 and json1["hp"] < json2["hp"]:
|
| 778 |
+
unique1 = get_unique_from_json(name1, json1)
|
| 779 |
+
unique2 = get_unique_from_json(name2, json2)
|
| 780 |
+
return detailed_attr_player1, detailed_attr_player2, display_board, "", "", "战斗结束!请清除战斗或者重新生成人物"
|
| 781 |
+
|
| 782 |
+
if json2["hp"] <= 0 and json2["hp"] < json1["hp"]:
|
| 783 |
+
unique1 = get_unique_from_json(name1, json1)
|
| 784 |
+
unique2 = get_unique_from_json(name2, json2)
|
| 785 |
+
return detailed_attr_player1, detailed_attr_player2, display_board, "", "", "战斗结束!请清除战斗或者重新生成人物"
|
| 786 |
+
|
| 787 |
+
game_manager = GameManager(json1, json2, detailed_skill_player1, detailed_skill_player2)
|
| 788 |
+
msgs, new_player1, new_player2 = game_manager.run()
|
| 789 |
+
for msg in msgs:
|
| 790 |
+
display_board.append(msg)
|
| 791 |
+
|
| 792 |
+
if game_manager.flag == "player1_win":
|
| 793 |
+
unique1 = get_unique_from_json(name1, json1)
|
| 794 |
+
unique2 = get_unique_from_json(name2, json2)
|
| 795 |
+
update_elo(unique1, unique2)
|
| 796 |
+
elif game_manager.flag == "player2_win":
|
| 797 |
+
unique1 = get_unique_from_json(name1, json1)
|
| 798 |
+
unique2 = get_unique_from_json(name2, json2)
|
| 799 |
+
update_elo(unique2, unique1)
|
| 800 |
+
|
| 801 |
+
new_player1_str = json.dumps(new_player1, ensure_ascii=False)
|
| 802 |
+
new_player2_str = json.dumps(new_player2, ensure_ascii=False)
|
| 803 |
+
|
| 804 |
+
return new_player1_str, new_player2_str, display_board, get_attr_str_short(new_player1), get_attr_str_short(
|
| 805 |
+
new_player2), status
|
| 806 |
+
|
| 807 |
+
|
| 808 |
+
def callback_random_role(display_board):
|
| 809 |
+
data = get_random_fighter()
|
| 810 |
+
name = data["name"]
|
| 811 |
+
json_str = data["attr_str"]
|
| 812 |
+
skills_jsonl = data["skills"]
|
| 813 |
+
json_answer = json.loads(json_str)
|
| 814 |
+
display_board.append(("从数据库选择角色" + name, None))
|
| 815 |
+
return name, json_str, skills_jsonl, get_attr_str_short(json_answer), get_skill_str_short(
|
| 816 |
+
json_answer), display_board
|
| 817 |
+
|
| 818 |
+
|
| 819 |
+
def callback_role_from_name(display_board, name):
|
| 820 |
+
data = searching_fighter_on_elo(name)
|
| 821 |
+
json_str = data["attr_str"]
|
| 822 |
+
skills_jsonl = data["skills"]
|
| 823 |
+
json_answer = json.loads(json_str)
|
| 824 |
+
display_board.append(("从数据库选择角色" + name, None))
|
| 825 |
+
return name, json_str, skills_jsonl, get_attr_str_short(json_answer), get_skill_str_short(
|
| 826 |
+
json_answer), display_board
|
| 827 |
+
|
| 828 |
+
|
| 829 |
+
def callback_clean_fight(display_board, detailed_attr_player1, detailed_attr_player2):
|
| 830 |
+
display_board = []
|
| 831 |
+
json1 = json.loads(detailed_attr_player1)
|
| 832 |
+
json2 = json.loads(detailed_attr_player2)
|
| 833 |
+
if "hp" in json1:
|
| 834 |
+
del json1["hp"]
|
| 835 |
+
if "hp" in json2:
|
| 836 |
+
del json2["hp"]
|
| 837 |
+
|
| 838 |
+
new_detailed_attr_player1 = json.dumps(json1, ensure_ascii=False)
|
| 839 |
+
new_detailed_attr_player2 = json.dumps(json2, ensure_ascii=False)
|
| 840 |
+
|
| 841 |
+
return display_board, new_detailed_attr_player1, new_detailed_attr_player2
|
| 842 |
+
|
| 843 |
+
|
| 844 |
+
def callback_refresh_rank():
|
| 845 |
+
return get_rank_str()
|
| 846 |
+
|
| 847 |
+
|
| 848 |
+
with gr.Blocks() as demo:
|
| 849 |
+
gr.Markdown(
|
| 850 |
+
"""
|
| 851 |
+
# LuotuoFighter
|
| 852 |
+
|
| 853 |
+
## 骆驼大乱斗
|
| 854 |
+
|
| 855 |
+
Implemented by 李鲁鲁
|
| 856 |
+
|
| 857 |
+
项目链接 https://github.com/LC1332/Chat-Haruhi-Suzumiya
|
| 858 |
+
|
| 859 |
+
这个原型是为了百川Hackathon而初步建立
|
| 860 |
+
|
| 861 |
+
三种角色建立方式: 根据姓名召唤、随机召唤,或者输入姓名和描述后生成新的人物
|
| 862 |
+
姓名召唤会召唤同名人物中战力最强的那个
|
| 863 |
+
由于Gradio特性,建立角色要花个几十秒,先点击生成功法,再点击生成功法描述
|
| 864 |
+
"""
|
| 865 |
+
)
|
| 866 |
+
|
| 867 |
+
with gr.Row():
|
| 868 |
+
with gr.Column():
|
| 869 |
+
current_status = gr.Textbox(label="当前状态", value="请输入角色1的姓名之后生成功法,或进行召唤")
|
| 870 |
+
|
| 871 |
+
display_board = gr.Chatbot(height=800)
|
| 872 |
+
|
| 873 |
+
submit_fight2 = gr.Button("继续战斗!")
|
| 874 |
+
clean_fight = gr.Button("清空战斗")
|
| 875 |
+
|
| 876 |
+
with gr.Column():
|
| 877 |
+
with gr.Row():
|
| 878 |
+
name_player1 = gr.Textbox(label="角色1姓名", scale=1, interactive=True, value="李鲁鲁")
|
| 879 |
+
desc_player1 = gr.Textbox(label="角色1描述", scale=20, value="师从,主修剑法", interactive=True)
|
| 880 |
+
|
| 881 |
+
with gr.Row():
|
| 882 |
+
generate_ma_player1 = gr.Button("生成功法")
|
| 883 |
+
generate_madetail_player1 = gr.Button("生成功法描述")
|
| 884 |
+
|
| 885 |
+
with gr.Row():
|
| 886 |
+
random_sel_player1 = gr.Button("随机召唤")
|
| 887 |
+
call_player1_with_name1 = gr.Button("根据姓名召唤")
|
| 888 |
+
|
| 889 |
+
with gr.Row():
|
| 890 |
+
name_player2 = gr.Textbox(label="角色2姓名", scale=1, interactive=True, value="冷子昂")
|
| 891 |
+
desc_player2 = gr.Textbox(label="角色2描述", scale=20, value="师从,主修剑法", interactive=True)
|
| 892 |
+
with gr.Row():
|
| 893 |
+
generate_ma_player2 = gr.Button("生成功法")
|
| 894 |
+
generate_madetail_player2 = gr.Button("生成功法描述")
|
| 895 |
+
|
| 896 |
+
with gr.Row():
|
| 897 |
+
random_sel_player2 = gr.Button("随机召唤2")
|
| 898 |
+
call_player1_with_name2 = gr.Button("根据姓名召唤2")
|
| 899 |
+
|
| 900 |
+
with gr.Row():
|
| 901 |
+
submit_fight = gr.Button("继续战斗!")
|
| 902 |
+
|
| 903 |
+
with gr.Row():
|
| 904 |
+
attr_player1 = gr.TextArea(label="角色1属性")
|
| 905 |
+
skill_player1 = gr.TextArea(label="角色1功法描述")
|
| 906 |
+
|
| 907 |
+
with gr.Row():
|
| 908 |
+
attr_player2 = gr.TextArea(label="角色2属性")
|
| 909 |
+
skill_player2 = gr.TextArea(label="角色2功法描述")
|
| 910 |
+
|
| 911 |
+
with gr.Row():
|
| 912 |
+
refresh_rank = gr.Button("刷新天梯")
|
| 913 |
+
|
| 914 |
+
with gr.Row():
|
| 915 |
+
rank_showboard = gr.TextArea(label="天梯")
|
| 916 |
+
|
| 917 |
+
with gr.Row():
|
| 918 |
+
with gr.Column():
|
| 919 |
+
detailed_description_player1 = gr.TextArea(label="角色1具体描述")
|
| 920 |
+
detailed_skill_player1 = gr.TextArea(label="角色1技能json")
|
| 921 |
+
detailed_attr_player1 = gr.TextArea(label="角色1属性json")
|
| 922 |
+
|
| 923 |
+
with gr.Column():
|
| 924 |
+
detailed_description_player2 = gr.TextArea(label="角色2具体描述")
|
| 925 |
+
detailed_skill_player2 = gr.TextArea(label="角色2技能json")
|
| 926 |
+
detailed_attr_player2 = gr.TextArea(label="角色2属性json")
|
| 927 |
+
|
| 928 |
+
generate_ma_player1.click(fn=generate_ma, inputs=[name_player1, desc_player1, display_board],
|
| 929 |
+
outputs=[detailed_description_player1, detailed_attr_player1, attr_player1, skill_player1,
|
| 930 |
+
display_board, current_status])
|
| 931 |
+
generate_ma_player2.click(fn=generate_ma, inputs=[name_player2, desc_player2, display_board],
|
| 932 |
+
outputs=[detailed_description_player2, detailed_attr_player2, attr_player2, skill_player2,
|
| 933 |
+
display_board, current_status])
|
| 934 |
+
generate_madetail_player1.click(fn=generate_madetail, inputs=[detailed_attr_player1, display_board],
|
| 935 |
+
outputs=[detailed_skill_player1, display_board, current_status])
|
| 936 |
+
generate_madetail_player2.click(fn=generate_madetail, inputs=[detailed_attr_player2, display_board],
|
| 937 |
+
outputs=[detailed_skill_player2, display_board, current_status])
|
| 938 |
+
|
| 939 |
+
random_sel_player1.click(fn=callback_random_role, inputs=[display_board],
|
| 940 |
+
outputs=[name_player1, detailed_attr_player1, detailed_skill_player1, attr_player1,
|
| 941 |
+
skill_player1, display_board])
|
| 942 |
+
random_sel_player2.click(fn=callback_random_role, inputs=[display_board],
|
| 943 |
+
outputs=[name_player2, detailed_attr_player2, detailed_skill_player2, attr_player2,
|
| 944 |
+
skill_player2, display_board])
|
| 945 |
+
|
| 946 |
+
call_player1_with_name1.click(fn=callback_role_from_name, inputs=[display_board, name_player1],
|
| 947 |
+
outputs=[name_player1, detailed_attr_player1, detailed_skill_player1, attr_player1,
|
| 948 |
+
skill_player1, display_board])
|
| 949 |
+
call_player1_with_name2.click(fn=callback_role_from_name, inputs=[display_board, name_player2],
|
| 950 |
+
outputs=[name_player2, detailed_attr_player2, detailed_skill_player2, attr_player2,
|
| 951 |
+
skill_player2, display_board])
|
| 952 |
+
|
| 953 |
+
refresh_rank.click(fn=callback_refresh_rank, inputs=[], outputs=[rank_showboard])
|
| 954 |
+
|
| 955 |
+
clean_fight.click(fn=callback_clean_fight, inputs=[display_board, detailed_attr_player1, detailed_attr_player2],
|
| 956 |
+
outputs=[display_board, detailed_attr_player1, detailed_attr_player2])
|
| 957 |
+
|
| 958 |
+
submit_fight.click(fn=continue_fight,
|
| 959 |
+
inputs=[detailed_attr_player1, detailed_attr_player2, detailed_skill_player1,
|
| 960 |
+
detailed_skill_player2, display_board],
|
| 961 |
+
outputs=[detailed_attr_player1, detailed_attr_player2, display_board, attr_player1, attr_player2,
|
| 962 |
+
current_status])
|
| 963 |
+
|
| 964 |
+
submit_fight2.click(fn=continue_fight,
|
| 965 |
+
inputs=[detailed_attr_player1, detailed_attr_player2, detailed_skill_player1,
|
| 966 |
+
detailed_skill_player2, display_board],
|
| 967 |
+
outputs=[detailed_attr_player1, detailed_attr_player2, display_board, attr_player1,
|
| 968 |
+
attr_player2, current_status])
|
| 969 |
+
|
| 970 |
+
demo.launch(debug=False, share=True)
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
openai
|
| 2 |
+
gradio
|
| 3 |
+
tiktoken
|
| 4 |
+
langchain
|