Package: lpsim
Lochfolk Prinzessin Simulator (LPSim): 水皇模拟器，一个七圣召唤模拟器English README该仓库为水皇模拟器的后端，用来模拟七圣召唤对局，使用Python 3.10编写，使用Pydantic和FastAPI。项目另有一个前端仓库，包含可以与该后端交互的前端页面。该项目使用AGPL-3.0协议。如果您有任何基于此项目的二次开发和分发，请遵守该协议。声明本项目仅供学习交流使用，前端界面仅用于展示对局状态和方便代码调试。请在下载后24小时内删除与本项目相关的所有内容。所有相关代码基于AGPLv3协议开源。项目与米哈游公司无关，所有游戏素材版权归米哈游公司所有。本项目及其代码仓库中不包含米哈游具有版权的图像素材，或是任何与米哈游产品相关的非公开信息。项目进度已实现所有4.4版本及以前的角色和卡牌，包括平衡性调整。:sparkles: NEW: 4.4版本角色和卡牌，以及平衡性调整已实现。特性已实现所有截止当前版本的角色和卡牌，包括其历史版本。支持在同一套卡组中使用不同版本的角色和卡牌。支持作为一个小型服务器与客户端交互。提供了一个前端用来与服务器交互。可以从任意状态加载并继续运行，保持结果不变。100%代码覆盖率。使用方法该项目需要Python 3.10或更新版本。使用pip安装使用pip install lpsim安装最新的发布版本。你可以在PyPI找到最新的发布版本，在CHANGELOG.md找到更新日志。使用pip install lpsim -i https://test.pypi.org/simple/安装最新的开发版本。当新的提交被推送到master分支并通过所有测试时，新的版本将会被发布到Test PyPI。当新的版本tag被推送到master分支时，新的版本将会被发布到PyPI。使用源码安装克隆该仓库并使用pip install .安装。HTTP服务器对局服务器使用FastAPI提供一个HTTP对局服务器，用来与客户端交互。使用以下命令运行服务器：from lpsim.network import HTTPServer
server = HTTPServer()
server.run()它将在localhost:8000上开启一个FastAPI服务器，并接受本地连接。在初始化HTTPServer时，你可以设置卡组和对局配置来创建一个带有指定规则的对局。启动服务器后，打开前端页面，在右上角修改服务器URL（默认为http://localhost:8000），按照页面上的指示设置卡组，并开始对局。目前异常处理比较混乱，错误可能导致游戏状态变为ERROR，服务器抛出异常，客户端返回空响应，返回404/500，或者前端运行JS失败。请打开前端的控制台，并在前端后后端查看错误信息。房间服务器你可以使用房间服务器来提供多个对局。它管理多个HTTP服务器实例，前端可以创建新的房间或加入已有的房间。当一个新的房间被创建时，房间服务器会告诉前端房间名和它运行的端口，然后前端会连接到该端口上的HTTP服务器。当一个房间创建了很长时间并且没有收到POST请求时，它会自动关闭。更多细节请参考lpsim/network/http_room_server.py和http_room_serve.py。非交互对局非交互对局主要用于代码测试和AI训练。你可以按照下述流程进行。定义卡组开始对局之前，需要先定义卡组。卡组可以使用文本或JSON格式定义。通常使用Deck.from_str就足够了，它可以定义角色和卡牌，以及控制它们的版本。下面的示例代码中的卡组字符串展示了卡组定义的语法，所有卡牌都使用4.1版本，除了风与自由，它使用4.0版本（因为它在3.7版本之后没有改变，当指定4.0版本时，卡组会自动选择3.7版本）。同时，也支持使用牌组分享码导入牌组。更多细节请参考server/deck.py。开始对局初始化一个新的server.Match实例。使用set_deck函数为玩家分配卡组。如果需要，修改Match.config。卡组设置完成后，使用Match.start函数开始对局。它会根据配置和卡组初始化对局。如果出现错误（例如卡组不合法），它会返回False和具体错误信息。使用Match.step函数推进对局。默认情况下，该函数会持续执行，直到对局结束或者生成需要响应的请求。为了更方便的响应请求，在agents模块中项目包含了一些简单的代理。这些代理可以响应各种请求。特别的，InteractionAgent可以解析命令行并生成响应，使用命令行交互时较为方便。同时，该代理也是前端和后端交互时使用的代理。示例代码fromlpsimimportMatch,Deckfromlpsim.agentsimportRandomAgentdeck_string='''default_version:4.1character:Fischlcharacter:Monacharacter:NahidaGambler's Earrings*2Wine-Stained Tricorne*2VanaranaTimmie*2Rana*2Covenant of RockWind and Freedom@4.0The Bestest Travel Companion!*2Changing Shifts*2Toss-UpStrategize*2I Haven't Lost Yet!*2Leave It to Me!Calx's Arts*2Adeptus' Temptation*2Lotus Flower Crisp*2Mondstadt Hash Brown*2Tandoori Roast Chicken'''deck0=Deck.from_str(deck_string)deck1=Deck.from_str(deck_string)match=Match()match.set_deck([deck0,deck1])match.start()match.step()agent_0=RandomAgent(player_idx=0)agent_1=RandomAgent(player_idx=1)whilenotmatch.is_game_end():ifmatch.need_respond(0):match.respond(agent_0.generate_response(match))elifmatch.need_respond(1):match.respond(agent_1.generate_response(match))match.step()print(f'winner is{match.winner}')自定义角色和卡牌自定义角色和卡牌前，你需要了解actions, event handlers和value modifiers。所有与对局的交互（一个实例需要修改对局中其他实例的状态）都是通过actions完成的，所有的actions都是由events触发的。value modifiers用来修改值，例如骰子消耗和伤害数值/类型。最简单的实现一个新的对象的方法是参考并复制一个已有的卡牌/角色/技能/状态...并修改它。你可以在细节中找到更多信息。templates/character.py是一个角色的模板。你可以复制它并修改它来实现一个新的角色。你可以定义任何与角色相关的对象，例如技能、天赋、召唤、状态。然后，你需要为这些对象创建描述，描述将会在前端中使用，class registry会拒绝没有描述的对象。最后，使用register_class函数将所有对象以及它们的描述注册到class registry中，就可以在对局中使用它们了。定义一个新的卡牌相对简单，你可以参考templates/card.py，它定义了一个新的卡牌“大心海”，它消耗2个任意骰子并抽3张牌。作为自定义卡牌的示例，在这个文件里使用了absolute import，因此可以在项目外直接使用。你可以手动注册新的对象并在对局中使用它们。以“大心海”为例，首先安装lpsim，然后在import lpsim之后输入import templates.card。然后你可以通过a = HTTPServer(); a.run()创建一个HTTP服务器，你会发现修改卡组时一个新的卡牌被添加到了候选卡牌列表中。总代码如下，在项目根目录运行：importlpsimimporttemplates.carda=lpsim.HTTPServer()a.run()细节使用Pydantic保存和加载对局状态，导出的数据可以用来恢复对局到某个状态并继续运行，也可以用来渲染前端的对局状态。兼容不同版本的角色和卡牌。例如你可以开启一个3.8版本的双岩一斗和3.3版本的双岩剑鬼的对局，或者使用3.3的神宵和3.7的申鹤配合4.3的新行动牌和装备。通过request和response来交互。当request列表不为空时，代理需要响应其中的一个请求。当多个玩家需要响应时（例如在游戏开始时选择角色和卡牌），它们的请求会同时生成。对局中的所有修改都是通过action来实现的。每个action都会触发一个事件，并且可能会激活后续的action。这些新激活的action会被添加到现有的action列表的顶部，类似于堆栈列表的结构，参考EventFrame类的实现。对局中所有的对象包含两种触发器：event handlers和value modifiers。事件处理器用来监控事件并产生响应的action列表。值修改器用来修改可变值并在必要时更新内部状态。可修改的值包括初始骰子颜色、伤害和消耗等。所有的代码都使用pytest进行测试，覆盖率100%（除了防御性代码，它们被标记为# pragma: no cover）。由于完全兼容不同版本，当实现了新的版本时，所有已有测试都应该通过而不需要修改。贡献欢迎合作开发项目代码，但是目前没有详细的文档。在贡献代码前，您可以首先阅读CONTRIBUTING.md(英文)，它包含了如何安装开发环境和如何运行测试的信息。如果你想添加新的角色相关的对象（角色、技能、天赋、召唤、状态），请参考server/character/template.py和已经实现的角色。如果你想添加新的卡牌，请参考server/card中已经实现的卡牌。完成代码编写后使用register_class函数注册新的对象到模拟器中即可使用。你可以通过QQ群945778865联系作者，咨询开发和使用上的问题，进群问题的答案是模拟器的中文名。开发这个项目花费了大量(本来用来打牌和打模拟宇宙的)时间。如果你觉得这个项目有帮助，您可以通过微信支持作者。