import gradio as gr import pandas as pd import numpy as np from CharacterStatistics import CharacterStatistics from WorldSimulation import WorldSimulation # 创建一个世界模拟对象 simulation = None num_rounds = 0 def initialize_world(world_spiritual_energy=1000000, resources = 100000, resources_threshold = 10): global simulation simulation = WorldSimulation(world_spiritual_energy=world_spiritual_energy, resources=resources, resources_threshold=resources_threshold) return f"世界初始化成功:\n\n世界灵气能量:{world_spiritual_energy}" def add_custom_character(name, gender, special_constitution, spiritual_roots, clan=None): special_constitution = [1 if i in special_constitution else 0 for i in range(4)] spiritual_roots = [1 if i in spiritual_roots else 0 for i in range(5)] simulation.add_custom_character(name, gender, special_constitution, spiritual_roots, clan) return str(simulation.characters[-1]) def start_simulation(c1, c2, c3, c4, r1, r2, r3, r4, r5, initial_population=3000): special_constitution_ratio = [c1, c2, c3, c4] spiritual_roots_ratio = [r1, r2, r3, r4, r5] initial_population = int(initial_population) simulation.create_population(special_constitution_ratio=special_constitution_ratio, spiritual_roots_ratio=spiritual_roots_ratio, initial_population=initial_population) return f"世界人口数量达到{len(simulation.characters)},可以运行模拟了。" def run_simulation(rounds): global num_rounds num_rounds = rounds if simulation is None: return "请先初始化世界" return simulation.run_simulation(num_rounds) def find_character_by_clan(name): characters = simulation.find_characters_by_clan(name) if len(characters) == 0: return f"没有找到名字为{name}的宗族" else: return "\n\n".join([str(c) for c in characters]) def get_character_info(name): characters = simulation.find_characters_by_name(name) if len(characters) == 0: return f"没有找到名字为{name}的角色" else: return "\n\n".join([str(c) for c in characters]) def get_dead_character_info(character_index): if character_index < len(simulation.dead_characters): return str(simulation.dead_characters[character_index]) else: return f"没有第{character_index}个死亡角色,目前共有{len(simulation.dead_characters)}个死亡角色" def get_world_stats(): stats = CharacterStatistics(simulation.characters) return stats.summarize_markdown() def plot(): y = simulation.history_population df = pd.DataFrame({"x": np.arange(len(y)), "y": y, "spi_count": simulation.history_spi_energy}) return df with gr.Blocks() as demo: # 初始化世界 gr.Markdown("## 初始化世界") with gr.Row(): world_spiritual_energy_input = gr.Number(label="世界灵气能量", value=1000000) initialize_button = gr.Button("初始化世界") output_text = gr.Markdown(label="初始化结果") initialize_button.click(fn=initialize_world, inputs=[ world_spiritual_energy_input], outputs=output_text) # 添加角色 with gr.Accordion("添加角色 (可选)", open=False): gr.Markdown("每次添加一个,添加完可以继续添加。") name_input = gr.Textbox(label="姓名") gender_input = gr.Radio(["男", "女"], label="性别") clan_input = gr.Textbox(label="宗族") special_constitution_input = gr.CheckboxGroup(["战斗体质", "合欢体质", "灵龟体质", "蜉蝣体质"], label="特殊体质", type="index") spiritual_roots_input = gr.CheckboxGroup(["金", "木", "水", "火", "土"], label="灵根", type="index") add_character_button = gr.Button("添加角色") new_character_info_output = gr.Textbox(label="新角色信息") add_character_button.click(fn=add_custom_character, inputs=[name_input, gender_input, special_constitution_input, spiritual_roots_input, clan_input], outputs=new_character_info_output) # 生成初始人口 gr.Markdown("## 生成初始人口") initial_population_input = gr.Number(label="初始人口", value=3000, precision=0) # 特殊体质 gr.Markdown("特殊体质比例") with gr.Row(): special_constitution_ratio_input = [ gr.Number(label="战斗体质", minimum=0, maximum=1, value=0.001), gr.Number(label="合欢体质", minimum=0, maximum=1, value=0.001), gr.Number(label="灵龟体质", minimum=0, maximum=1, value=0.001), gr.Number(label="蜉蝣体质", minimum=0, maximum=1, value=0.001)] # 灵根 gr.Markdown("灵根比例") with gr.Row(): spiritual_roots_ratio_input = [ gr.Number(label="金", minimum=0, maximum=1, value=0.04), gr.Number(label="木", minimum=0, maximum=1, value=0.04), gr.Number(label="水", minimum=0, maximum=1, value=0.04), gr.Number(label="火", minimum=0, maximum=1, value=0.04), gr.Number(label="土", minimum=0, maximum=1, value=0.04)] start_simulation_button = gr.Button("生成初始人口") output_text = gr.Markdown("") start_simulation_button.click(fn=start_simulation, inputs=[*special_constitution_ratio_input, *spiritual_roots_ratio_input, initial_population_input], outputs=output_text) # 运行模拟 gr.Markdown("## 运行模拟\n\n输入轮数,运行模拟,可以多次运行。") with gr.Row(): rounds_input = gr.Number(label="轮数", precision=0, value=1) run_simulation_button = gr.Button("运行模拟") simulation_result_output = gr.Textbox(label="模拟结果") run_simulation_button.click(fn=run_simulation, inputs=[rounds_input], outputs=[simulation_result_output]) # 查看统计信息 get_stats_button = gr.Button("查看统计信息") with gr.Accordion("详细文字统计信息", open=False): with gr.Box(): world_stats_output = gr.Markdown("") plot1 = gr.Plot() with gr.Row(): plot2 = gr.Plot() plot3 = gr.Plot() plot4 = gr.Plot() get_stats_button.click(fn=get_world_stats, inputs=[], outputs=[world_stats_output, plot1, plot2, plot3, plot4]) # 查看角色信息 with gr.Accordion("查看角色信息", open=False): with gr.Row(): character_info_output = gr.Textbox(label="角色信息", info="输入角色名字") get_character_info_button = gr.Button("查看角色信息") character_info_output_display = gr.Textbox(label="角色信息") get_character_info_button.click(fn=get_character_info, inputs=[character_info_output], outputs=[character_info_output_display]) # 查看宗族信息 with gr.Accordion("查看宗族信息", open=False): with gr.Row(): clan_name_input = gr.Textbox(label="宗族名字", info="输入宗族名字") get_clan_characters_button = gr.Button("查看宗族角色") characters_output_display = gr.Textbox(label="角色信息") get_clan_characters_button.click(fn=find_character_by_clan, inputs=[clan_name_input], outputs=[characters_output_display]) with gr.Accordion("查看死亡角色", open=False): with gr.Row(): dead_character_info_output = gr.Number(label="死亡角色信息", info="输入死亡角色序号(按死亡顺序排列)", precision=0) get_dead_character_info_button = gr.Button("查看死亡角色信息") dead_character_info_output_display = gr.Textbox(label="死亡角色信息") get_dead_character_info_button.click(fn=get_dead_character_info, inputs=[dead_character_info_output], outputs=[dead_character_info_output_display]) # 可视化 btn = gr.Button(value="查看人口图表") plot_output = gr.LinePlot( x="x", y="y", title="人口随时间变化图", x_title="年份", y_title="人口数量", overlay_point=True, tooltip=["x", "y"], width=350, height=300, ) btn2 = gr.Button(value="查看灵气图表") plot_output2 = gr.LinePlot( x="x", y="spi_count", title="灵气随时间变化图", x_title="年份", y_title="灵气数量", overlay_point=True, tooltip=["x", "spi_count"], width=350, height=300, ) btn.click(plot, outputs=plot_output) btn2.click(plot, outputs=plot_output2) demo.queue().launch(debug=True)