WorldSimulation / app.py
yingqianjiang-lingoace
update
0a0d866
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)