Update app.py
Browse files
app.py
CHANGED
|
@@ -5,8 +5,8 @@ import random
|
|
| 5 |
|
| 6 |
# --- Streamlit 설정 ---
|
| 7 |
st.set_page_config(
|
| 8 |
-
page_title="
|
| 9 |
-
page_icon="
|
| 10 |
layout="wide",
|
| 11 |
initial_sidebar_state="expanded",
|
| 12 |
)
|
|
@@ -53,14 +53,14 @@ model = genai.GenerativeModel(
|
|
| 53 |
# --- 세션 상태 초기화 ---
|
| 54 |
if "sdgs_chat_session" not in st.session_state:
|
| 55 |
st.session_state["sdgs_chat_session"] = model.start_chat(history=[])
|
| 56 |
-
if "
|
| 57 |
-
st.session_state["
|
| 58 |
if "policy_options" not in st.session_state:
|
| 59 |
st.session_state["policy_options"] = None
|
| 60 |
if "policy_result" not in st.session_state:
|
| 61 |
st.session_state["policy_result"] = None
|
| 62 |
-
if "
|
| 63 |
-
st.session_state["
|
| 64 |
if "user_policy_option" not in st.session_state:
|
| 65 |
st.session_state["user_policy_option"] = ""
|
| 66 |
if "points" not in st.session_state:
|
|
@@ -69,45 +69,31 @@ if "level" not in st.session_state:
|
|
| 69 |
st.session_state["level"] = 1
|
| 70 |
|
| 71 |
|
| 72 |
-
# ---
|
| 73 |
-
|
| 74 |
-
"
|
| 75 |
-
"
|
| 76 |
-
"
|
| 77 |
-
"
|
| 78 |
-
"
|
| 79 |
-
"
|
| 80 |
-
"
|
| 81 |
-
"
|
| 82 |
-
"
|
| 83 |
-
"
|
| 84 |
-
"SDG 11": "지속가능한 도시와 공동체",
|
| 85 |
-
"SDG 12": "지속가능한 소비, 생산",
|
| 86 |
-
"SDG 13": "기후 변화 대응",
|
| 87 |
-
"SDG 14": "해양 생태계 보전",
|
| 88 |
-
"SDG 15": "육상 생태계 보전",
|
| 89 |
-
"SDG 16": "평화, 정의, 제도",
|
| 90 |
-
"SDG 17": "파트너십",
|
| 91 |
}
|
| 92 |
|
| 93 |
-
|
| 94 |
-
"
|
| 95 |
-
"
|
| 96 |
-
"
|
| 97 |
-
"
|
| 98 |
-
"
|
| 99 |
-
"
|
| 100 |
-
"
|
| 101 |
-
"
|
| 102 |
-
"
|
| 103 |
-
"
|
| 104 |
-
"SDG 11": "안전하고 회복력 있고 지속가능한 도시와 인간 거주지를 만드는 것",
|
| 105 |
-
"SDG 12": "지속가능한 소비와 생산 패턴을 확립하는 것",
|
| 106 |
-
"SDG 13": "기후 변화와 그 영향에 맞서 싸우기 위한 긴급 조치를 취하는 것",
|
| 107 |
-
"SDG 14": "지속가능한 발전을 위해 해양과 해양 자원을 보존하고 지속가능하게 사용하는 것",
|
| 108 |
-
"SDG 15": "육지 생태계를 보호하고 복원하며 지속가능하게 사용하고, 산림을 지속가능하게 경영���며, 사막화를 방지하고, 토지 황폐화를 중지시키고 되살리며, 생물 다양성 손실을 멈추게 하는 것",
|
| 109 |
-
"SDG 16": "지속가능한 발전을 위해 평화롭고 포용적인 사회를 증진하고, 모두에게 정의를 보장하며, 모든 수준에서 효과적이고 책임감 있고 포용적인 제도를 구축하는 것",
|
| 110 |
-
"SDG 17": "지속가능한 발전을 위한 이행 수단을 강화하고, 글로벌 파트너십을 활성화하는 것",
|
| 111 |
}
|
| 112 |
|
| 113 |
# --- 레벨업 기준 포인트 ---
|
|
@@ -126,8 +112,8 @@ base_points_per_action = {
|
|
| 126 |
}
|
| 127 |
|
| 128 |
# --- 정책 평가 키워드 ---
|
| 129 |
-
positive_keywords = ["성공", "개선", "향상", "긍정적", "효과적", "증진", "발전", "도움", "기여", "해결"]
|
| 130 |
-
negative_keywords = ["어려움", "문제", "악화", "부정적", "비효율적", "부족", "손실", "악영향", "한계", "실패"]
|
| 131 |
point_ranges = { # 정책 평가에 따른 포인트 범위
|
| 132 |
"positive": (10, 15),
|
| 133 |
"neutral": (5, 10),
|
|
@@ -147,11 +133,11 @@ def update_level():
|
|
| 147 |
|
| 148 |
|
| 149 |
# --- 시나리오 생성 함수 ---
|
| 150 |
-
def
|
| 151 |
prompt = f"""
|
| 152 |
지시:
|
| 153 |
-
초등학생 6학년 수준에 맞춰서, {
|
| 154 |
-
시나리오는 8~10문장 정도로 현실적인
|
| 155 |
"## 시나리오" 로 시작해주세요.
|
| 156 |
|
| 157 |
**생성된 시나리오:**
|
|
@@ -175,7 +161,7 @@ def generate_policy_options(scenario_text):
|
|
| 175 |
{scenario_text}
|
| 176 |
|
| 177 |
**지시:**
|
| 178 |
-
위 시나리오에 제시된
|
| 179 |
각 옵션은 2~3문장으로 간결하게 설명해주세요.
|
| 180 |
옵션은 번호와 함께 "옵션 [번호]: " 로 시작해주세요. (예: 옵션 1: , 옵션 2: ...)
|
| 181 |
|
|
@@ -211,7 +197,7 @@ def generate_policy_result(scenario_text, selected_option_text):
|
|
| 211 |
{selected_option_text}
|
| 212 |
|
| 213 |
**지시:**
|
| 214 |
-
위 시나리오
|
| 215 |
정책의 긍정적인 효과와 함께 예상되는 어려움이나 부작용도 **솔직하게** 함께 설명해주세요.
|
| 216 |
정책 결과가 긍정적인지, 중립적인지, 부정적인지 스스로 평가하여 함께 알려주세요. (예: 긍정적 결과, 중립적 결과, 부정적 결과)
|
| 217 |
"## 정책 결과" 로 시작하고, 그 다음에 정책 평가(긍정적 결과, 중립적 결과, 부정적 결과 중 하나)를 괄호 안에 넣어서 표시해주세요. (예: ## 정책 결과 (긍정적 결과))
|
|
@@ -255,35 +241,35 @@ def generate_policy_result(scenario_text, selected_option_text):
|
|
| 255 |
|
| 256 |
# --- 메인 화면 ---
|
| 257 |
def main():
|
| 258 |
-
st.sidebar.header("
|
| 259 |
st.sidebar.markdown(f"### 🏆 Level {st.session_state['level']}") # 레벨 표시
|
| 260 |
st.sidebar.markdown(f"### ⭐ 포인트: {st.session_state['points']}") # 포인트 표시
|
| 261 |
st.sidebar.markdown("---")
|
| 262 |
|
| 263 |
-
|
| 264 |
-
|
| 265 |
|
| 266 |
-
if st.session_state["
|
| 267 |
-
st.session_state["
|
| 268 |
st.session_state["policy_options"] = None
|
| 269 |
st.session_state["policy_result"] = None
|
| 270 |
-
st.session_state["
|
| 271 |
st.session_state["user_policy_option"] = "" # 사용자 입력 옵션 초기화
|
| 272 |
|
| 273 |
|
| 274 |
-
with st.sidebar.expander("📖
|
| 275 |
-
for
|
| 276 |
-
st.markdown(f"**{
|
| 277 |
-
st.write(
|
| 278 |
st.markdown("---")
|
| 279 |
|
| 280 |
with st.sidebar.expander("🚀 앱 사용 가이드"):
|
| 281 |
st.markdown(
|
| 282 |
"""
|
| 283 |
-
**
|
| 284 |
|
| 285 |
-
1. **
|
| 286 |
-
2. **시나리오 생성:** '시나리오 생성' 버튼을 클릭하여 선택한
|
| 287 |
3. **정책 옵션 생성:** 시나리오를 읽고 '정책 옵션 생성' 버튼을 클릭하여 AI가 제시하는 정책 옵션들을 확인하세요. (⭐ **기본 포인트 +3**)
|
| 288 |
4. **정책 옵션 선택 또는 직접 입력:**
|
| 289 |
* **AI 옵션 선택:** 제시된 옵션 중 하나를 선택하세요.
|
|
@@ -296,68 +282,68 @@ def main():
|
|
| 296 |
|
| 297 |
* 게임을 진행하면서 포인트를 얻��, 레벨을 올릴 수 있습니다.
|
| 298 |
* **정책 결과가 좋을수록 더 많은 포인트를 획득**하여 레벨을 빠르게 올릴 수 있습니다.
|
| 299 |
-
* 다양한
|
| 300 |
|
| 301 |
**팁:**
|
| 302 |
|
| 303 |
-
* 각
|
| 304 |
* 시나리오를 꼼꼼히 읽고, 문제의 원인과 영향을 파악하는 것이 중요합니다.
|
| 305 |
* 정책 옵션의 긍정적 효과와 예상되는 어려움을 고려하여 신중하게 선택하세요.
|
| 306 |
* **더 나은 정책을 선택하거나, 창의적인 정책 아이디어를 직접 입력**하여 높은 점수를 획득해보세요!
|
| 307 |
|
| 308 |
-
**재미있게
|
| 309 |
"""
|
| 310 |
)
|
| 311 |
|
| 312 |
|
| 313 |
-
st.title(f"
|
| 314 |
|
| 315 |
-
if not st.session_state["
|
| 316 |
if st.button("시나리오 생성", use_container_width=True):
|
| 317 |
-
with st.spinner(f"{
|
| 318 |
-
scenario =
|
| 319 |
-
st.session_state["
|
| 320 |
-
st.session_state["policy_options"] = None
|
| 321 |
-
st.session_state["policy_result"] = None
|
| 322 |
-
st.session_state["user_policy_option"] = ""
|
| 323 |
st.rerun() # rerun to display scenario immediately
|
| 324 |
else:
|
| 325 |
st.subheader("📜 시나리오")
|
| 326 |
-
st.info(st.session_state["
|
| 327 |
|
| 328 |
-
if st.session_state["
|
| 329 |
if st.button("정책 옵션 생성", use_container_width=True):
|
| 330 |
with st.spinner("정책 옵션 생성 중..."):
|
| 331 |
-
policy_options = generate_policy_options(st.session_state["
|
| 332 |
st.session_state["policy_options"] = policy_options
|
| 333 |
-
st.session_state["policy_result"] = None
|
| 334 |
-
st.session_state["user_policy_option"] = ""
|
| 335 |
st.rerun() # rerun to display options immediately
|
| 336 |
|
| 337 |
if st.session_state["policy_options"]:
|
| 338 |
st.subheader("⚙️ 정책 옵션 선택")
|
| 339 |
policy_option_keys = list(st.session_state["policy_options"].keys())
|
| 340 |
-
policy_option_keys_with_input = ["직접 입력"] + policy_option_keys
|
| 341 |
selected_option_key = st.radio("정책 옵션을 선택하세요:", policy_option_keys_with_input)
|
| 342 |
|
| 343 |
-
if selected_option_key == "직접 입력":
|
| 344 |
user_input_option = st.text_area("직접 정책 옵션 입력:", value=st.session_state["user_policy_option"])
|
| 345 |
-
st.session_state["user_policy_option"] = user_input_option
|
| 346 |
-
selected_option_text = user_input_option
|
| 347 |
else:
|
| 348 |
-
selected_option_text = st.session_state["policy_options"][selected_option_key]
|
| 349 |
-
st.info(f"**선택한 옵션 {selected_option_key}:** {selected_option_text}")
|
| 350 |
|
| 351 |
|
| 352 |
if st.button("정책 결정 실행", use_container_width=True):
|
| 353 |
with st.spinner("정책 결과 분석 중..."):
|
| 354 |
-
policy_result_text, policy_evaluation, points = generate_policy_result(st.session_state["
|
| 355 |
-
st.session_state["policy_result"] = (policy_result_text, policy_evaluation, points)
|
| 356 |
st.rerun() # rerun to display result immediately
|
| 357 |
|
| 358 |
|
| 359 |
if st.session_state["policy_result"]:
|
| 360 |
-
policy_result_text, policy_evaluation, points = st.session_state["policy_result"]
|
| 361 |
st.subheader("💡 정책 결과")
|
| 362 |
if policy_evaluation == "positive":
|
| 363 |
st.success(f"✅ {policy_result_text}")
|
|
@@ -365,15 +351,15 @@ def main():
|
|
| 365 |
st.warning(f"⚠️ {policy_result_text}")
|
| 366 |
else: # neutral
|
| 367 |
st.info(f"😐 {policy_result_text}")
|
| 368 |
-
st.markdown(f"획득 포인트: ⭐ **{points}** points ({policy_evaluation} 정책)")
|
| 369 |
|
| 370 |
if st.button("새로운 시나리오로 다시하기", use_container_width=True):
|
| 371 |
-
st.session_state["
|
| 372 |
st.session_state["policy_options"] = None
|
| 373 |
st.session_state["policy_result"] = None
|
| 374 |
-
st.session_state["user_policy_option"] = ""
|
| 375 |
-
st.session_state["points"] += base_points_per_action["retry"]
|
| 376 |
-
update_level()
|
| 377 |
st.rerun()
|
| 378 |
|
| 379 |
|
|
|
|
| 5 |
|
| 6 |
# --- Streamlit 설정 ---
|
| 7 |
st.set_page_config(
|
| 8 |
+
page_title="국제 무역 분쟁 게임",
|
| 9 |
+
page_icon="⚖️",
|
| 10 |
layout="wide",
|
| 11 |
initial_sidebar_state="expanded",
|
| 12 |
)
|
|
|
|
| 53 |
# --- 세션 상태 초기화 ---
|
| 54 |
if "sdgs_chat_session" not in st.session_state:
|
| 55 |
st.session_state["sdgs_chat_session"] = model.start_chat(history=[])
|
| 56 |
+
if "current_trade_dispute_scenario" not in st.session_state:
|
| 57 |
+
st.session_state["current_trade_dispute_scenario"] = None
|
| 58 |
if "policy_options" not in st.session_state:
|
| 59 |
st.session_state["policy_options"] = None
|
| 60 |
if "policy_result" not in st.session_state:
|
| 61 |
st.session_state["policy_result"] = None
|
| 62 |
+
if "selected_trade_dispute_type" not in st.session_state:
|
| 63 |
+
st.session_state["selected_trade_dispute_type"] = None
|
| 64 |
if "user_policy_option" not in st.session_state:
|
| 65 |
st.session_state["user_policy_option"] = ""
|
| 66 |
if "points" not in st.session_state:
|
|
|
|
| 69 |
st.session_state["level"] = 1
|
| 70 |
|
| 71 |
|
| 72 |
+
# --- 국제 무역 분쟁 유형 목록 및 설명 ---
|
| 73 |
+
trade_dispute_types = {
|
| 74 |
+
"무역 전쟁": "주요 국가 간의 광범위하고 심각한 무역 제한 조치 (관세, 비관세 장벽 등) ",
|
| 75 |
+
"관세 분쟁": "특정 품목 또는 국가에 대한 관세 인상 또는 새로운 관세 부과로 인한 분쟁",
|
| 76 |
+
"보조금 분쟁": "특정 산업에 대한 정부 보조금 지급으로 인해 경쟁국 산업에 피해가 발생하여 일어나는 분쟁",
|
| 77 |
+
"지적재산권 분쟁": "특허권, 상표권, 저작권 등 지적재산권 침해로 인한 분쟁",
|
| 78 |
+
"기술 표준 분쟁": "서로 다른 기술 표준을 요구하여 무역 장벽으로 작용하는 분쟁",
|
| 79 |
+
"농산물 분쟁": "농산물 수입 제한, 검역 조치 등으로 인해 발생하는 분쟁",
|
| 80 |
+
"환율 분쟁": "인위적인 환율 조작 (평가 절하 등) 으로 인해 무역 불균형이 심화되어 발생하는 분쟁",
|
| 81 |
+
"통상 압력": "특정 국가가 무역 협상 또는 분쟁 해결 과정에서 정치적, 경제적 영향력을 이용하여 자국에 유리한 조건을 강요하는 상황",
|
| 82 |
+
"수출 통제 분쟁": "특정 품목 (특히 전략 물자) 에 대한 수출 통제 조치로 인해 관련국과 갈등이 발생하는 분쟁",
|
| 83 |
+
"FTA 분쟁": "자유무역협정 (FTA) 의 해석 또는 이행 과정에서 발생하는 분쟁",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
}
|
| 85 |
|
| 86 |
+
trade_dispute_descriptions = {
|
| 87 |
+
"무역 전쟁": "주로 두 개 이상의 국가가 서로에게 높은 관세를 부과하고, 수입을 제한하는 등 극단적인 무역 제한 조치를 반복하면서 발생하는 분쟁입니다. 이는 글로벌 경제에 심각한 타격을 줄 수 있습니다.",
|
| 88 |
+
"관세 분쟁": "특정 국가가 수입품에 대해 관세를 갑자기 인상하거나 새로운 관세를 부과하여, 수출국의 반발을 사거나 국제 무역 규범에 위배될 소지가 있을 때 발생합니다. 흔히 특정 산업 보호 또는 무역 불균형 해소를 목적으로 합니다.",
|
| 89 |
+
"보조금 분쟁": "한 국가의 정부가 자국 특정 산업에 보조금을 지급하여 가격 경쟁력을 높이는 경우, 경쟁 관계에 있는 다른 국가의 산업이 피해를 보게 되면서 발생합니다. WTO 보조금 협정 위반 여부가 쟁점이 되기도 합니다.",
|
| 90 |
+
"지적재산권 분쟁": "한 국가에서 다른 국가의 기업이나 개인의 특허, 상표, 저작권 등의 지적재산권을 침해하는 경우 발생합니다. 기술 탈취, 짝퉁 상품 제조 및 판매 등이 주요 원인이 됩니다.",
|
| 91 |
+
"기술 표준 분쟁": "각 국가마다 다른 기술 표준을 적용하면서, 특정 국가의 기술이나 제품이 다른 국가 시장에 진입하는 데 어려움을 겪게 되는 경우입니다. 자국 산업 보호 또는 기술 주도권 확보를 위한 수단으로 이용되기도 합니다.",
|
| 92 |
+
"농산물 분쟁": "농산물은 각 국가의 식량 안보와 관련되어 민감한 품목입니다. 자국 농업 보호를 위해 수입을 제한하거나 높은 관세를 부과하는 경우, 수출국과 분쟁이 발생할 수 있습니다. SPS (위생 및 식물위생 조치) 관련 분쟁도 많습니다.",
|
| 93 |
+
"환율 분쟁": "한 국가가 수출 경쟁력을 높이기 위해 인위적으로 자국 통화 환율을 낮추는(평가 절하) 경우, 다른 국가로부터 불공정 무역 행위라는 비판을 받으며 분쟁이 발생할 수 있습니다.",
|
| 94 |
+
"통상 압력": "경제 강대국이 무역 협상이나 분쟁 해결 과정에서 정치적 영향력이나 경제 제재 등을 이용하여 상대국에게 불리한 합의를 강요하는 상황을 의미합니다. 국제 관계의 불평등성을 보여주는 사례입니다.",
|
| 95 |
+
"수출 통제 분쟁": "안보, 테러 방지, 또는 특정 목적 (예: 기술 패권 경쟁) 을 위해 특정 품목의 수출을 제한하는 경우, 수입국 또는 관련 기업들의 반발을 사며 분쟁이 발생할 수 있습니다. 반도체, 군사 장비 등이 주요 품목입니다.",
|
| 96 |
+
"FTA 분쟁": "자유무역협정(FTA) 체결 후 협정 내용의 해석 차이, 또는 협정 이행 과정에서의 문제 발생으로 인해 협정 당사국 간에 분쟁이 발생할 수 있습니다. FTA 조항의 모호성 또는 이견이 원인이 됩니다.",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
}
|
| 98 |
|
| 99 |
# --- 레벨업 기준 포인트 ---
|
|
|
|
| 112 |
}
|
| 113 |
|
| 114 |
# --- 정책 평가 키워드 ---
|
| 115 |
+
positive_keywords = ["성공", "개선", "향상", "긍정적", "효과적", "증진", "발전", "도움", "기여", "해결", "무역 관계 개선", "협상 성공", "분쟁 완화"]
|
| 116 |
+
negative_keywords = ["어려움", "문제", "악화", "부정적", "비효율적", "부족", "손실", "악영향", "한계", "실패", "무역 전쟁 심화", "관계 악화", "경제적 손실"]
|
| 117 |
point_ranges = { # 정책 평가에 따른 포인트 범위
|
| 118 |
"positive": (10, 15),
|
| 119 |
"neutral": (5, 10),
|
|
|
|
| 133 |
|
| 134 |
|
| 135 |
# --- 시나리오 생성 함수 ---
|
| 136 |
+
def generate_trade_dispute_scenario(dispute_type_name, dispute_type_text):
|
| 137 |
prompt = f"""
|
| 138 |
지시:
|
| 139 |
+
초등학생 6학년 수준에 맞춰서, **{dispute_type_text}({dispute_type_name})** 유형의 국제 무역 분쟁 시뮬레이션 시나리오를 생성해주세���.
|
| 140 |
+
시나리오는 8~10문장 정도로 현실적인 국제 무역 분쟁 상황을 설명하고, 학생들이 **무역 분쟁과 정책 결정의 필요성**을 느낄 수 있도록 작성해주세요.
|
| 141 |
"## 시나리오" 로 시작해주세요.
|
| 142 |
|
| 143 |
**생성된 시나리오:**
|
|
|
|
| 161 |
{scenario_text}
|
| 162 |
|
| 163 |
**지시:**
|
| 164 |
+
위 시나리오에 제시된 **국제 무역 분쟁 문제**를 해결하거나 완화하기 위한 정책 옵션 3가지 정도를 초등학생 6학년 수준에 맞춰서 생성해주세요.
|
| 165 |
각 옵션은 2~3문장으로 간결하게 설명해주세요.
|
| 166 |
옵션은 번호와 함께 "옵션 [번호]: " 로 시작해주세요. (예: 옵션 1: , 옵션 2: ...)
|
| 167 |
|
|
|
|
| 197 |
{selected_option_text}
|
| 198 |
|
| 199 |
**지시:**
|
| 200 |
+
위 시나리오의 **국제 무역 분쟁 상황**에서 선택한 정책 옵션을 실행했을 때 예상되는 결과를 초등학생 6학년 수준에 맞춰서 6~8문장 정도로 설명해주세요.
|
| 201 |
정책의 긍정적인 효과와 함께 예상되는 어려움이나 부작용도 **솔직하게** 함께 설명해주세요.
|
| 202 |
정책 결과가 긍정적인지, 중립적인지, 부정적인지 스스로 평가하여 함께 알려주세요. (예: 긍정적 결과, 중립적 결과, 부정적 결과)
|
| 203 |
"## 정책 결과" 로 시작하고, 그 다음에 정책 평가(긍정적 결과, 중립적 결과, 부정적 결과 중 하나)를 괄호 안에 넣어서 표시해주세요. (예: ## 정책 결과 (긍정적 결과))
|
|
|
|
| 241 |
|
| 242 |
# --- 메인 화면 ---
|
| 243 |
def main():
|
| 244 |
+
st.sidebar.header("⚖️ 국제 무역 분쟁 게임")
|
| 245 |
st.sidebar.markdown(f"### 🏆 Level {st.session_state['level']}") # 레벨 표시
|
| 246 |
st.sidebar.markdown(f"### ⭐ 포인트: {st.session_state['points']}") # 포인트 표시
|
| 247 |
st.sidebar.markdown("---")
|
| 248 |
|
| 249 |
+
selected_dispute_type_name = st.sidebar.selectbox("무역 분쟁 유형 선택:", list(trade_dispute_types.keys()))
|
| 250 |
+
dispute_type_text = trade_dispute_types[selected_dispute_type_name]
|
| 251 |
|
| 252 |
+
if st.session_state["selected_trade_dispute_type"] != selected_dispute_type_name:
|
| 253 |
+
st.session_state["current_trade_dispute_scenario"] = None
|
| 254 |
st.session_state["policy_options"] = None
|
| 255 |
st.session_state["policy_result"] = None
|
| 256 |
+
st.session_state["selected_trade_dispute_type"] = selected_dispute_type_name
|
| 257 |
st.session_state["user_policy_option"] = "" # 사용자 입력 옵션 초기화
|
| 258 |
|
| 259 |
|
| 260 |
+
with st.sidebar.expander("📖 무역 분쟁 유형 설명"):
|
| 261 |
+
for dispute_name, dispute_text in trade_dispute_types.items():
|
| 262 |
+
st.markdown(f"**{dispute_name}: {dispute_text}**")
|
| 263 |
+
st.write(trade_dispute_descriptions[dispute_name])
|
| 264 |
st.markdown("---")
|
| 265 |
|
| 266 |
with st.sidebar.expander("🚀 앱 사용 가이드"):
|
| 267 |
st.markdown(
|
| 268 |
"""
|
| 269 |
+
**국제 무역 분쟁 게임 방법**
|
| 270 |
|
| 271 |
+
1. **무역 분쟁 유형 선택:** 왼쪽 사이드바에서 **무역 분쟁 유형**을 선택하세요.
|
| 272 |
+
2. **시나리오 생성:** '시나리오 생성' 버튼을 클릭하여 선택한 유형과 관련된 분쟁 상황 시나리오를 받아보세요. (⭐ **기본 포인트 +5**)
|
| 273 |
3. **정책 옵션 생성:** 시나리오를 읽고 '정책 옵션 생성' 버튼을 클릭하여 AI가 제시하는 정책 옵션들을 확인하세요. (⭐ **기본 포인트 +3**)
|
| 274 |
4. **정책 옵션 선택 또는 직접 입력:**
|
| 275 |
* **AI 옵션 선택:** 제시된 옵션 중 하나를 선택하세요.
|
|
|
|
| 282 |
|
| 283 |
* 게임을 진행하면서 포인트를 얻��, 레벨을 올릴 수 있습니다.
|
| 284 |
* **정책 결과가 좋을수록 더 많은 포인트를 획득**하여 레벨을 빠르게 올릴 수 있습니다.
|
| 285 |
+
* 다양한 **무역 분쟁 유형**에 도전하고, 좋은 정책 결정을 많이 내려서 높은 레벨에 도전해보세요!
|
| 286 |
|
| 287 |
**팁:**
|
| 288 |
|
| 289 |
+
* 각 **무역 분쟁 유형**이 무엇을 의미하는지 '무역 분쟁 유형 설명'을 참고하세요.
|
| 290 |
* 시나리오를 꼼꼼히 읽고, 문제의 원인과 영향을 파악하는 것이 중요합니다.
|
| 291 |
* 정책 옵션의 긍정적 효과와 예상되는 어려움을 고려하여 신중하게 선택하세요.
|
| 292 |
* **더 나은 정책을 선택하거나, 창의적인 정책 아이디어를 직접 입력**하여 높은 점수를 획득해보세요!
|
| 293 |
|
| 294 |
+
**재미있게 국제 무역 분쟁 게임을 즐기면서 국제 경제 및 외교 문제 해결 능력을 키워보세요!**
|
| 295 |
"""
|
| 296 |
)
|
| 297 |
|
| 298 |
|
| 299 |
+
st.title(f"⚖️ {selected_dispute_type_name} 시뮬레이션")
|
| 300 |
|
| 301 |
+
if not st.session_state["current_trade_dispute_scenario"]:
|
| 302 |
if st.button("시나리오 생성", use_container_width=True):
|
| 303 |
+
with st.spinner(f"{selected_dispute_type_name} 시나리오 생성 중..."):
|
| 304 |
+
scenario = generate_trade_dispute_scenario(selected_dispute_type_name, dispute_type_text)
|
| 305 |
+
st.session_state["current_trade_dispute_scenario"] = scenario
|
| 306 |
+
st.session_state["policy_options"] = None
|
| 307 |
+
st.session_state["policy_result"] = None
|
| 308 |
+
st.session_state["user_policy_option"] = ""
|
| 309 |
st.rerun() # rerun to display scenario immediately
|
| 310 |
else:
|
| 311 |
st.subheader("📜 시나리오")
|
| 312 |
+
st.info(st.session_state["current_trade_dispute_scenario"])
|
| 313 |
|
| 314 |
+
if st.session_state["current_trade_dispute_scenario"] and not st.session_state["policy_options"]:
|
| 315 |
if st.button("정책 옵션 생성", use_container_width=True):
|
| 316 |
with st.spinner("정책 옵션 생성 중..."):
|
| 317 |
+
policy_options = generate_policy_options(st.session_state["current_trade_dispute_scenario"])
|
| 318 |
st.session_state["policy_options"] = policy_options
|
| 319 |
+
st.session_state["policy_result"] = None
|
| 320 |
+
st.session_state["user_policy_option"] = ""
|
| 321 |
st.rerun() # rerun to display options immediately
|
| 322 |
|
| 323 |
if st.session_state["policy_options"]:
|
| 324 |
st.subheader("⚙️ 정책 옵션 선택")
|
| 325 |
policy_option_keys = list(st.session_state["policy_options"].keys())
|
| 326 |
+
policy_option_keys_with_input = ["직접 입력"] + policy_option_keys
|
| 327 |
selected_option_key = st.radio("정책 옵션을 선택하세요:", policy_option_keys_with_input)
|
| 328 |
|
| 329 |
+
if selected_option_key == "직접 입력":
|
| 330 |
user_input_option = st.text_area("직접 정책 옵션 입력:", value=st.session_state["user_policy_option"])
|
| 331 |
+
st.session_state["user_policy_option"] = user_input_option
|
| 332 |
+
selected_option_text = user_input_option
|
| 333 |
else:
|
| 334 |
+
selected_option_text = st.session_state["policy_options"][selected_option_key]
|
| 335 |
+
st.info(f"**선택한 옵션 {selected_option_key}:** {selected_option_text}")
|
| 336 |
|
| 337 |
|
| 338 |
if st.button("정책 결정 실행", use_container_width=True):
|
| 339 |
with st.spinner("정책 결과 분석 중..."):
|
| 340 |
+
policy_result_text, policy_evaluation, points = generate_policy_result(st.session_state["current_trade_dispute_scenario"], selected_option_text)
|
| 341 |
+
st.session_state["policy_result"] = (policy_result_text, policy_evaluation, points)
|
| 342 |
st.rerun() # rerun to display result immediately
|
| 343 |
|
| 344 |
|
| 345 |
if st.session_state["policy_result"]:
|
| 346 |
+
policy_result_text, policy_evaluation, points = st.session_state["policy_result"]
|
| 347 |
st.subheader("💡 정책 결과")
|
| 348 |
if policy_evaluation == "positive":
|
| 349 |
st.success(f"✅ {policy_result_text}")
|
|
|
|
| 351 |
st.warning(f"⚠️ {policy_result_text}")
|
| 352 |
else: # neutral
|
| 353 |
st.info(f"😐 {policy_result_text}")
|
| 354 |
+
st.markdown(f"획득 포인트: ⭐ **{points}** points ({policy_evaluation} 정책)")
|
| 355 |
|
| 356 |
if st.button("새로운 시나리오로 다시하기", use_container_width=True):
|
| 357 |
+
st.session_state["current_trade_dispute_scenario"] = None
|
| 358 |
st.session_state["policy_options"] = None
|
| 359 |
st.session_state["policy_result"] = None
|
| 360 |
+
st.session_state["user_policy_option"] = ""
|
| 361 |
+
st.session_state["points"] += base_points_per_action["retry"]
|
| 362 |
+
update_level()
|
| 363 |
st.rerun()
|
| 364 |
|
| 365 |
|