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