zenityx commited on
Commit
e7c2a53
·
verified ·
1 Parent(s): 6adc7e6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +284 -146
app.py CHANGED
@@ -1,133 +1,196 @@
 
1
  import gradio as gr
2
- import random
3
-
4
- # ==== เพิ่ม: โหลดโมเดล MarianMT และ Tokenizer สำหรับแปลไทย->อังกฤษ ====
5
  from transformers import MarianMTModel, MarianTokenizer
 
6
 
 
 
 
7
  model_name = "Helsinki-NLP/opus-mt-th-en"
8
  tokenizer = MarianTokenizer.from_pretrained(model_name)
9
  model = MarianMTModel.from_pretrained(model_name)
10
 
11
- def translate_th_to_en(th_text: str) -> str:
12
- """
13
- ใช้โมเดล MarianMT แปลภาษาไทย -> อังกฤษ
14
- รันบน CPU (Hugging Face Spaces) ได้โดยไม่ต้องใช้ GPU
15
- """
16
- th_text = th_text.strip()
17
- if not th_text:
18
  return ""
19
- inputs = tokenizer(th_text, return_tensors="pt", max_length=512, truncation=True)
20
  translation_tokens = model.generate(**inputs, max_length=512)
21
  en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
22
  return en_text
23
 
24
-
25
  ##############################################
26
- # ฟังก์ชันคำนวณ: อุณหภูมิ & แรงโน้มถ่วง
27
  ##############################################
28
- def approximate_temperature(planet_type, distance_au):
29
- if planet_type == "ดาวหิน (Rocky Planet)":
30
- base_temp = 15
31
- elif planet_type == "ดาวก๊าซ (Gas Giant)":
32
- base_temp = 30
33
- elif planet_type == "ดาวน้ำแข็ง (Icy Planet)":
34
- base_temp = -50
35
- else:
36
- base_temp = 0
37
 
38
- if distance_au > 1.0:
39
- diff = (distance_au - 1.0) * 20
40
- approx_temp = base_temp - diff
41
- else:
42
- diff = (1.0 - distance_au) * 30
43
- approx_temp = base_temp + diff
44
-
45
- return round(approx_temp)
46
-
47
- def approximate_gravity(diameter_earth):
48
- return round(diameter_earth, 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
 
51
  ##############################################
52
- # สรุปข้อมูล (ภาษาไทย) สำหรับเด็ก
53
  ##############################################
54
- def child_friendly_summary(
55
- name_th, planet_type_th, temp_c, gravity_g, oxygen_percent, life_th
56
- ):
57
- if temp_c > 40:
58
- temp_comment = "ร้อนจัดเลย!"
59
- elif temp_c < -10:
60
- temp_comment = "หนาวสุดขั้ว!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  else:
62
- temp_comment = "อากาศกำลังดีเลย!"
63
 
64
- if gravity_g > 1.5:
65
- gravity_comment = f"แรงโน้มถ่วงประมาณ {gravity_g}g อาจเดินลำบากนะ!"
66
- elif gravity_g < 0.5:
67
- gravity_comment = f"แรงโน้มถ่วงแค่ {gravity_g}g ระวังลอยได้!"
 
 
 
 
 
 
68
  else:
69
- gravity_comment = f"แรงโน้มถ่วง ~{gravity_g}g กำลังโอเค"
70
 
71
- o2_comment = f"ออกซิเจน {oxygen_percent}%"
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- summary_th = (
74
- f"ดาว {name_th} เป็น{planet_type_th}\n"
75
- f"อุณหภูมิราว {temp_c}°C ({temp_comment})\n"
76
- f"{gravity_comment}\n"
77
- f"บรรยากาศมี {o2_comment}\n"
78
- f"มีสิ่งมีชีวิต: {life_th}\n"
79
- f"ว้าว! น่าสนใจมาก!"
80
- )
81
- return summary_th
 
 
82
 
83
 
84
  ##############################################
85
- # ฟังก์ชันสร้าง 3 Prompts (ภาษาอังกฤษ)
86
  ##############################################
87
- def generate_three_prompts_en(
88
- planet_name_en, planet_type_en, distance_au, diameter_factor,
89
- temp_c, gravity_g, oxygen_percent, life_en
90
- ):
91
- base_info = (
92
- f"Planet {planet_name_en}, {planet_type_en}, at ~{distance_au} AU from its star, "
93
- f"diameter ~{diameter_factor}x Earth, surface temp ~{temp_c}C, gravity ~{gravity_g}g, "
94
- f"oxygen ~{oxygen_percent}%. "
95
- )
96
 
97
  # Prompt 1: ภาพดาวจากอวกาศ
98
  prompt1 = (
99
- f"{base_info}A breathtaking orbital view of this planet showing its vibrant atmosphere, "
100
- f"highly detailed, cinematic lighting, wide shot --ar 16:9"
 
101
  )
102
 
103
  # Prompt 2: สิ่งมีชีวิต
104
  prompt2 = (
105
- f"{base_info}Alien life form on the planet: {life_en}, "
106
- f"illustration focusing on creature design, environment details, "
107
- f"fantasy concept art, photorealistic --ar 9:16"
108
  )
109
 
110
  # Prompt 3: พื้นผิวดาว
111
  prompt3 = (
112
- f"{base_info}Planetary surface landscape, unique terrain and color palette, "
113
- f"epic environment shot, detailed textures, natural light, hyperrealistic --ar 16:9"
 
114
  )
115
 
116
- return prompt1, prompt2, prompt3
 
 
 
 
 
117
 
118
 
119
  ##############################################
120
- # ฟังก์ชันหลัก (รับ input ไทย -> สร้างผลลัพธ์)
121
  ##############################################
122
  def generate_planet_info(
123
- planet_name_th, # ชื่อดาว (ไทย)
124
- planet_type_th, # ชนิดดาว (ไทย)
125
- distance_str, # ระยะห่าง (string)
126
- diameter_str, # ขนาด (string)
127
- oxygen_percent, # slider (int)
128
- life_th # สิ่งมีชีวิต (ไทย)
 
 
 
129
  ):
130
- # parse float
131
  try:
132
  distance_au = float(distance_str)
133
  except:
@@ -138,62 +201,118 @@ def generate_planet_info(
138
  except:
139
  diameter_factor = 1.0
140
 
141
- # คำนวณ
142
- temp_c = approximate_temperature(planet_type_th, distance_au)
143
- gravity_g = approximate_gravity(diameter_factor)
 
144
 
145
- # 1) สรุปสำหรับเด็ก (ภาษาไทย)
146
- child_summary = child_friendly_summary(
147
- planet_name_th, planet_type_th, temp_c,
148
- gravity_g, oxygen_percent, life_th
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  )
150
 
151
- # 2) รายละเอียด (ไทย)
152
  detail_th = (
153
- f"ชื่อดาวเคราะห์: {planet_name_th}\n"
154
- f"ชนิดดาว: {planet_type_th}\n"
155
  f"ระยะห่าง: ~{distance_au} AU\n"
156
- f"ขนาด: ~{diameter_factor} เท่าโลก\n"
157
- f"อุณหภูมิ: ~{temp_c} °C\n"
158
- f"แรงโน้มถ่วง: ~{gravity_g} g\n"
159
- f"เปอร์เซ็นต์ออกซิเจน: {oxygen_percent}%\n"
160
- f"สิ่งมีชีวิต: {life_th}\n"
 
 
 
161
  )
162
 
163
- # 3) แปลเป็นอังกฤษผ่าน MarianMT
164
  planet_name_en = translate_th_to_en(planet_name_th)
165
- # แปล life_th ด้วย
166
  life_en = translate_th_to_en(life_th)
167
 
168
- # แมปชนิดดาว -> อังกฤษ
 
169
  type_map = {
170
- "ดาวหิน (Rocky Planet)": "rocky planet",
171
- "ดาวก๊าซ (Gas Giant)": "gas giant",
172
- "ดาวน้ำแข็ง (Icy Planet)": "icy planet",
173
  }
174
- planet_type_en = type_map.get(planet_type_th, "mysterious planet")
175
-
176
- # 4) สร้าง 3 prompts
177
- prompt1, prompt2, prompt3 = generate_three_prompts_en(
178
- planet_name_en, planet_type_en, distance_au, diameter_factor,
179
- temp_c, gravity_g, oxygen_percent, life_en
180
- )
181
-
182
- prompt_all = (
183
- f"--- Prompt #1 ---\n{prompt1}\n\n"
184
- f"--- Prompt #2 ---\n{prompt2}\n\n"
185
- f"--- Prompt #3 ---\n{prompt3}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  )
187
 
188
  return child_summary, detail_th, prompt_all
189
 
190
 
191
  ##############################################
192
- # ส่วน UI (Gradio)
193
  ##############################################
194
 
195
- import gradio as gr
196
-
197
  css_code = """
198
  body {
199
  background-color: #F9FBFF;
@@ -236,7 +355,7 @@ body {
236
  """
237
 
238
  def welcome_text():
239
- return "ยินดีต้อนรับสู่ Planetary Adventure! ลองกรอกข้อมูลแล้วกด 'สร้างโลกแฟนตาซี' สิ!"
240
 
241
  copy_button_html = """
242
  <button style="background-color: #F06292; border: 2px solid #E91E63; font-weight: bold;
@@ -253,49 +372,61 @@ function copyPromptText() {
253
  }
254
  const promptText = promptBox.value;
255
  navigator.clipboard.writeText(promptText);
256
- alert('คัดลอก Prompt แล้ว! เอาไปใช้กับ Midjourney ได้เลย~');
257
  }
258
  </script>
259
  """
260
 
 
 
261
  with gr.Blocks(css=css_code) as demo:
262
- gr.Markdown("<h1 id='title'>Planetary Adventure (Thai + %O2 + 3 English Prompts w/ Real Translation)</h1>")
263
  gr.Markdown("""
264
  <div class="game-desc">
265
- <p>ออกแบบดาวเคราะห์ในฝันของหนูน้อย (ภาษาไทย) แล้วให้ระบบแปลเป็นอังกฤษผ่าน MarianMT!</p>
266
- <ul>
267
- <li>กรอกชื่อดาว, ชนิดดาว, ระยะห่าง, ขนาด (เท่าโลก)</li>
268
- <li>เลื่อน %O2 ในบรรยากาศ</li>
269
- <li>พิมพ์สิ่งมีชีวิตเป็นภาษาไทย</li>
 
 
270
  <li>กดปุ่ม <strong>"สร้างโลกแฟนตาซี"</strong></li>
271
- </ul>
272
- <p>รับ <em>สรุปสำหรับเด็ก</em> (ไทย), <em>รายละเอียด</em> (ไทย), และ <em>3 Prompts อังกฤษ</em> นำไปใช้ใน Midjourney ได้ทันที!</p>
 
273
  </div>
274
  """)
275
 
276
  planet_name_th = gr.Textbox(label="ชื่อดาวเคราะห์ (ภาษาไทย)", placeholder="ตัวอย่าง: ดาวซานาดา")
277
- planet_type_th = gr.Dropdown(
278
- label="ชนิดดาว",
279
- choices=["ดาวหิน (Rocky Planet)", "ดาวก๊าซ (Gas Giant)", "ดาวน้ำแข็ง (Icy Planet)"],
280
- value="ดาวหิน (Rocky Planet)"
 
281
  )
282
- distance_au = gr.Textbox(label="ระยะห่างจากดาวฤกษ์ (หน่วย AU)", placeholder="เช่น 0.8, 1, 2")
283
- diameter_factor = gr.Textbox(label="ขนาด (เท่าเส้นผ่านศูนย์กลางโลก)", placeholder="เช่น 1, 2, 0.5")
 
 
 
284
 
285
  oxygen_slider = gr.Slider(
286
- minimum=0,
287
- maximum=100,
288
- step=1,
289
- value=21,
290
- label="% ออกซิเจนในบรรยากาศ"
 
 
 
291
  )
292
 
293
- life_th = gr.Textbox(label="สิ่งมีชีวิตบนดาว (ภาษาไทย)", placeholder="ตัวอย่าง: สัตว์เลื้อยคลานขนาดยักษ์")
294
 
295
  create_btn = gr.Button("สร้างโลกแฟนตาซี", elem_classes="btn-main")
296
 
297
- child_summary_out = gr.Textbox(label="สรุป (สำหรับเด็ก)", interactive=False, elem_id="child-summary")
298
- detail_th_out = gr.Textbox(label="รายละเอียด (ภาษาไทย)", interactive=False, elem_id="detail-th")
299
  prompt_en_out = gr.Textbox(label="3 Prompts (English)", interactive=False, elem_id="prompt-en")
300
 
301
  gr.HTML(copy_button_html)
@@ -303,14 +434,21 @@ with gr.Blocks(css=css_code) as demo:
303
  create_btn.click(
304
  fn=generate_planet_info,
305
  inputs=[
306
- planet_name_th,
307
- planet_type_th,
308
  distance_au,
309
  diameter_factor,
 
 
310
  oxygen_slider,
 
311
  life_th
312
  ],
313
- outputs=[child_summary_out, detail_th_out, prompt_en_out]
 
 
 
 
314
  )
315
 
316
  demo.load(fn=welcome_text, inputs=None, outputs=child_summary_out)
 
1
+ import math
2
  import gradio as gr
 
 
 
3
  from transformers import MarianMTModel, MarianTokenizer
4
+ import torch
5
 
6
+ ##############################################
7
+ # 1) โหลดโมเดล MarianMT สำหรับแปลไทย->อังกฤษ
8
+ ##############################################
9
  model_name = "Helsinki-NLP/opus-mt-th-en"
10
  tokenizer = MarianTokenizer.from_pretrained(model_name)
11
  model = MarianMTModel.from_pretrained(model_name)
12
 
13
+ def translate_th_to_en(text_th: str) -> str:
14
+ text_th = text_th.strip()
15
+ if not text_th:
 
 
 
 
16
  return ""
17
+ inputs = tokenizer(text_th, return_tensors="pt", max_length=512, truncation=True)
18
  translation_tokens = model.generate(**inputs, max_length=512)
19
  en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
20
  return en_text
21
 
 
22
  ##############################################
23
+ # 2) สูตรคำนวณ Black Body (Stefan-Boltzmann) + Greenhouse เบื้องต้น
24
  ##############################################
 
 
 
 
 
 
 
 
 
25
 
26
+ def approximate_temp_with_star(star_type, distance_au, albedo=0.3):
27
+ """
28
+ คำนวณอุณหภูมิพื้นผิว (°C) อย่างง่าย โดยอิง Black Body + star luminosity
29
+ - star_type:
30
+ "Red Dwarf" -> luminosity ~0.02 เท่าดวงอาทิตย์
31
+ "Sun-like" -> luminosity = 1 เท่าดวงอาทิตย์
32
+ "Blue Giant"-> luminosity ~10 เท่าดวงอาทิตย์ (สมมุติ)
33
+ - distance_au: ระยะห่างหน่วย AU
34
+ - albedo: สัดส่วนสะท้อนแสง (สมมุติ 0.3)
35
+ - สุดท้ายบวก greenhouse effect ~ +15 °C (สมมุติ)
36
+ """
37
+ if star_type == "Red Dwarf":
38
+ lum_ratio = 0.02 # สมมุติ
39
+ elif star_type == "Blue Giant":
40
+ lum_ratio = 10.0
41
+ else: # Sun-like
42
+ lum_ratio = 1.0
43
+
44
+ # ความสว่างของดวงอาทิตย์ ~3.828e26 W
45
+ luminosity = 3.828e26 * lum_ratio
46
+
47
+ # แปลง AU -> เมตร
48
+ dist_m = distance_au * 1.496e11
49
+
50
+ sigma = 5.67e-8 # Stefan-Boltzmann constant
51
+ # T(K) = [ ( (1 - A) * L ) / (16*pi*sigma * d^2 ) ]^(1/4)
52
+ T_k = ((1 - albedo) * luminosity / (16 * math.pi * sigma * dist_m**2))**0.25
53
+ T_c = T_k - 273.15
54
+
55
+ # บวก greenhouse เล็กน้อย
56
+ T_c += 15
57
+
58
+ return round(T_c)
59
+
60
+ def approximate_gravity(diameter_factor):
61
+ """
62
+ สมมุติว่า แรงโน้มถ่วง ~ diameter_factor เท่าของโลก
63
+ (จริงๆ เกี่ยวกับความหนาแน่นด้วย แต่เอาแบบง่าย)
64
+ """
65
+ return round(diameter_factor, 2)
66
 
67
 
68
  ##############################################
69
+ # 3) ฟังก์ชันแปลงตัวเลข -> คำบรรยายเชิงเปรียบเทียบ
70
  ##############################################
71
+
72
+ def describe_distance(distance_au):
73
+ """
74
+ ตีความระยะห่าง (AU) เป็นคำบรรยาย
75
+ """
76
+ if distance_au < 0.5:
77
+ return "โคจรอยู่ใกล้มากจนดาวเคราะห์ร้อนระอุ"
78
+ elif distance_au < 1.2:
79
+ return "โคจรค่อนข้างใกล้เหมือนโลก หรืออาจอุ่นกว่านิดหน่อย"
80
+ elif distance_au < 2.5:
81
+ return "โคจรห่างพอประมาณ ค่อนข้างเย็น"
82
+ else:
83
+ return "โคจรไกลมาก มีสภาพหนาวเย็นสุดขั้ว"
84
+
85
+ def describe_temp(temp_c):
86
+ """
87
+ ตีความอุณหภูมิ (°C) เป็นคำบรรยาย
88
+ """
89
+ if temp_c < -30:
90
+ return "อากาศหนาวแข็ง"
91
+ elif temp_c < 10:
92
+ return "อากาศค่อนข้างเย็น"
93
+ elif temp_c < 35:
94
+ return "อากาศกำลังสบาย"
95
  else:
96
+ return "ร้อนระอุ"
97
 
98
+ def describe_gravity(g):
99
+ """
100
+ ตีความแรงโน้มถ่วง (g) เป็นคำบรรยาย
101
+ """
102
+ if g < 0.5:
103
+ return "โน้มถ่วงเบามาก (ตัวลอยได้ง่าย)"
104
+ elif g < 1.2:
105
+ return "คล้ายโลก"
106
+ elif g < 2.0:
107
+ return "ค่อนข้างหนัก"
108
  else:
109
+ return "หนักมากจนอาจกดทับทุกสิ่ง"
110
 
111
+ def describe_tilt(tilt_deg):
112
+ """
113
+ ตีความแกนเอียง
114
+ """
115
+ tilt = float(tilt_deg)
116
+ if tilt < 5:
117
+ return "แทบไม่เอียง ฤดูกาลเรียบง่าย"
118
+ elif tilt < 25:
119
+ return "เอียงเล็กน้อย มีฤดูกาลพอประมาณ"
120
+ elif tilt < 45:
121
+ return "เอียงปานกลาง ฤดูกาลค่อนข้างเปลี่ยนแปลง"
122
+ else:
123
+ return "เอียงมาก ฤดูกาลสุดขั้ว"
124
 
125
+ def describe_moons(n):
126
+ """
127
+ ตีความจำนวนดวงจันทร์
128
+ """
129
+ n = int(n)
130
+ if n == 0:
131
+ return "ไม่มีดวงจันทร์"
132
+ elif n == 1:
133
+ return "มีดวงจันทร์หนึ่งดวง"
134
+ else:
135
+ return f"มีดวงจันทร์ {n} ดวง"
136
 
137
 
138
  ##############################################
139
+ # 4) สร้าง prompt 3 แบบ (ไม่มีตัวเลขตรงๆ)
140
  ##############################################
141
+
142
+ def build_prompts_en(planet_name_en, star_type_en, distance_desc_en,
143
+ temp_desc_en, gravity_desc_en, tilt_desc_en,
144
+ moon_desc_en, oxygen_desc_en, life_en):
145
+ """
146
+ สร้าง 3 prompts ภาษาอังกฤษ โดยไม่ใส่ตัวเลขตรงๆ
147
+ แต่ใช้คำบรรยายเชิงเปรียบเทียบ
148
+ """
 
149
 
150
  # Prompt 1: ภาพดาวจากอวกาศ
151
  prompt1 = (
152
+ f"A stunning space illustration of planet '{planet_name_en}' orbiting a {star_type_en} star. "
153
+ f"It is {distance_desc_en}, with {temp_desc_en} climate and {gravity_desc_en} surface gravity. "
154
+ f"{tilt_desc_en}, and {moon_desc_en}. Atmosphere containing {oxygen_desc_en}, truly fascinating."
155
  )
156
 
157
  # Prompt 2: สิ่งมีชีวิต
158
  prompt2 = (
159
+ f"Alien life on planet '{planet_name_en}': {life_en}, "
160
+ f"thriving under {temp_desc_en} conditions, {gravity_desc_en} gravity, and {oxygen_desc_en} in the air. "
161
+ f"Highly imaginative, concept art style, fantasy world."
162
  )
163
 
164
  # Prompt 3: พื้นผิวดาว
165
  prompt3 = (
166
+ f"The planet '{planet_name_en}' has a surface with {temp_desc_en} weather, {gravity_desc_en}, "
167
+ f"{tilt_desc_en}, and {moon_desc_en}. An epic terrain, atmospheric glow, and {oxygen_desc_en} presence. "
168
+ f"Realistic space painting, cinematic lighting."
169
  )
170
 
171
+ prompt_all = (
172
+ "--- Prompt #1 ---\n" + prompt1 + "\n\n"
173
+ "--- Prompt #2 ---\n" + prompt2 + "\n\n"
174
+ "--- Prompt #3 ---\n" + prompt3 + "\n"
175
+ )
176
+ return prompt_all
177
 
178
 
179
  ##############################################
180
+ # 5) ฟังก์ชันหลัก generate_planet_info
181
  ##############################################
182
  def generate_planet_info(
183
+ planet_name_th,
184
+ star_type_en_select, # ("Red Dwarf", "Sun-like", "Blue Giant")
185
+ distance_str,
186
+ diameter_str,
187
+ tilt_str,
188
+ moon_str,
189
+ oxygen_percent,
190
+ planet_type_th, # ("ดาวหิน", "ดาวก๊าซ", "ดาวน้ำแข็ง")
191
+ life_th
192
  ):
193
+ # แปลง string -> float/int
194
  try:
195
  distance_au = float(distance_str)
196
  except:
 
201
  except:
202
  diameter_factor = 1.0
203
 
204
+ try:
205
+ tilt_deg = float(tilt_str)
206
+ except:
207
+ tilt_deg = 23.5
208
 
209
+ try:
210
+ num_moon = int(moon_str)
211
+ except:
212
+ num_moon = 1
213
+
214
+ # 1) คำนวณอุณหภูมิ (°C)
215
+ temp_c = approximate_temp_with_star(star_type_en_select, distance_au)
216
+ # 2) คำนวณแรงโน้มถ่วง
217
+ g_approx = approximate_gravity(diameter_factor)
218
+
219
+ # 3) สร้าง “สรุปสำหรับเด็ก” (ภาษาไทย)
220
+ # โดยยังไม่ได้รวม star_type_en_select เพราะเป็นภาษาอังกฤษ
221
+ # แต่เราจะใช้ planet_type_th ด้วย
222
+ # สมมุติ child_friendly_summary:
223
+ # => โชว์ temp, g, oxygen, life
224
+ child_summary = (
225
+ f"ดาว {planet_name_th} เป็น{planet_type_th} "
226
+ f"โคจรรอบดาวฤกษ์ประเภท {star_type_en_select} (อิงวิทยาศาสตร์สมมุติ)\n"
227
+ f"อุณหภูมิประมาณ {temp_c}°C, "
228
+ f"แรงโน้มถ่วง ~{g_approx}g, ออกซิเจน ~{oxygen_percent}%, "
229
+ f"แกนเอียง {tilt_deg}°, {num_moon} ดวงจันทร์,\n"
230
+ f"มีสิ่งมีชีวิต: {life_th}\n"
231
+ f"น่าอัศจรรย์จริง ๆ!"
232
  )
233
 
234
+ # 4) รายละเอียดเชิงเทคนิค (ไทย)
235
  detail_th = (
236
+ f"ชื่อดาวเคราะห์ (ไทย): {planet_name_th}\n"
237
+ f"ประเภทดาวฤกษ์: {star_type_en_select}\n"
238
  f"ระยะห่าง: ~{distance_au} AU\n"
239
+ f"ขนาดเส้นผ่านศูนย์กลาง: ~{diameter_factor} เท่าโลก\n"
240
+ f"แกนเอียง: ~{tilt_deg}°\n"
241
+ f"จำนวนดวงจันทร์: {num_moon}\n"
242
+ f"อุณหภูมิคำนวณ: ~{temp_c} °C\n"
243
+ f"แรงโน้มถ่วง: ~{g_approx} g\n"
244
+ f"ออกซิเจน: {oxygen_percent}%\n"
245
+ f"ชนิดดาวเคราะห์ (ไทย): {planet_type_th}\n"
246
+ f"สิ่งมีชีวิต (ไทย): {life_th}\n"
247
  )
248
 
249
+ # 5) แปล planet_name_th -> English
250
  planet_name_en = translate_th_to_en(planet_name_th)
251
+ # แปล life_th -> อังกฤษ
252
  life_en = translate_th_to_en(life_th)
253
 
254
+ # แมป planet_type_th -> Eng
255
+ # (ดาวหิน -> rocky planet, ดาวก๊าซ -> gas giant, ดาวน้ำแข็ง -> icy planet)
256
  type_map = {
257
+ "ดาวหิน": "rocky planet",
258
+ "ดาวก๊าซ": "gas giant",
259
+ "ดาวน้ำแข็ง": "icy planet"
260
  }
261
+ # (กรณี user พิมพ์ว่า "ดาวหิน" หรือมีวงเล็บ อาจต้อง .replace ให้เคลียร์)
262
+ planet_type_key = planet_type_th.replace("(", "").replace(")", "").replace(" ", "").split("ดาว")[-1]
263
+ planet_type_key = planet_type_key.strip()
264
+ planet_type_en = type_map.get(planet_type_key, "unknown planet")
265
+
266
+ # 6) ตีความ distance, temp, gravity, tilt, moon, oxygen เพื่ออธิบายเป็นอังกฤษ (non-numeric)
267
+ # - distance
268
+ distance_desc_th = describe_distance(distance_au)
269
+ distance_desc_en = translate_th_to_en(distance_desc_th)
270
+ # - temp
271
+ temp_desc_th = describe_temp(temp_c)
272
+ temp_desc_en = translate_th_to_en(temp_desc_th)
273
+ # - gravity
274
+ gravity_desc_th = describe_gravity(g_approx)
275
+ gravity_desc_en = translate_th_to_en(gravity_desc_th)
276
+ # - tilt
277
+ tilt_desc_th = describe_tilt(tilt_deg)
278
+ tilt_desc_en = translate_th_to_en(tilt_desc_th)
279
+ # - moon
280
+ moon_desc_th = describe_moons(num_moon)
281
+ moon_desc_en = translate_th_to_en(moon_desc_th)
282
+ # - oxygen
283
+ # ถ้า oxygen 0 -> no oxygen
284
+ # oxygen < 5 -> extremely low oxygen
285
+ # etc.
286
+ if oxygen_percent < 1:
287
+ oxygen_desc_th = "ไม่มีออกซิเจน"
288
+ elif oxygen_percent < 10:
289
+ oxygen_desc_th = "ออกซิเจนจางมาก"
290
+ elif oxygen_percent < 25:
291
+ oxygen_desc_th = "ออกซิเจนพอเหมาะ"
292
+ else:
293
+ oxygen_desc_th = "ออกซิเจนสูง"
294
+ oxygen_desc_en = translate_th_to_en(oxygen_desc_th)
295
+
296
+ # 7) สร้าง 3 Prompts (English)
297
+ prompt_all = build_prompts_en(
298
+ planet_name_en,
299
+ f"{star_type_en_select} star", # e.g. "Red Dwarf star"
300
+ distance_desc_en,
301
+ temp_desc_en,
302
+ gravity_desc_en,
303
+ tilt_desc_en,
304
+ moon_desc_en,
305
+ oxygen_desc_en,
306
+ life_en
307
  )
308
 
309
  return child_summary, detail_th, prompt_all
310
 
311
 
312
  ##############################################
313
+ # 6) สร้าง UI (Gradio)
314
  ##############################################
315
 
 
 
316
  css_code = """
317
  body {
318
  background-color: #F9FBFF;
 
355
  """
356
 
357
  def welcome_text():
358
+ return "ยินดีต้อนรับสู่ Planetary Adventure+! ลองกรอกข้อมูลแล้วกด 'สร้างโลกแฟนตาซี' กันนะจ๊ะ"
359
 
360
  copy_button_html = """
361
  <button style="background-color: #F06292; border: 2px solid #E91E63; font-weight: bold;
 
372
  }
373
  const promptText = promptBox.value;
374
  navigator.clipboard.writeText(promptText);
375
+ alert('คัดลอก Prompt แล้ว! นำไปใ��้ใน AI สร้างภาพได้เลย~');
376
  }
377
  </script>
378
  """
379
 
380
+ import re
381
+
382
  with gr.Blocks(css=css_code) as demo:
383
+ gr.Markdown("<h1 id='title'>Planetary Adventure (Advanced) - Thai Input + Real Sci + No Direct Numbers</h1>")
384
  gr.Markdown("""
385
  <div class="game-desc">
386
+ <p>สร้างดาวเคราะห์พร้อมหลักวิทยาศาสตร์เบื้องต้น (สูตร Stefan-Boltzmann) และใช้การแปล MarianMT</p>
387
+ <ol>
388
+ <li>กรอกชื่อดาวเคราะห์ (ภาษาไทย)</li>
389
+ <li>เลือกชนิดดาวฤกษ์ (Red Dwarf / Sun-like / Blue Giant)</li>
390
+ <li>กรอกระยะห่าง (หน่วย AU), ขนาดเท่าโลก, แกนเอียง, จำนวนดวงจันทร์, % ออกซิเจน</li>
391
+ <li>ระบุประเภทดาวเคราะห์ (ไทย) เช่น "ดาวหิน", "ดาวก๊าซ", "ดาวน้ำแข็ง"</li>
392
+ <li>พิมพ์สิ่งมีชีวิต (ไทย)</li>
393
  <li>กดปุ่ม <strong>"สร้างโลกแฟนตาซี"</strong></li>
394
+ </ol>
395
+ <p>ระบบจะ <em>คำนวณอุณหภูมิ</em>, <em>แรงโน้มถ่วง</em>, <em>ตีความเป็นคำบรรยาย</em>, และแปลไทย->อังกฤษ<br>
396
+ จากนั้นสร้าง <strong>3 prompts</strong> ที่เลี่ยงตัวเลขตรงๆ ใช้คำเปรียบเทียบแทน</p>
397
  </div>
398
  """)
399
 
400
  planet_name_th = gr.Textbox(label="ชื่อดาวเคราะห์ (ภาษาไทย)", placeholder="ตัวอย่าง: ดาวซานาดา")
401
+
402
+ star_type_select = gr.Dropdown(
403
+ label="ประเภทดาวฤกษ์ (English)",
404
+ choices=["Red Dwarf", "Sun-like", "Blue Giant"],
405
+ value="Sun-like"
406
  )
407
+
408
+ distance_au = gr.Textbox(label="ระยะห่างจากดาวฤกษ์ (AU)", placeholder="เช่น 1, 0.5, 2")
409
+ diameter_factor = gr.Textbox(label="ขนาด (เท่าโลก)", placeholder="เช่น 1, 2, 0.5")
410
+ tilt_deg = gr.Textbox(label="แกนเอียง (องศา)", placeholder="0-90")
411
+ moon_number = gr.Textbox(label="จำนวนดวงจันทร์", placeholder="0, 1, 2, ...")
412
 
413
  oxygen_slider = gr.Slider(
414
+ minimum=0, maximum=100, step=1, value=21,
415
+ label="% ออกซิเจน (ในบรรยากาศ)"
416
+ )
417
+
418
+ planet_type_th = gr.Dropdown(
419
+ label="ชนิดดาวเคราะห์ (ไทย)",
420
+ choices=["ดาวหิน", "ดาวก๊าซ", "ดาวน้ำแข็ง"],
421
+ value="ดาวหิน"
422
  )
423
 
424
+ life_th = gr.Textbox(label="สิ่งมีชีวิต (ภาษาไทย)", placeholder="ตัวอย่า��: แมลงยักษ์เรืองแสง")
425
 
426
  create_btn = gr.Button("สร้างโลกแฟนตาซี", elem_classes="btn-main")
427
 
428
+ child_summary_out = gr.Textbox(label="สรุปสำหรับเด็ก (ไทย)", interactive=False, elem_id="child-summary")
429
+ detail_th_out = gr.Textbox(label="รายละเอียด (ไทย)", interactive=False, elem_id="detail-th")
430
  prompt_en_out = gr.Textbox(label="3 Prompts (English)", interactive=False, elem_id="prompt-en")
431
 
432
  gr.HTML(copy_button_html)
 
434
  create_btn.click(
435
  fn=generate_planet_info,
436
  inputs=[
437
+ planet_name_th, # text
438
+ star_type_select, # red dwarf / sun-like / blue giant
439
  distance_au,
440
  diameter_factor,
441
+ tilt_deg,
442
+ moon_number,
443
  oxygen_slider,
444
+ planet_type_th, # "ดาวหิน", "ดาวก๊าซ", "ดาวน้ำแข็ง"
445
  life_th
446
  ],
447
+ outputs=[
448
+ child_summary_out,
449
+ detail_th_out,
450
+ prompt_en_out
451
+ ]
452
  )
453
 
454
  demo.load(fn=welcome_text, inputs=None, outputs=child_summary_out)