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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +235 -250
app.py CHANGED
@@ -1,11 +1,10 @@
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)
@@ -19,153 +18,126 @@ def translate_th_to_en(text_th: str) -> str:
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 = (
@@ -175,22 +147,21 @@ def build_prompts_en(planet_name_en, star_type_en, distance_desc_en,
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:
@@ -202,117 +173,116 @@ def generate_planet_info(
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;
@@ -345,7 +315,7 @@ body {
345
  border-radius: 10px;
346
  margin-right: 10px;
347
  }
348
- #child-summary, #detail-th, #prompt-en {
349
  background-color: #FFFDF5;
350
  border: 2px solid #FFE082;
351
  border-radius: 10px;
@@ -354,94 +324,106 @@ body {
354
  }
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;
362
- font-size: 1.0rem; padding: 8px 20px; border-radius: 10px;"
363
- onclick="copyPromptText()">
364
- คัดลอก Prompt
365
- </button>
366
- <script>
367
- function copyPromptText() {
368
- const promptBox = document.querySelector('#prompt-en textarea');
369
- if (!promptBox) {
370
- alert('ไม่พบข้อความ Prompt!');
371
- return;
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)
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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=[
@@ -451,6 +433,9 @@ with gr.Blocks(css=css_code) as demo:
451
  ]
452
  )
453
 
 
 
 
454
  demo.load(fn=welcome_text, inputs=None, outputs=child_summary_out)
455
 
456
  demo.launch()
 
1
  import math
2
  import gradio as gr
3
+ from transformers import MarianTokenizer, MarianMTModel
 
4
 
5
+ ###################################
6
+ # 1) โหลดโมเดล MarianMT (Thai->En)
7
+ ###################################
8
  model_name = "Helsinki-NLP/opus-mt-th-en"
9
  tokenizer = MarianTokenizer.from_pretrained(model_name)
10
  model = MarianMTModel.from_pretrained(model_name)
 
18
  en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
19
  return en_text
20
 
21
+ ###################################
22
+ # 2) สูตรคำนวณอุณหภูมิ (Black Body)
23
+ ###################################
 
24
  def approximate_temp_with_star(star_type, distance_au, albedo=0.3):
25
  """
26
+ - star_type: เพิ่ม White Dwarf, Supergiant
27
+ - distance_au: ระยะห่าง (AU)
28
+ - albedo: สัดส่วนสะท้อน (0.3)
29
+ - กลไก: Stefan-Boltzmann + greenhouse + lum_ratio
 
 
 
 
30
  """
31
  if star_type == "Red Dwarf":
32
+ lum_ratio = 0.02
33
+ elif star_type == "White Dwarf":
34
+ lum_ratio = 0.001 # สมมุติ (white dwarf มักมี luminosity ต่ำ)
35
+ elif star_type == "Sun-like":
36
+ lum_ratio = 1.0
37
  elif star_type == "Blue Giant":
38
  lum_ratio = 10.0
39
+ elif star_type == "Supergiant":
40
+ lum_ratio = 100.0
41
+ else:
42
+ lum_ratio = 1.0 # default
 
43
 
44
+ luminosity = 3.828e26 * lum_ratio
45
  dist_m = distance_au * 1.496e11
46
 
47
+ sigma = 5.67e-8
 
48
  T_k = ((1 - albedo) * luminosity / (16 * math.pi * sigma * dist_m**2))**0.25
49
  T_c = T_k - 273.15
50
+ T_c += 15 # สมมุติ Greenhouse
 
 
51
 
52
  return round(T_c)
53
 
54
+ ###################################
55
+ # 3) สูตรแรงโน้มถ่วงตามกฎนิวตัน (สมมุติ)
56
+ ###################################
57
+ def approximate_gravity_nw(diameter_factor):
58
  """
59
+ ถ้าคิดว่าดาวเคราะห์มีความหนาแน่นเท่าโลก:
60
+ - มวล (M) ~ (diameter_factor^3) (เพราะ R^3 => Volume)
61
+ - รัศมี (R) ~ diameter_factor
62
+ - g ~ GM/R^2 ~ R^3 / R^2 = R (ถ้า density คงที่)
63
+ ดังนั้น g ~ diameter_factor (เหมือนเดิม)
64
+ แต่เราจะใส่ “สูตรจริง” ในปุ่มโชว์สูตร
65
  """
66
  return round(diameter_factor, 2)
67
 
68
+ ###################################
69
+ # 4) ตีความเชิงบรรยาย (ภาษาไทย)
70
+ ###################################
 
 
71
  def describe_distance(distance_au):
 
 
 
72
  if distance_au < 0.5:
73
+ return "โค��รใกล้ดาวฤกษ์มาก"
74
  elif distance_au < 1.2:
75
+ return "โคจรคล้ายโลกหรืออุ่นกว่านิดหน่อย"
76
  elif distance_au < 2.5:
77
+ return "โคจรห่างพอประมาณ อากาศค่อนข้างเย็น"
78
  else:
79
+ return "โคจรไกลสุดขั้ว อากาศหนาวมาก"
80
 
81
  def describe_temp(temp_c):
 
 
 
82
  if temp_c < -30:
83
  return "อากาศหนาวแข็ง"
84
  elif temp_c < 10:
85
+ return "เย็นสบาย"
86
  elif temp_c < 35:
87
+ return "พอเหมาะกำลังดี"
88
  else:
89
  return "ร้อนระอุ"
90
 
91
  def describe_gravity(g):
 
 
 
92
  if g < 0.5:
93
+ return "โน้มถ่วงเบา (ลอยง่าย)"
94
  elif g < 1.2:
95
  return "คล้ายโลก"
96
  elif g < 2.0:
97
+ return "หนักกว่าปกติ"
98
  else:
99
+ return "หนักมาก"
100
 
101
  def describe_tilt(tilt_deg):
102
+ if tilt_deg < 5:
103
+ return "แทบไม่เอียง"
104
+ elif tilt_deg < 25:
105
+ return "เอียงเล็กน้อย มีฤดูกาลเบาๆ"
106
+ elif tilt_deg < 45:
107
+ return "เอียงปานกลาง ฤดูกาลเปลี่ยนแปลง"
 
 
 
 
108
  else:
109
  return "เอียงมาก ฤดูกาลสุดขั้ว"
110
 
111
  def describe_moons(n):
112
+ if n <= 0:
 
 
 
 
113
  return "ไม่มีดวงจันทร์"
114
  elif n == 1:
115
  return "มีดวงจันทร์หนึ่งดวง"
116
  else:
117
+ # ถ้ามีเยอะ => tides effect
118
+ if n > 2:
119
+ return f"มีดวงจันทร์ {n} ดวง ซึ่งทำให้ปรากฏการณ์น้ำขึ้นน้ำลงรุนแรง"
120
+ else:
121
+ return f"มีดวงจันทร์ {n} ดวง"
122
+
123
+ ###################################
124
+ # 5) สร้าง Prompt 3 แบบ (ไม่มีตัวเลข)
125
+ ###################################
126
+ def build_prompts_en(planet_name_en, star_type_en, dist_desc_en, temp_desc_en, grav_desc_en, tilt_desc_en, moon_desc_en, oxygen_desc_en, life_en):
 
 
 
 
 
 
127
  prompt1 = (
128
+ f"A vibrant space painting of planet '{planet_name_en}' orbiting a {star_type_en}. "
129
+ f"It is {dist_desc_en}, with {temp_desc_en} conditions and {grav_desc_en} gravity. "
130
+ f"{tilt_desc_en}, {moon_desc_en}, atmosphere has {oxygen_desc_en}. Cinematic details."
131
  )
132
 
 
133
  prompt2 = (
134
+ f"On planet '{planet_name_en}', we discover {life_en} thriving in {temp_desc_en} weather, "
135
+ f"{grav_desc_en} pull, and {oxygen_desc_en} in the air. Surreal alien ecosystem, rich concept art."
 
136
  )
137
 
 
138
  prompt3 = (
139
+ f"Exploring the surface of '{planet_name_en}': {temp_desc_en} climate, {grav_desc_en}, "
140
+ f"{tilt_desc_en} tilt, and {moon_desc_en}. Epic environment design, atmospheric perspective."
 
141
  )
142
 
143
  prompt_all = (
 
147
  )
148
  return prompt_all
149
 
150
+ ###################################
151
+ # 6) ฟังก์ชันหลัก
152
+ ###################################
 
153
  def generate_planet_info(
154
  planet_name_th,
155
+ star_type_en, # Red Dwarf / White Dwarf / Sun-like / Blue Giant / Supergiant
156
  distance_str,
157
  diameter_str,
158
+ tilt_value,
159
+ moon_value,
160
  oxygen_percent,
161
+ planet_type_th, # (ดาวหิน, ดาวก๊าซ, ดาวน้ำแข็ง)
162
  life_th
163
  ):
164
+ # parse
165
  try:
166
  distance_au = float(distance_str)
167
  except:
 
173
  diameter_factor = 1.0
174
 
175
  try:
176
+ tilt_deg = float(tilt_value)
177
  except:
178
  tilt_deg = 23.5
179
 
180
  try:
181
+ moon_count = int(moon_value)
182
  except:
183
+ moon_count = 1
184
+
185
+ # คำนวณอุณหภูมิ
186
+ temp_c = approximate_temp_with_star(star_type_en, distance_au)
187
+ # คำนวณแรงโน้มถ่วงแบบนิวตันสมมุติ (R^3 => M, g => M/R^2 => R)
188
+ g_approx = approximate_gravity_nw(diameter_factor)
189
+
190
+ # สรุปสำหรับเด็ก (ภาษาไทย)
 
 
 
 
191
  child_summary = (
192
+ f"ดาว {planet_name_th} เป็น{planet_type_th} โคจรรอบดาวฤกษ์ {star_type_en}\n"
193
+ f"ระยะ ~{distance_au} AU => อุณหภูมิราว {temp_c}°C,\n"
194
+ f"แกนเอียง {tilt_deg}°, ดวงจันทร์ {moon_count}, "
195
+ f"แรงโน้มถ่วง ~{g_approx}g, O2 ~{oxygen_percent}%\n"
 
196
  f"มีสิ่งมีชีวิต: {life_th}\n"
197
+ f"น่าตื่นเต้นมาก!"
198
  )
199
 
200
+ # รายละเอียด
201
  detail_th = (
202
+ f"ชื่อดาวเคราะห์(ไทย): {planet_name_th}\n"
203
+ f"ประเภทดาวฤกษ์: {star_type_en}\n"
204
+ f"ระยะ (AU): {distance_au}\n"
205
+ f"ขนาด (เท่าโลก): {diameter_factor}\n"
206
+ f"แกนเอียง: {tilt_deg}°\n"
207
+ f"จำนวนดวงจันทร์: {moon_count}\n"
208
+ f"เปอร์เซ็นต์ O2: {oxygen_percent}%\n"
209
+ f"ชนิดดาวเคราะห์(ไทย): {planet_type_th}\n"
210
+ f"สิ่งมีชีวิต(ไทย): {life_th}\n"
211
+ f"อุณหภูมิ (สูตร SB): {temp_c} °C\n"
212
+ f"แรงโน้มถ่วง (สมมุติ R^3 => M => g): ~{g_approx} g\n"
213
  )
214
 
215
+ # แปลชื่อดาว, สิ่งมีชีวิต
216
  planet_name_en = translate_th_to_en(planet_name_th)
 
217
  life_en = translate_th_to_en(life_th)
218
 
219
+ # ตีความ distance, temp, grav, tilt, moon, oxygen
220
+ dist_desc_th = describe_distance(distance_au)
221
+ dist_desc_en = translate_th_to_en(dist_desc_th)
222
+
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  temp_desc_th = describe_temp(temp_c)
224
  temp_desc_en = translate_th_to_en(temp_desc_th)
225
+
226
+ grav_desc_th = describe_gravity(g_approx)
227
+ grav_desc_en = translate_th_to_en(grav_desc_th)
228
+
229
  tilt_desc_th = describe_tilt(tilt_deg)
230
  tilt_desc_en = translate_th_to_en(tilt_desc_th)
231
+
232
+ moon_desc_th = describe_moons(moon_count)
233
  moon_desc_en = translate_th_to_en(moon_desc_th)
234
+
235
+ # ตีความ O2
 
 
236
  if oxygen_percent < 1:
237
+ o2_desc_th = "ไม่มีออกซิเจน"
238
  elif oxygen_percent < 10:
239
+ o2_desc_th = "ออกซิเจนน้อย"
240
  elif oxygen_percent < 25:
241
+ o2_desc_th = "ออกซิเจนพอเหมาะ"
242
  else:
243
+ o2_desc_th = "ออกซิเจนสูง"
244
+ oxygen_desc_en = translate_th_to_en(o2_desc_th)
245
 
246
+ # สร้าง 3 Prompts
247
+ prompts_en = build_prompts_en(
248
  planet_name_en,
249
+ star_type_en + " star",
250
+ dist_desc_en,
251
  temp_desc_en,
252
+ grav_desc_en,
253
  tilt_desc_en,
254
  moon_desc_en,
255
  oxygen_desc_en,
256
  life_en
257
  )
258
 
259
+ return child_summary, detail_th, prompts_en
260
+
261
+ ###################################
262
+ # สูตร (Markdown) เพิ่มเนื้อหา
263
+ ###################################
264
+ formula_text = r"""
265
+ **สูตรอุณหภูมิ (Stefan-Boltzmann)**
266
 
267
+ \\[
268
+ T = \left(\frac{(1 - A) \times L}{16 \pi \sigma \, d^2}\right)^{\frac{1}{4}} - 273.15 + 15^\circ\text{C (Greenhouse)}
269
+ \\]
270
 
271
+ - \\(A\\) = Albedo
272
+ - \\(L\\) = ความสว่างของดาว (W)
273
+ - \\(\sigma\\) = 5.67\\times10^{-8} (ค่าคงที่ Stefan-Boltzmann)
274
+ - \\(d\\) = ระยะทาง (m)
275
 
276
+ **สูตรแรงโน้มถ่วงนิวตัน**: \\(g = \frac{GM}{R^2}\\)
277
+
278
+ ถ้าสมมติความหนาแน่นเท่าโลก => \\(M \propto R^3\\) => \\(g \propto \frac{R^3}{R^2} = R\\)
279
+
280
+ *(ในโค้ดเราประยุกต์ใช้ค่าสัดส่วนง่าย ๆ)*
281
+ """
282
+
283
+ ###################################
284
+ # 7) สร้าง UI (Gradio)
285
+ ###################################
286
  css_code = """
287
  body {
288
  background-color: #F9FBFF;
 
315
  border-radius: 10px;
316
  margin-right: 10px;
317
  }
318
+ #child-summary, #detail-th, #prompt-en, #formula-box {
319
  background-color: #FFFDF5;
320
  border: 2px solid #FFE082;
321
  border-radius: 10px;
 
324
  }
325
  """
326
 
327
+ def show_formula(state):
328
+ new_state = not state
329
+ return new_state, gr.update(visible=new_state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
+ def welcome_text():
332
+ return "ยินดีต้อนรับสู่ Planetary Adventure++! ลองกรอกข้อมูลแล้วกด 'สร้างโลกแฟนตาซี' สิ!"
333
 
334
  with gr.Blocks(css=css_code) as demo:
335
+ gr.Markdown("<h1 id='title'>ZenityX Planetary Adventure</h1>")
336
  gr.Markdown("""
337
  <div class="game-desc">
338
+ <p>เพิ่มประเภทดาวฤกษ์ (White Dwarf, Supergiant), ใส่เงื่อนไขน้ำขึ้นน้ำลง (tides) ถ้าดวงจันทร์เยอะ,
339
+ และใช้สูตรแรงโน้มถ่วงนิวตัน (สมมุติ).</p>
340
+ <p>กรอกข้อมูลแล้วกด <strong>"สร้างโลกแฟนตาซี"</strong>!</p>
341
+ <p>หากอยากดู <strong>สูตรคำนวณ</strong> ให้กดปุ่ม "โชว์สูตรคำนวณ" ด้านล่าง</p>
 
 
 
 
 
 
 
342
  </div>
343
  """)
344
 
345
+ formula_state = gr.State(value=False)
346
+ formula_md = gr.Markdown(formula_text, visible=False, elem_id="formula-box")
347
+
348
+ show_formula_btn = gr.Button("โชว์สูตรคำนวณ")
349
+ show_formula_btn.click(fn=show_formula, inputs=formula_state, outputs=[formula_state, formula_md])
350
+
351
+ with gr.Row():
352
+ with gr.Column():
353
+ planet_name_th = gr.Textbox(label="ชื่อดาวเคราะห์ (ไทย)", placeholder="เช่น: ดาวซานาดา")
354
+ star_type_en = gr.Dropdown(
355
+ label="ประเภทดาวฤกษ์",
356
+ choices=["Red Dwarf", "White Dwarf", "Sun-like", "Blue Giant", "Supergiant"],
357
+ value="Sun-like"
358
+ )
359
+ distance_au = gr.Textbox(label="ระยะห่าง (AU)", placeholder="1, 0.5, 2...")
360
+ diameter_factor = gr.Textbox(label="ขนาด (เท่าโลก)", placeholder="1, 2, 0.5...")
361
+
362
+ with gr.Column():
363
+ tilt_slider = gr.Slider(0, 90, step=1, value=23.5, label="แกนเอียง (องศา)")
364
+ moon_slider = gr.Slider(0, 10, step=1, value=1, label="จำนวนดวงจันทร์")
365
+ oxygen_slider = gr.Slider(0, 100, step=1, value=21, label="% ออกซิเจน")
366
+
367
+ planet_type_th = gr.Dropdown(
368
+ label="ชนิดดาวเคราะห์ (ไทย)",
369
+ choices=["ดาวหิน", "ดาวก๊าซ", "ดาวน้ำแข็ง"],
370
+ value="ดาวหิน"
371
+ )
372
+ life_th = gr.Textbox(label="สิ่งมีชีวิต (ไทย)", placeholder="แมลงยักษ์เรืองแสง...")
373
 
374
  create_btn = gr.Button("สร้างโลกแฟนตาซี", elem_classes="btn-main")
375
 
376
  child_summary_out = gr.Textbox(label="สรุปสำหรับเด็ก (ไทย)", interactive=False, elem_id="child-summary")
377
  detail_th_out = gr.Textbox(label="รายละเอียด (ไทย)", interactive=False, elem_id="detail-th")
378
+ prompt_en_out = gr.Textbox(label="Prompts (English)", interactive=False, elem_id="prompt-en")
379
+
380
+ copy_button_html = """
381
+ <button style="background-color: #F06292; border: 2px solid #E91E63; font-weight: bold;
382
+ font-size: 1.0rem; padding: 8px 20px; border-radius: 10px;"
383
+ onclick="copyPromptText()">
384
+ คัดลอก Prompt
385
+ </button>
386
+ <script>
387
+ function copyPromptText() {
388
+ const promptBox = document.querySelector('#prompt-en textarea');
389
+ if (!promptBox) {
390
+ alert('ไม่พบข้อความ Prompt!');
391
+ return;
392
+ }
393
+ const promptText = promptBox.value;
394
+ navigator.clipboard.writeText(promptText);
395
+ alert('คัดลอก Prompt แล้ว! ใช้งานกับ AI สร้างภาพได้เลย~');
396
+ }
397
+ </script>
398
+ """
399
  gr.HTML(copy_button_html)
400
 
401
+ def generate_wrapper(
402
+ p_name_th, s_type_en, dist_au, dia_fac, tilt_val, moon_val, oxy_val, p_type_th, l_th
403
+ ):
404
+ return generate_planet_info(
405
+ planet_name_th=p_name_th,
406
+ star_type_en=s_type_en,
407
+ distance_str=dist_au,
408
+ diameter_str=dia_fac,
409
+ tilt_value=str(tilt_val),
410
+ moon_value=str(moon_val),
411
+ oxygen_percent=oxy_val,
412
+ planet_type_th=p_type_th,
413
+ life_th=l_th
414
+ )
415
+
416
  create_btn.click(
417
+ fn=generate_wrapper,
418
  inputs=[
419
+ planet_name_th,
420
+ star_type_en,
421
  distance_au,
422
  diameter_factor,
423
+ tilt_slider,
424
+ moon_slider,
425
  oxygen_slider,
426
+ planet_type_th,
427
  life_th
428
  ],
429
  outputs=[
 
433
  ]
434
  )
435
 
436
+ def welcome_text():
437
+ return "ยินดีต้อนรับสู่ Planetary Adventure++! ลองกรอกข้อมูลแล้วกด 'สร้างโลกแฟนตาซี' สิ!"
438
+
439
  demo.load(fn=welcome_text, inputs=None, outputs=child_summary_out)
440
 
441
  demo.launch()