pizb commited on
Commit
e657945
Β·
verified Β·
1 Parent(s): b94cf26

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. 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()