Spaces:
Sleeping
Sleeping
import streamlit as st | |
from src.modules.character_creation import display_character_creation_page | |
from src.modules.game_play import game_play_page | |
from src.modules.world_description import world_description_page | |
from src.utils.theme_manager import setup_responsive_layout | |
from src.config.constants import INITIAL_MASTER_MESSAGE | |
from src.config.styles import apply_custom_styles | |
def initialize_session_state(): | |
"""세션 상태 초기화 함수""" | |
if 'initialized' not in st.session_state: | |
st.session_state.stage = 'theme_selection' | |
st.session_state.world_description = "" | |
st.session_state.character = { | |
'profession': '', | |
'stats': {'STR': 0, 'INT': 0, 'DEX': 0, 'CON': 0, 'WIS': 0, 'CHA': 0}, | |
'backstory': '', | |
'inventory': ['기본 의류', '작은 주머니 (5 골드)'] | |
} | |
st.session_state.story_log = [] | |
st.session_state.current_location = "" | |
st.session_state.use_backup_mode = False | |
st.session_state.world_generated = False | |
st.session_state.world_accepted = False | |
st.session_state.question_answers = [] | |
st.session_state.question_count = 0 | |
st.session_state.question_submitted = False | |
st.session_state.question_answered = False | |
st.session_state.question_current = "" | |
st.session_state.answer_current = "" | |
st.session_state.background_options_generated = False | |
st.session_state.character_backgrounds = [] | |
st.session_state.dice_rolled = False | |
st.session_state.dice_result = 0 | |
st.session_state.dice_rolling_animation = False | |
st.session_state.action_submitted = False | |
st.session_state.action_processed = False | |
st.session_state.current_action = "" | |
st.session_state.action_response = "" | |
st.session_state.ability_check_done = False | |
st.session_state.suggestions_generated = False | |
st.session_state.action_suggestions = [] | |
st.session_state.master_question_submitted = False | |
st.session_state.master_question_answered = False | |
st.session_state.master_question = "" | |
st.session_state.master_answer = "" | |
st.session_state.move_submitted = False | |
st.session_state.move_processed = False | |
st.session_state.move_destination = "" | |
st.session_state.move_response = "" | |
st.session_state.available_locations = [] | |
st.session_state.action_phase = 'suggestions' | |
st.session_state.continuation_mode = False | |
st.session_state.continuation_text = "" | |
st.session_state.item_notification = "" | |
st.session_state.show_item_notification = False | |
st.session_state.world_questions = [] | |
st.session_state.world_question_count = 0 | |
st.session_state.active_section = None | |
st.session_state.master_message = INITIAL_MASTER_MESSAGE | |
st.session_state.initialized = True | |
def reset_game_session(): | |
"""게임 세션을 완전히 초기화하고 첫 화면으로 돌아가는 함수""" | |
all_keys = list(st.session_state.keys()) | |
for key in all_keys: | |
if key != 'initialized': | |
if key in st.session_state: | |
del st.session_state[key] | |
st.session_state.stage = 'theme_selection' | |
st.session_state.master_message = INITIAL_MASTER_MESSAGE | |
def theme_selection_page(): | |
"""테마 선택 페이지""" | |
from src.utils.theme_manager import create_theme_image, get_theme_description | |
from src.modules.world_generator import generate_world_description | |
from src.utils.location_manager import generate_locations | |
st.title("유니버스 원: 세상에서 하나뿐인 TRPG") | |
st.markdown(""" | |
<div style='background-color: #2a3549; padding: 15px; border-radius: 5px; margin-bottom: 20px;'> | |
<p>🌟 <strong>유니버스 원</strong>은 AI가 만들어내는 유일무이한 세계와 이야기를 경험하는 TRPG 플랫폼입니다.</p> | |
<p>🎲 당신이 내리는 모든 선택과 행동이 세계를 형성하고, 이야기를 만들어갑니다.</p> | |
<p>✨ 누구도 똑같은 이야기를 경험할 수 없습니다. 오직 당신만의 단 하나뿐인 모험이 시작됩니다.</p> | |
</div> | |
""", unsafe_allow_html=True) | |
st.header("1️⃣ 세계관 선택") | |
# 마스터 메시지 표시 | |
st.markdown(f"<div class='master-text'>{st.session_state.master_message}</div>", unsafe_allow_html=True) | |
# 테마 설명 추가 | |
st.markdown(""" | |
<div style='background-color: #1e2636; padding: 15px; border-radius: 5px; margin-bottom: 20px;'> | |
<p>모험을 시작할 세계의 테마를 선택하세요. 각 테마는 독특한 분위기와 가능성을 제공합니다.</p> | |
</div> | |
""", unsafe_allow_html=True) | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
st.markdown("<div class='theme-card'>", unsafe_allow_html=True) | |
st.markdown(create_theme_image("fantasy"), unsafe_allow_html=True) | |
st.markdown(get_theme_description("fantasy"), unsafe_allow_html=True) | |
if st.button("판타지", key="fantasy"): | |
with st.spinner("AI 마스터가 세계를 생성 중입니다..."): | |
loading_placeholder = st.empty() | |
loading_placeholder.info("판타지 세계를 생성하는 중... 잠시만 기다려주세요.") | |
st.session_state.theme = "fantasy" | |
st.session_state.world_description = generate_world_description("fantasy") | |
st.session_state.current_location = "왕국의 수도" | |
st.session_state.available_locations = generate_locations("fantasy") | |
st.session_state.master_message = "판타지 세계에 오신 것을 환영합니다! 아래 세계 설명을 읽어보시고, 질문이 있으시면 언제든지 물어보세요." | |
st.session_state.world_generated = True | |
st.session_state.stage = 'world_description' | |
loading_placeholder.empty() | |
st.rerun() | |
st.markdown("</div>", unsafe_allow_html=True) | |
with col2: | |
st.markdown("<div class='theme-card'>", unsafe_allow_html=True) | |
st.markdown(create_theme_image("sci-fi"), unsafe_allow_html=True) | |
st.markdown(get_theme_description("sci-fi"), unsafe_allow_html=True) | |
if st.button("SF", key="scifi"): | |
with st.spinner("AI 마스터가 세계를 생성 중입니다..."): | |
loading_placeholder = st.empty() | |
loading_placeholder.info("SF 세계를 생성하는 중... 잠시만 기다려주세요.") | |
st.session_state.theme = "sci-fi" | |
st.session_state.world_description = generate_world_description("sci-fi") | |
st.session_state.current_location = "중앙 우주 정거장" | |
st.session_state.available_locations = generate_locations("sci-fi") | |
st.session_state.master_message = "SF 세계에 오신 것을 환영합니다! 아래 세계 설명을 읽어보시고, 질문이 있으시면 언제든지 물어보세요." | |
st.session_state.world_generated = True | |
st.session_state.stage = 'world_description' | |
loading_placeholder.empty() | |
st.rerun() | |
st.markdown("</div>", unsafe_allow_html=True) | |
with col3: | |
st.markdown("<div class='theme-card'>", unsafe_allow_html=True) | |
st.markdown(create_theme_image("dystopia"), unsafe_allow_html=True) | |
st.markdown(get_theme_description("dystopia"), unsafe_allow_html=True) | |
if st.button("디스토피아", key="dystopia"): | |
with st.spinner("AI 마스터가 세계를 생성 중입니다..."): | |
loading_placeholder = st.empty() | |
loading_placeholder.info("디스토피아 세계를 생성하는 중... 잠시만 기다려주세요.") | |
st.session_state.theme = "dystopia" | |
st.session_state.world_description = generate_world_description("dystopia") | |
st.session_state.current_location = "지하 피난처" | |
st.session_state.available_locations = generate_locations("dystopia") | |
st.session_state.master_message = "디스토피아 세계에 오신 것을 환영합니다! 아래 세계 설명을 읽어보시고, 질문이 있으시면 언제든지 물어보세요." | |
st.session_state.world_generated = True | |
st.session_state.stage = 'world_description' | |
loading_placeholder.empty() | |
st.rerun() | |
st.markdown("</div>", unsafe_allow_html=True) | |
def main(): | |
"""메인 애플리케이션 함수""" | |
# 스트림릿 페이지 설정 | |
st.set_page_config( | |
page_title="TRPG 주사위 기반 스토리텔링", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
# 커스텀 CSS 적용 | |
apply_custom_styles() | |
# 세션 상태 초기화 | |
initialize_session_state() | |
# 반응형 레이아웃 설정 | |
setup_responsive_layout() | |
# 현재 단계에 따라 다른 페이지 표시 | |
if st.session_state.stage == 'theme_selection': | |
theme_selection_page() | |
elif st.session_state.stage == 'world_description': | |
world_description_page() | |
elif st.session_state.stage == 'character_creation': | |
display_character_creation_page() | |
elif st.session_state.stage == 'game_play': | |
game_play_page() | |
if __name__ == "__main__": | |
main() |