File size: 8,567 Bytes
bcf0302
0a0d866
 
bcf0302
 
 
 
 
 
 
0a0d866
bcf0302
0a0d866
bcf0302
4e30523
bcf0302
0a0d866
bcf0302
 
0a0d866
bcf0302
 
4e30523
 
 
 
 
bcf0302
 
 
 
 
 
 
 
 
0a0d866
 
 
 
 
 
 
b41b224
 
 
 
bcf0302
b41b224
bcf0302
 
 
 
 
 
 
 
 
 
 
0a0d866
 
 
 
 
bcf0302
 
 
 
 
4e30523
 
 
 
 
 
 
 
 
0a0d866
4e30523
 
 
 
 
 
0a0d866
4e30523
 
 
 
bcf0302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4e30523
bcf0302
 
 
 
 
 
 
 
 
 
0a0d866
 
4e30523
 
0a0d866
 
 
 
 
 
bcf0302
 
0a0d866
 
 
 
 
bcf0302
 
0a0d866
 
 
 
 
 
 
 
 
 
 
 
 
bcf0302
 
0a0d866
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b41b224
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
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)