File size: 16,043 Bytes
0b75c79 97f15a5 0b75c79 1d4890c 0b75c79 97f15a5 0b75c79 1d4890c 0b75c79 97f15a5 0b75c79 b94cf26 97f15a5 0b75c79 1d4890c 0b75c79 91fb83a 97f15a5 0b75c79 |
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 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
import gradio as gr
import re
from create_world.creator_gradio import create_custom_world, create_scenario, create_storyline
from create_world.utils import load_txt
from create_character.gradio import generate_character_creation_questions, create_character_profile, parse_character_data_to_json
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
from play_game.formatter import player_profile_to_str, to_round_result
# 1. Main & World Selection
# 2. Character Creation
# 3. Game Play
def main():
with gr.Blocks() as demo:
gr.Markdown("## LRPG")
game_topic = gr.State()
world_summary = gr.State()
stories = gr.State([])
player_profile = gr.State()
with gr.Tab("κ²μ μΈκ³ μμ±"):
theme_choices = gr.Radio(["Harry Potter", "μ§μ μμ±"], label="ν
λ§ μ ν", info="κ²μμ ν
λ§λ₯Ό μ ννμΈμ.")
@gr.render(inputs=[theme_choices])
def on_world_choices(theme):
if theme == "μ§μ μμ±":
topic = gr.Textbox("ex)λ§λ²μ¬ μΈκ³, μ°μ£Ό μ μ", label="μ£Όμ ", info="μΈκ³μ μ£Όμ λ₯Ό μλ €μ£ΌμΈμ.", interactive=True)
world_story = gr.Textbox(label="μ€λͺ
", info="ꡬ체μ μΈ μΈκ³κ΄ μ€λͺ
κ³Ό λ£°μ μκ°νμΈμ", interactive=True)
world_create_btn = gr.Button("μΈκ³κ΄ μλ μμ±")
create_story_btn = gr.Button("μ€ν 리 μμ±", visible=False)
result = gr.Markdown("## μ€ν 리 μμ±μ΄ μλ£λμμ΅λλ€. μΊλ¦ν° μμ± νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
# @world_create_btn.click(inputs=[ topic, world_story ], outputs=[ game_topic, world_summary, create_story_btn ])
def click_world_create_btn(topic, world_story):
gr.Info("μΈκ³κ΄ μμ±μ€μ
λλ€...")
topic, summary = create_custom_world(topic, world_story)
gr.Info("μΈκ³κ΄ μμ± μλ£!")
return { game_topic: topic, world_summary: summary, create_story_btn: gr.Button(visible=True) }
world_create_btn.click(fn=click_world_create_btn, inputs=[ topic, world_story ], outputs=[ game_topic, world_summary, create_story_btn ])
# @create_story_btn.click(inputs=[ game_topic, world_summary ], outputs= [ stories, result ])
def click_create_story_btn(topic, summary):
gr.Info("μ€ν 리 μμ±μ€μ
λλ€...")
scenario = create_scenario(topic, summary, output_count=1, save=False)
_stories = create_storyline(topic, scenario[0], save=False)
gr.Info("μ€ν 리 μμ± μλ£!")
return { stories: _stories, result: gr.Markdown(visible=True) }
create_story_btn.click(fn=click_create_story_btn, inputs=[ game_topic, world_summary ], outputs= [ stories, result ])
elif theme == "Harry Potter":
create_story_btn = gr.Button("μ€ν 리 μμ±")
result = gr.Markdown("## μ€ν 리 μμ±μ΄ μλ£λμμ΅λλ€. μΊλ¦ν° μμ± νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
def click_create_story_btn():
gr.Info("μ€ν 리 μμ±μ€μ
λλ€...")
topic = "Harry Potter"
_world_summary = load_txt("harrypotter_scenario/world_summary.txt")
scenario = create_scenario(topic, _world_summary, output_count=1, save=False)
_stories = create_storyline(topic, scenario[0], save=False)
gr.Info("μ€ν 리 μμ± μλ£!")
return { game_topic: topic, world_summary: _world_summary, stories: _stories, result: gr.Markdown(visible=True) }
create_story_btn.click(fn=click_create_story_btn, outputs=[ game_topic, world_summary, stories, result ])
with gr.Tab("μΊλ¦ν° μμ±"):
@gr.render(inputs=[world_summary])
def on_game_topic(summary):
questions = generate_character_creation_questions(summary)
answers = []
for question_idx, question in enumerate(questions):
answer = gr.Textbox(key=question_idx, label=question, placeholder="λΉμ μ λλ΅μ μ
λ ₯νμΈμ.", interactive=True)
answers.append(answer)
char_create_btn = gr.Button("μΊλ¦ν° μμ±")
result = gr.Markdown("## μΊλ¦ν° μμ±μ΄ μλ£λμμ΅λλ€. κ²μ μ§ν νμΌλ‘ μ΄λν΄μ£ΌμΈμ.", visible=False)
def click_char_create_btn(*_answers):
gr.Info("μΊλ¦ν° μμ±μ€μ
λλ€...")
character_profile = parse_character_data_to_json(create_character_profile(questions, _answers))
profile_keys = [key for key in character_profile.keys()]
required_keys = ["name", "gender", "age", "race", "job", "background"]
params_keys = [key for key in character_profile["params"].keys()]
required_params_keys = ["stamina", "intelligence", "combat_power", "agility"]
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):
gr.Error("μΊλ¦ν° μμ±μ μ€ν¨νμ΅λλ€. νλͺ©λ€μ μμΈνκ² λΉ μ§μμ΄ κΈ°μ
ν΄μ£ΌμΈμ.")
return
gr.Info("μΊλ¦ν° μμ± μλ£!")
return { player_profile: character_profile, result: gr.Markdown(visible=True) }
char_create_btn.click(fn=click_char_create_btn, inputs=answers, outputs=[player_profile, result])
with gr.Tab("κ²μ νλ μ΄"):
round = gr.State(0)
player_restriction = gr.State()
player_capability = gr.State()
previous_conversation = gr.State("")
previous_round_result = gr.State("")
@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])
def on_round(_world_summary, _stories, _player_profile, _round, _player_restriction, _player_capability, _previous_conversation, _previous_round_result, _game_topic):
entire_story = [f"{idx+1}. {scenario['title']}\n{scenario['story']}\n\n" for idx, scenario in enumerate(_stories)]
player_profile_str = player_profile_to_str({ **_player_profile, 'params': _player_capability })
round_scenario = _stories[_round-1]
if _round == 0:
introduction = gr.Markdown(create_initial_conversation(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story))
game_start_btn = gr.Button("κ²μ μμ")
def click_game_start_btn():
return { round: 1, player_restriction: { "life": 20, "money": 20 }, player_capability: _player_profile["params"] }
game_start_btn.click(fn=click_game_start_btn, outputs=[round, player_restriction, player_capability])
else:
round_story = f"{_round}. {round_scenario['title']}: {round_scenario['story']}\n"
if _player_restriction["life"] <= 0 or _player_restriction["money"] <= 0:
gr.Markdown("## μμ½κ²λ κ²μ μ€λ²λμμ΅λλ€. λ€λ₯Έ μ νμ ν΅ν΄ μλ‘μ΄ μ΄μΌκΈ°μ κ²°λ§μ λ§λ€μ΄λ³΄μΈμ.")
bad_ending = create_bad_ending(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, round_story, _previous_conversation, _previous_round_result)
display_bad_ending = gr.Markdown(bad_ending)
restart_button = gr.Button("λ€μ μμνκΈ°")
def click_restart_button():
return { round: 0, player_restriction: {}, player_capability: {}, previous_conversation: "", previous_round_result: "" }
restart_button.click(fn=click_restart_button, outputs=[round, player_restriction, player_capability, previous_conversation, previous_round_result])
elif _round > len(_stories):
gr.Markdown("## μΆνν©λλ€! κ²μ ν΄λ¦¬μ΄μ μ±κ³΅νμ
¨μ΅λλ€")
good_ending = create_good_ending(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, _previous_conversation)
display_good_ending = gr.Markdown(good_ending)
restart_button = gr.Button("λ€μ μμνκΈ°")
def click_restart_button():
return { round: 0, player_restriction: {}, player_capability: {}, previous_conversation: "", previous_round_result: "" }
restart_button.click(fn=click_restart_button, outputs=[round, player_restriction, player_capability, previous_conversation, previous_round_result])
else:
round_description = create_round_description(_world_summary, player_profile_str, _player_restriction, _player_capability, entire_story, round_story, _previous_conversation, _previous_round_result)
gr.Markdown(f"## {_round}. {round_scenario['title']}")
with gr.Row():
gr.Markdown(round_description)
with gr.Column():
image_output = gr.Image(interactive=False, scale=5)
generate_image_btn = gr.Button("μ΄λ―Έμ§ μμ±")
def click_generate_image_btn():
gr.Info("μ΄λ―Έμ§ μμ±μ€μ
λλ€...")
image_generation_prompt = convert_to_image_prompt(_game_topic, _world_summary, _player_profile, round_description)
image_url = generate_image(image_generation_prompt)
gr.Info("μ΄λ―Έμ§ μμ± μλ£!")
return gr.Image(image_url)
generate_image_btn.click(fn=click_generate_image_btn, outputs=image_output)
with gr.Row():
player_response = gr.Textbox(label="λΉμ λ§μ κ²°μ μ λ΄λ €μ£ΌμΈμ!", info="νλμ λ¬Έμ₯μΌλ‘ λΉμ μ΄ ν νλκ³Ό κ·Έμ λν κ·Όκ±°μ μ΄μ λ₯Ό λͺ
ννκ² μ€λͺ
ν΄μ£ΌμΈμ", interactive=True, scale=10)
submit_btn = gr.Button("κ²°μ ", scale=1)
def click_submit_btn(_player_response, _previous_conversation, _player_restriction, _player_capability):
gr.Info("κ²°μ μ λ°μμ€μ
λλ€...")
__round = _round
_round_description = round_description
# Reflect the result and update player status
round_result = create_round_result(_world_summary, player_profile_str, _player_restriction, _player_capability, _round_description, _player_response)
round_effect = round_result["effect"]
round_result_explanation = round_result["reason"]
for key, value in round_effect["player_restriction"].items():
if _player_restriction.get(key) is not None:
modified_value = _player_restriction[key] + value
if modified_value > 10:
_player_restriction[key] = 10
elif modified_value < -10:
_player_restriction[key] = -10
else:
_player_restriction[key] = modified_value
for key, value in round_effect["player_capability"].items():
if _player_capability.get(key) is not None:
modified_value = _player_capability[key] + value
if modified_value > 100:
_player_capability[key] = 100
elif modified_value < -100:
_player_capability[key] = -100
else:
_player_capability[key] = modified_value
return {
round: __round+1,
previous_conversation: _previous_conversation + f"Game Master: {_round_description}\nPlayer: {_player_response}\n",
previous_round_result: to_round_result(round_effect, round_result_explanation),
player_restriction: _player_restriction,
player_capability: _player_capability,
}
submit_btn.click(
fn=click_submit_btn,
inputs=[ player_response, previous_conversation, player_restriction, player_capability ],
outputs=[round, previous_conversation, previous_round_result, player_restriction, player_capability]
)
player_name = re.sub(r'"', '', _player_profile['name'])
player_status_display = gr.Markdown(f"## {player_name}λμ μν")
with gr.Group():
with gr.Row():
gr.Textbox(_player_restriction['life'], interactive=False, label="λͺ©μ¨")
gr.Textbox(_player_restriction['money'], interactive=False, label="μμ§κΈ")
with gr.Row():
gr.Textbox(_player_capability["stamina"], interactive=False, label="μ€νλ―Έλ")
gr.Textbox(_player_capability["intelligence"], interactive=False, label="μ§λ₯")
gr.Textbox(_player_capability["combat_power"], interactive=False, label="μ ν¬λ ₯")
gr.Textbox(_player_capability["agility"], interactive=False, label="민첩μ±")
# # For Debugging
# game_topic_debugging = gr.Textbox(game_topic.value, label="game_topic_debugging")
# game_topic.change(lambda x: gr.Textbox(x), inputs=[game_topic], outputs=game_topic_debugging)
# world_summary_debugging=gr.Textbox(world_summary.value, label="world_summary_debugging")
# world_summary.change(lambda x: gr.Textbox(x), inputs=[world_summary], outputs=world_summary_debugging)
# stories_debugging=gr.Textbox(stories.value, label="stories_debugging")
# stories.change(lambda x: gr.Textbox(x), inputs=[stories], outputs=stories_debugging)
# player_profile_debugging=gr.Textbox(player_profile.value, label="player_profile_debugging")
# player_profile.change(lambda x: gr.Textbox(x), inputs=[player_profile], outputs=player_profile_debugging)
demo.launch(share=True)
if __name__ == "__main__":
main() |