Upload folder using huggingface_hub
Browse files- demo_hf_space.py +220 -0
demo_hf_space.py
ADDED
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import re
|
3 |
+
|
4 |
+
from create_world.creator_gradio import create_custom_world, create_scenario, create_storyline
|
5 |
+
from create_world.utils import load_txt
|
6 |
+
from create_character.gradio import generate_character_creation_questions, create_character_profile, parse_character_data_to_json
|
7 |
+
from play_game.main import create_initial_conversation, create_round_description, create_round_result, create_bad_ending, create_good_ending, convert_to_image_prompt, generate_image
|
8 |
+
from play_game.formatter import player_profile_to_str, to_round_result
|
9 |
+
|
10 |
+
# 1. Main & World Selection
|
11 |
+
# 2. Character Creation
|
12 |
+
# 3. Game Play
|
13 |
+
|
14 |
+
def main():
|
15 |
+
with gr.Blocks() as demo:
|
16 |
+
gr.Markdown("## LRPG")
|
17 |
+
game_topic = gr.State()
|
18 |
+
world_summary = gr.State()
|
19 |
+
stories = gr.State([])
|
20 |
+
player_profile = gr.State()
|
21 |
+
|
22 |
+
with gr.Tab("κ²μ μΈκ³ μμ±"):
|
23 |
+
theme_choices = gr.Radio(["Harry Potter", "μ§μ μμ±"], label="ν
λ§ μ ν", info="κ²μμ ν
λ§λ₯Ό μ ννμΈμ.")
|
24 |
+
|
25 |
+
@gr.render(inputs=[theme_choices])
|
26 |
+
def on_world_choices(theme):
|
27 |
+
if theme == "μ§μ μμ±":
|
28 |
+
topic = gr.Textbox("ex)λ§λ²μ¬ μΈκ³, μ°μ£Ό μ μ", label="μ£Όμ ", info="μΈκ³μ μ£Όμ λ₯Ό μλ €μ£ΌμΈμ.", interactive=True)
|
29 |
+
world_story = gr.Textbox(label="μ€λͺ
", info="ꡬ체μ μΈ μΈκ³κ΄ μ€λͺ
κ³Ό λ£°μ μκ°νμΈμ", interactive=True)
|
30 |
+
world_create_btn = gr.Button("μΈκ³κ΄ μλ μμ±")
|
31 |
+
create_story_btn = gr.Button("μ€ν 리 μμ±", visible=False)
|
32 |
+
result = gr.Markdown("## μ€ν 리 μμ±μ΄ μλ£λμμ΅λλ€. μΊλ¦ν° μμ± νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
|
33 |
+
|
34 |
+
# @world_create_btn.click(inputs=[ topic, world_story ], outputs=[ game_topic, world_summary, create_story_btn ])
|
35 |
+
def click_world_create_btn(topic, world_story):
|
36 |
+
gr.Info("μΈκ³κ΄ μμ±μ€μ
λλ€...")
|
37 |
+
topic, summary = create_custom_world(topic, world_story)
|
38 |
+
gr.Info("μΈκ³κ΄ μμ± μλ£!")
|
39 |
+
return { game_topic: topic, world_summary: summary, create_story_btn: gr.Button(visible=True) }
|
40 |
+
world_create_btn.click(fn=click_world_create_btn, inputs=[ topic, world_story ], outputs=[ game_topic, world_summary, create_story_btn ])
|
41 |
+
|
42 |
+
# @create_story_btn.click(inputs=[ game_topic, world_summary ], outputs= [ stories, result ])
|
43 |
+
def click_create_story_btn(topic, summary):
|
44 |
+
gr.Info("μ€ν 리 μμ±μ€μ
λλ€...")
|
45 |
+
scenario = create_scenario(topic, summary, output_count=1, save=False)
|
46 |
+
_stories = create_storyline(topic, scenario[0], save=False)
|
47 |
+
gr.Info("μ€ν 리 μμ± μλ£!")
|
48 |
+
return { stories: _stories, result: gr.Markdown(visible=True) }
|
49 |
+
create_story_btn.click(fn=click_create_story_btn, inputs=[ game_topic, world_summary ], outputs= [ stories, result ])
|
50 |
+
|
51 |
+
elif theme == "Harry Potter":
|
52 |
+
create_story_btn = gr.Button("μ€ν 리 μμ±")
|
53 |
+
result = gr.Markdown("## μ€ν 리 μμ±μ΄ μλ£λμμ΅λλ€. μΊλ¦ν° μμ± νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
|
54 |
+
def click_create_story_btn():
|
55 |
+
gr.Info("μ€ν 리 μμ±μ€μ
λλ€...")
|
56 |
+
topic = "Harry Potter"
|
57 |
+
_world_summary = load_txt("harrypotter_scenario/world_summary.txt")
|
58 |
+
scenario = create_scenario(topic, _world_summary, output_count=1, save=False)
|
59 |
+
_stories = create_storyline(topic, scenario[0], save=False)
|
60 |
+
gr.Info("μ€ν 리 μμ± μλ£!")
|
61 |
+
return { game_topic: topic, world_summary: _world_summary, stories: _stories, result: gr.Markdown(visible=True) }
|
62 |
+
create_story_btn.click(fn=click_create_story_btn, outputs=[ game_topic, world_summary, stories, result ])
|
63 |
+
|
64 |
+
with gr.Tab("μΊλ¦ν° μμ±"):
|
65 |
+
@gr.render(inputs=[world_summary])
|
66 |
+
def on_game_topic(summary):
|
67 |
+
questions = generate_character_creation_questions(summary)
|
68 |
+
answers = []
|
69 |
+
for question_idx, question in enumerate(questions):
|
70 |
+
answer = gr.Textbox(key=question_idx, label=question, placeholder="λΉμ μ λλ΅μ μ
λ ₯νμΈμ.", interactive=True)
|
71 |
+
answers.append(answer)
|
72 |
+
char_create_btn = gr.Button("μΊλ¦ν° μμ±")
|
73 |
+
result = gr.Markdown("## μΊλ¦ν° μμ±μ΄ μλ£λμμ΅λλ€. κ²μ μ§ν νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
|
74 |
+
|
75 |
+
def click_char_create_btn(*_answers):
|
76 |
+
gr.Info("μΊλ¦ν° μοΏ½οΏ½μ€μ
λλ€...")
|
77 |
+
character_profile = parse_character_data_to_json(create_character_profile(questions, _answers))
|
78 |
+
profile_keys = [key for key in character_profile.keys()]
|
79 |
+
required_keys = ["name", "gender", "age", "race", "job", "background"]
|
80 |
+
params_keys = [key for key in character_profile["params"].keys()]
|
81 |
+
required_params_keys = ["stamina", "intelligence", "combat_power", "agility"]
|
82 |
+
if not all(item in profile_keys for item in required_keys) or not all(item in params_keys for item in required_params_keys):
|
83 |
+
gr.Error("μΊλ¦ν° μμ±μ μ€ν¨νμ΅λλ€. νλͺ©λ€μ μμΈνκ² λΉ μ§μμ΄ κΈ°μ
ν΄μ£ΌμΈμ.")
|
84 |
+
return
|
85 |
+
gr.Info("μΊλ¦ν° μμ± μλ£!")
|
86 |
+
return { player_profile: character_profile, result: gr.Markdown(visible=True) }
|
87 |
+
char_create_btn.click(fn=click_char_create_btn, inputs=answers, outputs=[player_profile, result])
|
88 |
+
|
89 |
+
|
90 |
+
with gr.Tab("κ²μ νλ μ΄"):
|
91 |
+
round = gr.State(0)
|
92 |
+
player_restriction = gr.State()
|
93 |
+
player_capability = gr.State()
|
94 |
+
previous_conversation = gr.State("")
|
95 |
+
previous_round_result = gr.State("")
|
96 |
+
|
97 |
+
@gr.render(inputs=[world_summary, stories, player_profile, round, player_restriction, player_capability, previous_conversation, previous_round_result, game_topic], triggers=[round.change, player_profile.change])
|
98 |
+
def on_round(_world_summary, _stories, _player_profile, _round, _player_restriction, _player_capability, _previous_conversation, _previous_round_result, _game_topic):
|
99 |
+
entire_story = [f"{idx+1}. {scenario['title']}\n{scenario['story']}\n\n" for idx, scenario in enumerate(_stories)]
|
100 |
+
player_profile_str = player_profile_to_str({ **_player_profile, 'params': _player_capability })
|
101 |
+
|
102 |
+
round_scenario = _stories[_round-1]
|
103 |
+
if _round == 0:
|
104 |
+
introduction = gr.Markdown(create_initial_conversation(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story))
|
105 |
+
game_start_btn = gr.Button("κ²μ μμ")
|
106 |
+
|
107 |
+
def click_game_start_btn():
|
108 |
+
return { round: 1, player_restriction: { "life": 20, "money": 20 }, player_capability: _player_profile["params"] }
|
109 |
+
game_start_btn.click(fn=click_game_start_btn, outputs=[round, player_restriction, player_capability])
|
110 |
+
else:
|
111 |
+
round_story = f"{_round}. {round_scenario['title']}: {round_scenario['story']}\n"
|
112 |
+
if _player_restriction["life"] <= 0 or _player_restriction["money"] <= 0:
|
113 |
+
gr.Markdown("## μμ½κ²λ κ²μ μ€λ²λμμ΅λλ€. λ€λ₯Έ μ νμ ν΅ν΄ μλ‘μ΄ μ΄μΌκΈ°μ κ²°λ§μ λ§λ€μ΄λ³΄μΈμ.")
|
114 |
+
bad_ending = create_bad_ending(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, round_story, _previous_conversation, _previous_round_result)
|
115 |
+
display_bad_ending = gr.Markdown(bad_ending)
|
116 |
+
restart_button = gr.Button("λ€μ μμνκΈ°")
|
117 |
+
def click_restart_button():
|
118 |
+
return { round: 0, player_restriction: {}, player_capability: {}, previous_conversation: "", previous_round_result: "" }
|
119 |
+
restart_button.click(fn=click_restart_button, outputs=[round, player_restriction, player_capability, previous_conversation, previous_round_result])
|
120 |
+
|
121 |
+
elif _round > len(_stories):
|
122 |
+
gr.Markdown("## μΆνν©λλ€! κ²μ ν΄λ¦¬μ΄μ μ±κ³΅νμ
¨μ΅λλ€")
|
123 |
+
good_ending = create_good_ending(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, _previous_conversation)
|
124 |
+
display_good_ending = gr.Markdown(good_ending)
|
125 |
+
restart_button = gr.Button("λ€μ μμνκΈ°")
|
126 |
+
def click_restart_button():
|
127 |
+
return { round: 0, player_restriction: {}, player_capability: {}, previous_conversation: "", previous_round_result: "" }
|
128 |
+
restart_button.click(fn=click_restart_button, outputs=[round, player_restriction, player_capability, previous_conversation, previous_round_result])
|
129 |
+
|
130 |
+
else:
|
131 |
+
round_description = create_round_description(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, round_story, _previous_conversation, _previous_round_result)
|
132 |
+
gr.Markdown(f"## {_round}. {round_scenario['title']}")
|
133 |
+
with gr.Row():
|
134 |
+
gr.Markdown(round_description)
|
135 |
+
with gr.Column():
|
136 |
+
image_output = gr.Image(interactive=False, scale=5)
|
137 |
+
generate_image_btn = gr.Button("μ΄λ―Έμ§ μμ±", interactive=False)
|
138 |
+
def click_generate_image_btn():
|
139 |
+
gr.Info("μ΄λ―Έμ§ μμ±μ€μ
λλ€...")
|
140 |
+
image_generation_prompt = convert_to_image_prompt(_game_topic, _world_summary, _player_profile, round_description)
|
141 |
+
image_url = generate_image(image_generation_prompt)
|
142 |
+
gr.Info("μ΄λ―Έμ§ μμ± μλ£!")
|
143 |
+
return gr.Image(image_url)
|
144 |
+
generate_image_btn.click(fn=click_generate_image_btn, outputs=image_output)
|
145 |
+
|
146 |
+
with gr.Row():
|
147 |
+
player_response = gr.Textbox(label="λΉμ λ§μ κ²°μ μ λ΄λ €μ£ΌμΈμ!", info="νλμ λ¬Έμ₯μΌλ‘ λΉμ μ΄ ν νλκ³Ό κ·Έμ λν κ·Όκ±°μ μ΄μ λ₯Ό λͺ
ννκ² μ€λͺ
ν΄μ£ΌμΈμ", interactive=True, scale=10)
|
148 |
+
submit_btn = gr.Button("κ²°μ ", scale=1)
|
149 |
+
|
150 |
+
def click_submit_btn(_player_response, _previous_conversation, _player_restriction, _player_capability):
|
151 |
+
gr.Info("κ²°μ μ λ°μμ€μ
λλ€...")
|
152 |
+
__round = _round
|
153 |
+
_round_description = round_description
|
154 |
+
|
155 |
+
# Reflect the result and update player status
|
156 |
+
round_result = create_round_result(_world_summary, player_profile_str, _player_restriction, _player_capability, _round_description, _player_response)
|
157 |
+
round_effect = round_result["effect"]
|
158 |
+
round_result_explanation = round_result["reason"]
|
159 |
+
for key, value in round_effect["player_restriction"].items():
|
160 |
+
if _player_restriction.get(key) is not None:
|
161 |
+
modified_value = _player_restriction[key] + value
|
162 |
+
if modified_value > 10:
|
163 |
+
_player_restriction[key] = 10
|
164 |
+
elif modified_value < -10:
|
165 |
+
_player_restriction[key] = -10
|
166 |
+
else:
|
167 |
+
_player_restriction[key] = modified_value
|
168 |
+
|
169 |
+
for key, value in round_effect["player_capability"].items():
|
170 |
+
if _player_capability.get(key) is not None:
|
171 |
+
modified_value = _player_capability[key] + value
|
172 |
+
if modified_value > 100:
|
173 |
+
_player_capability[key] = 100
|
174 |
+
elif modified_value < -100:
|
175 |
+
_player_capability[key] = -100
|
176 |
+
else:
|
177 |
+
_player_capability[key] = modified_value
|
178 |
+
|
179 |
+
return {
|
180 |
+
round: __round+1,
|
181 |
+
previous_conversation: _previous_conversation + f"Game Master: {_round_description}\nPlayer: {_player_response}\n",
|
182 |
+
previous_round_result: to_round_result(round_effect, round_result_explanation),
|
183 |
+
player_restriction: _player_restriction,
|
184 |
+
player_capability: _player_capability,
|
185 |
+
}
|
186 |
+
submit_btn.click(
|
187 |
+
fn=click_submit_btn,
|
188 |
+
inputs=[ player_response, previous_conversation, player_restriction, player_capability ],
|
189 |
+
outputs=[round, previous_conversation, previous_round_result, player_restriction, player_capability]
|
190 |
+
)
|
191 |
+
|
192 |
+
player_name = re.sub(r'"', '', _player_profile['name'])
|
193 |
+
player_status_display = gr.Markdown(f"## {player_name}λμ μν")
|
194 |
+
with gr.Group():
|
195 |
+
with gr.Row():
|
196 |
+
gr.Textbox(_player_restriction['life'], interactive=False, label="λͺ©μ¨")
|
197 |
+
gr.Textbox(_player_restriction['money'], interactive=False, label="μμ§κΈ")
|
198 |
+
with gr.Row():
|
199 |
+
gr.Textbox(_player_capability["stamina"], interactive=False, label="μ€νλ―Έλ")
|
200 |
+
gr.Textbox(_player_capability["intelligence"], interactive=False, label="μ§λ₯")
|
201 |
+
gr.Textbox(_player_capability["combat_power"], interactive=False, label="μ ν¬λ ₯")
|
202 |
+
gr.Textbox(_player_capability["agility"], interactive=False, label="민첩μ±")
|
203 |
+
|
204 |
+
|
205 |
+
# # For Debugging
|
206 |
+
# game_topic_debugging = gr.Textbox(game_topic.value, label="game_topic_debugging")
|
207 |
+
# game_topic.change(lambda x: gr.Textbox(x), inputs=[game_topic], outputs=game_topic_debugging)
|
208 |
+
# world_summary_debugging=gr.Textbox(world_summary.value, label="world_summary_debugging")
|
209 |
+
# world_summary.change(lambda x: gr.Textbox(x), inputs=[world_summary], outputs=world_summary_debugging)
|
210 |
+
# stories_debugging=gr.Textbox(stories.value, label="stories_debugging")
|
211 |
+
# stories.change(lambda x: gr.Textbox(x), inputs=[stories], outputs=stories_debugging)
|
212 |
+
# player_profile_debugging=gr.Textbox(player_profile.value, label="player_profile_debugging")
|
213 |
+
# player_profile.change(lambda x: gr.Textbox(x), inputs=[player_profile], outputs=player_profile_debugging)
|
214 |
+
|
215 |
+
|
216 |
+
demo.launch()
|
217 |
+
|
218 |
+
|
219 |
+
if __name__ == "__main__":
|
220 |
+
main()
|