Update app.py
Browse files
app.py
CHANGED
@@ -1,11 +1,10 @@
|
|
1 |
import math
|
2 |
import gradio as gr
|
3 |
-
from transformers import
|
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)
|
24 |
-
|
25 |
-
|
26 |
def approximate_temp_with_star(star_type, distance_au, albedo=0.3):
|
27 |
"""
|
28 |
-
|
29 |
-
-
|
30 |
-
|
31 |
-
|
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 |
-
|
42 |
-
lum_ratio =
|
43 |
-
|
44 |
-
|
45 |
-
luminosity = 3.828e26 * lum_ratio
|
46 |
|
47 |
-
|
48 |
dist_m = distance_au * 1.496e11
|
49 |
|
50 |
-
sigma = 5.67e-8
|
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 |
-
|
|
|
|
|
|
|
61 |
"""
|
62 |
-
|
63 |
-
(
|
|
|
|
|
|
|
|
|
64 |
"""
|
65 |
return round(diameter_factor, 2)
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
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 |
-
|
116 |
-
|
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 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
"""
|
146 |
-
สร้าง 3 prompts ภาษาอังกฤษ โดยไม่ใส่ตัวเลขตรงๆ
|
147 |
-
แต่ใช้คำบรรยายเชิงเปรียบเทียบ
|
148 |
-
"""
|
149 |
-
|
150 |
-
# Prompt 1: ภาพดาวจากอวกาศ
|
151 |
prompt1 = (
|
152 |
-
f"A
|
153 |
-
f"It is {
|
154 |
-
f"{tilt_desc_en},
|
155 |
)
|
156 |
|
157 |
-
# Prompt 2: สิ่งมีชีวิต
|
158 |
prompt2 = (
|
159 |
-
f"
|
160 |
-
f"
|
161 |
-
f"Highly imaginative, concept art style, fantasy world."
|
162 |
)
|
163 |
|
164 |
-
# Prompt 3: พื้นผิวดาว
|
165 |
prompt3 = (
|
166 |
-
f"
|
167 |
-
f"{tilt_desc_en}, and {moon_desc_en}.
|
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 |
-
|
181 |
-
##############################################
|
182 |
def generate_planet_info(
|
183 |
planet_name_th,
|
184 |
-
|
185 |
distance_str,
|
186 |
diameter_str,
|
187 |
-
|
188 |
-
|
189 |
oxygen_percent,
|
190 |
-
planet_type_th,
|
191 |
life_th
|
192 |
):
|
193 |
-
#
|
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(
|
206 |
except:
|
207 |
tilt_deg = 23.5
|
208 |
|
209 |
try:
|
210 |
-
|
211 |
except:
|
212 |
-
|
213 |
-
|
214 |
-
#
|
215 |
-
temp_c = approximate_temp_with_star(
|
216 |
-
# 2)
|
217 |
-
g_approx =
|
218 |
-
|
219 |
-
#
|
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"
|
227 |
-
f"
|
228 |
-
f"แรงโน้มถ่วง ~{g_approx}g,
|
229 |
-
f"แกนเอียง {tilt_deg}°, {num_moon} ดวงจันทร์,\n"
|
230 |
f"มีสิ่งมีชีวิต: {life_th}\n"
|
231 |
-
f"
|
232 |
)
|
233 |
|
234 |
-
#
|
235 |
detail_th = (
|
236 |
-
f"ชื่อดาวเคราะห์
|
237 |
-
f"ประเภทดาวฤกษ์: {
|
238 |
-
f"
|
239 |
-
f"
|
240 |
-
f"แกนเอียง:
|
241 |
-
f"จำนวนดวงจันทร์: {
|
242 |
-
f"
|
243 |
-
f"
|
244 |
-
f"
|
245 |
-
f"
|
246 |
-
f"
|
247 |
)
|
248 |
|
249 |
-
#
|
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 |
-
#
|
255 |
-
|
256 |
-
|
257 |
-
|
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 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
tilt_desc_th = describe_tilt(tilt_deg)
|
278 |
tilt_desc_en = translate_th_to_en(tilt_desc_th)
|
279 |
-
|
280 |
-
moon_desc_th = describe_moons(
|
281 |
moon_desc_en = translate_th_to_en(moon_desc_th)
|
282 |
-
|
283 |
-
#
|
284 |
-
# oxygen < 5 -> extremely low oxygen
|
285 |
-
# etc.
|
286 |
if oxygen_percent < 1:
|
287 |
-
|
288 |
elif oxygen_percent < 10:
|
289 |
-
|
290 |
elif oxygen_percent < 25:
|
291 |
-
|
292 |
else:
|
293 |
-
|
294 |
-
oxygen_desc_en = translate_th_to_en(
|
295 |
|
296 |
-
#
|
297 |
-
|
298 |
planet_name_en,
|
299 |
-
|
300 |
-
|
301 |
temp_desc_en,
|
302 |
-
|
303 |
tilt_desc_en,
|
304 |
moon_desc_en,
|
305 |
oxygen_desc_en,
|
306 |
life_en
|
307 |
)
|
308 |
|
309 |
-
return child_summary, detail_th,
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
|
|
|
|
|
|
|
311 |
|
312 |
-
|
313 |
-
|
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
|
358 |
-
|
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 |
-
|
|
|
381 |
|
382 |
with gr.Blocks(css=css_code) as demo:
|
383 |
-
gr.Markdown("<h1 id='title'>Planetary Adventure
|
384 |
gr.Markdown("""
|
385 |
<div class="game-desc">
|
386 |
-
<p
|
387 |
-
|
388 |
-
|
389 |
-
|
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 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
)
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
|
|
|
|
|
|
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="
|
431 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
432 |
gr.HTML(copy_button_html)
|
433 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
434 |
create_btn.click(
|
435 |
-
fn=
|
436 |
inputs=[
|
437 |
-
planet_name_th,
|
438 |
-
|
439 |
distance_au,
|
440 |
diameter_factor,
|
441 |
-
|
442 |
-
|
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()
|