Spaces:
Sleeping
Sleeping
Create main.py
Browse files
main.py
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import threading
|
| 4 |
+
import random
|
| 5 |
+
import logging
|
| 6 |
+
import torch
|
| 7 |
+
import torch.nn.functional as F
|
| 8 |
+
from flask import Flask, request, jsonify
|
| 9 |
+
|
| 10 |
+
# --- CONFIGURATION ---
|
| 11 |
+
MAX_IDLE_TIME = 3600
|
| 12 |
+
CLEANUP_INTERVAL = 300
|
| 13 |
+
|
| 14 |
+
# ⚠️ ไฟล์ Vector ภาษาไทยที่เราเพิ่งอบเสร็จ
|
| 15 |
+
VECTOR_FILE = "vectors_th_fasttext.pt"
|
| 16 |
+
|
| 17 |
+
# --- รายชื่อคำศัพท์สำหรับสุ่มเป็น "คำตอบ" (Secret Word) ---
|
| 18 |
+
KIDS_WORDS = [
|
| 19 |
+
# 👨👩👧👦 ครอบครัว & คน & อาชีพ
|
| 20 |
+
"พ่อ", "แม่", "ลูก", "พี่", "น้อง", "ปู่", "ย่า", "ตา", "ยาย", "ลุง", "ป้า", "น้า",
|
| 21 |
+
"ครู", "นักเรียน", "หมอ", "พยาบาล", "ตำรวจ", "ทหาร", "เพื่อน", "คน", "เด็ก", "ผู้ชาย", "ผู้หญิง",
|
| 22 |
+
"ชาวนา", "พ่อค้า", "แม่ค้า", "นักบิน", "คนขับรถ", "ดารา", "นักร้อง", "ช่างภาพ", "พ่อครัว",
|
| 23 |
+
"พระ", "เณร", "โจร", "ยักษ์", "นางฟ้า", "เจ้าหญิง", "เจ้าชาย", "กษัตริย์", "ราชินี",
|
| 24 |
+
|
| 25 |
+
# 🐶 สัตว์บก & สัตว์เลี้ยง
|
| 26 |
+
"หมา", "แมว", "ไก่", "เป็ด", "นก", "ช้าง", "ม้า", "วัว","หมู",
|
| 27 |
+
"ลิง", "เสือ", "สิงโต", "กระต่าย", "เต่า", "งู", "กบ", "มด", "ผึ้ง", "ยุง",
|
| 28 |
+
"หมี", "ยีราฟ", "ม้าลาย", "จระเข้", "แกะ", "แพะ", "กวาง", "จิ้งจก",
|
| 29 |
+
"หนอน", "ผีเสื้อ", "แมงมุม", "แมลงสาบ", "กระรอก", "หนู", "จิ้งจอก", "หมาป่า",
|
| 30 |
+
|
| 31 |
+
# 🐟 สัตว์น้ำ
|
| 32 |
+
"ปลา", "กุ้ง", "หอย", "ปู", "ปลาหมึก", "ฉลาม", "โลมา", "วาฬ", "แมงกะพรุน", "ดาวทะเล",
|
| 33 |
+
|
| 34 |
+
# 🏠 สิ่งของในบ้าน & ของใช้ส่วนตัว
|
| 35 |
+
"บ้าน", "โต๊ะ", "เก้าอี้", "เตียง", "หมอน", "ผ้าห่ม","กระจก", "นาฬิกา", "หวี",
|
| 36 |
+
"สบู่", "ยาสีฟัน", "แปรงสีฟัน", "แชมพู", "ผ้าเช็ดตัว", "แป้ง", "ถังขยะ", "ไม้กวาด", "ไม้ถูพื้น",
|
| 37 |
+
"จาน", "ชาม", "ช้อน","แก้ว", "ขวด", "มีด", "เขียง", "หม้อ", "กระทะ",
|
| 38 |
+
"ถังน้ำ", "กุญแจ", "ไฟฉาย", "เทียน", "ธูป", "แจกัน", "รูปภาพ",
|
| 39 |
+
|
| 40 |
+
# 📺 เครื่องใช้ไฟฟ้า & เทคโนโลยี
|
| 41 |
+
"คอมพิวเตอร์", "โทรศัพท์", "ทีวี", "ตู้เย็น", "พัดลม", "แอร์", "หม้อหุงข้าว", "เตารีด",
|
| 42 |
+
"เครื่องซักผ้า", "ไมโครเวฟ", "หลอดไฟ", "ปลั๊กไฟ", "วิทยุ", "ลำโพง", "กล้อง",
|
| 43 |
+
|
| 44 |
+
# ✏️ โรงเรียน & เครื่องเขียน
|
| 45 |
+
"โรงเรียน", "หนังสือ", "สมุด", "ดินสอ", "ปากกา", "ยางลบ", "ไม้บรรทัด", "กบเหลาดินสอ",
|
| 46 |
+
"กระเป๋า", "กระดาน", "ชอล์ก", "สี", "พู่กัน", "กรรไกร", "กาว", "กล่องดินสอ", "ลูกโลก", "ธงชาติ",
|
| 47 |
+
|
| 48 |
+
# 🚗 ยานพาหนะ & การเดินทาง
|
| 49 |
+
"รถ", "รถยนต์", "รถมอเตอร์ไซค์", "จักรยาน", "รถเมล์", "รถตู้", "รถไฟ", "เรือ", "เครื่องบิน",
|
| 50 |
+
"จรวด", "รถพยาบาล", "รถดับเพลิง", "รถตำรวจ", "รถบรรทุก", "รถแท็กซี่","ถนน", "สะพาน", "ทางม้าลาย",
|
| 51 |
+
|
| 52 |
+
# 🌳 ธรรมชาติ & สิ่งแวดล้อม
|
| 53 |
+
"ฟ้า", "ฝน", "เมฆ", "แดด", "ลม", "ดิน", "หิน", "ทราย", "น้ำ", "ไฟ",
|
| 54 |
+
"ภูเขา", "ทะเล", "แม่น้ำ", "ลำธาร", "น้ำตก", "ป่า", "ถ้ำ", "เกาะ", "ชายหาด",
|
| 55 |
+
"ต้นไม้", "ดอกไม้", "ใบไม้", "หญ้า", "รากไม้", "กิ่งไม้", "ผลไม้",
|
| 56 |
+
"พระอาทิตย์", "พระจั��ทร์", "ดาว", "รุ้ง", "หิมะ", "ภูเขาไฟ", "คลื่น", "ฝุ่น", "ควัน",
|
| 57 |
+
|
| 58 |
+
# 🍉 ผลไม้ & ผัก
|
| 59 |
+
"กล้วย", "ส้ม", "แตงโม", "มะม่วง", "แอปเปิ้ล", "องุ่น", "ทุเรียน", "เงาะ", "ลำไย", "มังคุด",
|
| 60 |
+
"สตรอว์เบอร์รี", "มะพร้าว", "สับปะรด", "ชมพู่", "ฝรั่ง", "มะละกอ",
|
| 61 |
+
"ผัก", "ข้าวโพด", "แตงกวา", "มะเขือเทศ", "ฟักทอง", "แครอท", "ผักบุ้ง", "พริก", "มะนาว", "หัวหอม", "กระเทียม",
|
| 62 |
+
|
| 63 |
+
# 🍜 อาหาร & ขนม
|
| 64 |
+
"ข้าว", "ข้าวผัด", "ไข่เจียว", "ไข่ต้ม", "ก๋วยเตี๋ยว", "ส้มตำ", "ไก่ทอด", "หมูปิ้ง", "ลูกชิ้น",
|
| 65 |
+
"ขนม", "ขนมปัง", "เค้ก", "ไอศกรีม", "ช็อกโกแลต", "ลูกอม", "เยลลี่", "คุกกี้", "โดนัท",
|
| 66 |
+
"น้ำ", "นม", "น้ำอัดลม", "น้ำส้ม", "น้ำแข็ง", "น้ำตาล", "เกลือ", "น้ำปลา",
|
| 67 |
+
|
| 68 |
+
# 👕 ร่างกาย & เครื่องแต่งกาย
|
| 69 |
+
"หัว", "ตา", "หู", "จมูก", "ปาก", "ฟัน", "ลิ้น", "แก้ม", "คาง", "หน้าผาก", "คอ",
|
| 70 |
+
"มือ", "นิ้ว", "แขน", "เล็บ", "ท้อง", "หลัง", "ขา", "เข่า", "เท้า", "ผม", "ผิว", "เลือด", "กระดูก",
|
| 71 |
+
"เสื้อ", "กางเกง", "กระโปรง", "รองเท้า", "ถุงเท้า", "หมวก", "เข็มขัด", "แว่นตา", "หน้ากาก", "แหวน", "สร้อย",
|
| 72 |
+
|
| 73 |
+
# 🏥 สถานที่ต่างๆ
|
| 74 |
+
"บ้าน", "โรงพยาบาล", "วัด", "ตลาด", "สวนสัตว์", "ห้าง", "ร้านค้า", "สวนสนุก", "สวนสาธารณะ", "สนามเด็กเล่น",
|
| 75 |
+
"ห้องน้ำ", "ห้องนอน", "ห้องครัว", "ห้องนั่งเล่น", "สนามบิน", "โรงแรม", "ธนาคาร", "ไปรษณีย์", "สถานีตำรวจ",
|
| 76 |
+
|
| 77 |
+
# 🎨 สี & รูปร่าง
|
| 78 |
+
"สีแดง", "สีเหลือง", "สีชมพู", "สีเขียว", "สีส้ม", "สีฟ้า", "สีน้ำเงิน", "สีม่วง", "สีดำ", "สีขาว", "สีเทา", "สีน้ำตาล",
|
| 79 |
+
"วงกลม", "สี่เหลี่ยม", "สามเหลี่ยม", "ดาว", "หัวใจ",
|
| 80 |
+
|
| 81 |
+
# ⚽ กีฬา & ของเล่น
|
| 82 |
+
"ฟุตบอล", "บาสเกตบอล", "ว่ายน้ำ", "วิ่ง", "มวย", "แบดมินตัน",
|
| 83 |
+
"ตุ๊กตา", "ลูกบอล", "หุ่นยนต์", "รถบังคับ", "ตัวต่อ", "ลูกโป่ง","เกม",
|
| 84 |
+
|
| 85 |
+
# 😊 ความรู้สึกและคำขยาย (Adjectives)
|
| 86 |
+
"ดี", "เลว", "ชั่ว", "เก่ง", "ฉลาด","น่ารัก", "สวย", "หล่อ",
|
| 87 |
+
"อ้วน", "ผอม", "สูง", "เตี้ย", "ใหญ่", "เล็ก", "ยาว", "สั้น", "กว้าง", "แคบ",
|
| 88 |
+
"หนา", "บาง", "หนัก", "เบา", "แข็ง", "นิ่ม", "นุ่ม", "เหนียว", "ลื่น",
|
| 89 |
+
"เรียบ", "ตรง", "โค้ง", "งอ", "กลม", "ลึก", "ตื้น", "ไกล", "ใกล้",
|
| 90 |
+
"เร็ว", "ช้า", "ดัง", "เบา", "เงียบ", "สว่าง", "มืด", "ร้อน", "หนาว", "เย็น",
|
| 91 |
+
"อุ่น", "เปียก", "แห้ง", "สะอาด", "สกปรก", "ใหม่", "เก่า", "แก่", "หนุ่ม", "สาว",
|
| 92 |
+
"รวย", "จน", "ถูก", "แพง", "ง่าย", "ยาก", "เยอะ", "น้อย", "หมด", "เต็ม",
|
| 93 |
+
"ว่าง", "หิว", "อิ่ม", "ง่วง", "เหนื่อย", "สบาย", "ป่วย", "เจ็บ", "คัน", "ปวด",
|
| 94 |
+
"หอม", "เหม็น", "อร่อย", "หวาน", "เปรี้ยว", "เค็ม", "เผ็ด", "ขม", "มัน",
|
| 95 |
+
"สด", "เน่า", "สุก", "ดิบ", "กรอบ", "เละ", "จริง", "ปลอม", "ผิด", "ถูก",
|
| 96 |
+
|
| 97 |
+
# 🕒 เวลาและฤดูกาล (Time & Seasons)
|
| 98 |
+
"เวลา", "นาฬิกา", "วินาที", "นาที", "ชั่วโมง", "วัน", "สัปดาห์", "เดือน", "ปี",
|
| 99 |
+
"เช้า", "สาย", "เที่ยง", "บ่าย", "เย็น", "ค่ำ", "ดึก", "รุ่งเช้า",
|
| 100 |
+
"เมื่อวาน", "วันนี้", "พรุ่งนี้", "มะรืน", "อดีต", "ปัจจุบัน", "อนาคต",
|
| 101 |
+
"ฤดูร้อน", "ฤดูฝน", "ฤดูหนาว", "เทศกาล", "ปีใหม่", "สงกรานต์", "ลอยกระทง", "วันเด็ก",
|
| 102 |
+
|
| 103 |
+
# 🏙️ สถานที่ (Places)
|
| 104 |
+
"เมือง", "ชนบท", "หมู่บ้าน", "จังหวัด", "ประเทศ", "โลก", "จักรวาล", "อวกาศ",
|
| 105 |
+
"สนามบิน", "ท่าเรือ", "สถานีรถไฟ", "ป้ายรถเมล์", "ทางด่วน", "ถนนใหญ่", "ซอย",
|
| 106 |
+
"สะพาน", "อุโมงค์", "ทางม้าลาย", "สี่แยก", "วงเวียน", "ฟุตบาท", "ทางเดิน",
|
| 107 |
+
"ตึก", "อาคาร", "คอนโด", "หอพัก", "โรงแรม", "รีสอร์ท", "กระท่อม", "ปราสาท",
|
| 108 |
+
"วัง", "พิพิธภัณฑ์", "ห้องสมุด", "โรงหนัง", "สวนสนุก", "สวนน้ำ", "สนามกีฬา",
|
| 109 |
+
"สระว่ายน้ำ", "ยิม", "ร้านอาหาร", "ร้านกาแฟ", "ร้านหนังสือ", "ร้านตัดผม", "ร้านขายยา",
|
| 110 |
+
"ตลาดนัด", "ซุปเปอร์มาร์เก็ต", "เซเว่น", "ปั๊มน้ำมัน", "อู่ซ่อมรถ", "โรงงาน", "บริษัท",
|
| 111 |
+
"ที่ทำงาน", "สถานีดับเพลิง", "คุก", "ศาล", "อำเภอ", "เทศบาล", "รัฐสภา",
|
| 112 |
+
"วัด", "โบสถ์", "ศาลเจ้า", "เจดีย์", "เมรุ", "ป่าช้า", "สุสาน",
|
| 113 |
+
|
| 114 |
+
# 🎸 ดนตรีและศิลปะ (Music & Arts)
|
| 115 |
+
"ดนตรี", "เพลง", "นักร้อง", "วงดนตรี", "คอนเสิร์ต", "ทำนอง", "จังหวะ", "เสียง",
|
| 116 |
+
"กีตาร์", "เปียโน", "กลอง", "ไวโอลิน","ทรัมเป็ต", "ขลุ่ย", "แคน",
|
| 117 |
+
"ระนาด", "กลองยาว", "พิณ", "ซอ", "อูคูเลเล่", "ไมโครโฟน", "ลำโพง",
|
| 118 |
+
"ศิลปะ", "รูปวาด", "ภาพถ่าย", "สีน้ำ", "สีเทียน", "สีไม้", "พู่กัน", "จานสี",
|
| 119 |
+
"ดินน้ำมัน", "กาว", "กรรไกร", "คัตเตอร์", "ไม้บรรทัด", "ยางลบ",
|
| 120 |
+
"ละคร", "การ์ตูน", "หนัง", "นิทาน", "เรื่องเล่า", "บทกวี", "กลอน", "เต้น", "รำ",
|
| 121 |
+
|
| 122 |
+
# 🔧 เครื่องมือและเทคโนโลยี (Tools & Tech)
|
| 123 |
+
"ค้อน", "ตะปู", "ไขควง","เลื่อย", "สว่าน", "คีม", "ประแจ", "ตลับเมตร",
|
| 124 |
+
"บันได", "เชือก", "โซ่", "กุญแจ", "แม่กุญแจ", "ลูกกุญแจ", "ไฟแช็ก", "ไม้ขีด",
|
| 125 |
+
"อินเทอร์เน็ต", "ไวไฟ", "เว็บไซต์","เกม", "หน้าจอ", "เมาส์", "คีย์บอร์ด",
|
| 126 |
+
"หูฟัง", "สายชาร์จ", "แบตเตอรี่", "ถ่าน", "รีโมท","สวิตช์ไฟ",
|
| 127 |
+
"หุ่นยนต์", "ดาวเทียม", "จรวด", "ยานอวกาศ", "มนุษย์ต่างดาว",
|
| 128 |
+
|
| 129 |
+
# 🦁 สัตว์เพิ่มเติม (More Animals)
|
| 130 |
+
"นกแก้ว", "นกอินทรี", "นกฮูก", "นกเพนกวิน", "นกกระจอกเทศ", "นกยูง", "หงส์", "ห่าน",
|
| 131 |
+
"ไก่งวง", "ค้างคาว", "ตุ๊กแก", "กิ้งก่า", "ตะขาบ", "แมงป่อง", "ปลวก", "เหา",
|
| 132 |
+
"เห็บ", "หมัด","พยาธิ", "ไส้เดือน", "ทาก", "หอยทาก", "แมลงปอ", "ตั๊กแตน",
|
| 133 |
+
"จิ้งหรีด", "จักจั่น", "ด้วง", "ต่อ", "แตน", "แมลงวัน", "หิ่งห้อย", "แมงมุม",
|
| 134 |
+
"วาฬ", "โลมา", "แมวน้ำ", "สิงโตทะเล", "วอลรัส", "นาก", "บีเวอร์", "ตุ่น",
|
| 135 |
+
"เม่น", "สลอธ", "โคอาล่า", "จิงโจ้","อัลปาก้า", "ลา",
|
| 136 |
+
|
| 137 |
+
# 🥦 ผักผลไม้และอาหารเพิ่มเติม (More Food)
|
| 138 |
+
"ทุเรียน", "มังคุด", "ลำไย", "ลิ้นจี่", "ขนุน","พุทรา", "มะขาม",
|
| 139 |
+
"มะยม","เสาวรส", "แก้วมังกร","เชอร์รี่", "บลูเบอร์รี่",
|
| 140 |
+
"อะโวคาโด", "ลูกพีช", "ลูกพลับ", "สาลี่", "ลูกเกด",
|
| 141 |
+
"ถั่ว", "งา", "พริกไทย", "ขิง", "ข่า", "ตะไคร้", "ใบมะกรูด", "โหระพา",
|
| 142 |
+
"กะเพรา", "สะระแหน่", "ผักชี", "ต้นหอม", "ขึ้นฉ่าย", "ผักกาด", "คะน้า", "กวางตุ้ง",
|
| 143 |
+
"บุ้ง", "กระหล่ำปลี", "บล็อกโคลี่", "เห็ด", "หน่อไม้", "ยอดมะพร้าว", "เผือก", "มัน",
|
| 144 |
+
"ก๋วยจั๊บ", "ราดหน้า", "ผัดซีอิ๊ว", "ผัดไทย", "หอยทอด", "ข้าวมันไก่", "ข้าวขาหมู",
|
| 145 |
+
"ข้าวหมูแดง", "แกงเขียวหวาน", "แกงส้ม", "ต้มยำกุ้ง", "ต้มข่าไก่", "ไข่พะโล้",
|
| 146 |
+
"น้ำพริก", "ปลาทู", "ไข่ดาว", "ไข่ตุ๋น", "ไส้กรอก", "แฮม", "เบคอน", "ชีส",
|
| 147 |
+
"เนย", "นมข้น", "น้ำเชื่อม", "น้ำผึ้ง", "ซอส", "น้ำส้มสายชู", "ผงชูรส",
|
| 148 |
+
"ทองหยิบ", "ทองหยอด", "ฝอยทอง", "เม็ดขนุน", "สังขยา", "วุ้น", "เฉาก๊วย", "ลอดช่อง",
|
| 149 |
+
|
| 150 |
+
# 👔 เสื้อผ้าและเครื่องแต่งกาย (Clothing)
|
| 151 |
+
"เสื้อยืด", "เสื้อเชิ้ต", "เสื้อกล้าม", "เสื้อกันหนาว", "เสื้อกันฝน", "ชุดนักเรียน",
|
| 152 |
+
"ชุดนอน","ผ้าขาวม้า",
|
| 153 |
+
"เข็มขัด", "เนคไท", "โบว์", "กิ๊บ", "ยางรัดผม", "ที่คาดผม", "หมวกแก๊ป", "หมวกกันน็อค",
|
| 154 |
+
"ผ้าพันคอ", "ถุงมือ", "ถุงเท้า", "รองเท้าแตะ", "รองเท้าผ้าใบ", "รองเท้าหนัง", "รองเท้าส้นสูง",
|
| 155 |
+
"สร้อยคอ", "สร้อยข้อมือ", "กำไล", "ต่างหู", "แหวน", "นาฬิกาข้อมือ", "แว่นกันแดด",
|
| 156 |
+
"ร่ม", "กระเป๋าเป้","พวงกุญแจ",
|
| 157 |
+
|
| 158 |
+
# 🏥 สุขภาพและร่างกาย (Health & Body)
|
| 159 |
+
"สมอง", "หัวใจ", "ปอด", "กระเพาะ", "ลำไส้", "ตับ", "ไต", "เลือด", "น้ำลาย",
|
| 160 |
+
"ขี้หู", "ขี้ตา", "เล็บมือ", "เล็บเท้า",
|
| 161 |
+
"ข้อศอก", "หัวไหล่", "หน้าอก", "เอว", "สะโพก","ผิวหนัง",
|
| 162 |
+
"ขน", "หนวด", "เครา", "ลักยิ้ม", "ปาน", "แผล",
|
| 163 |
+
"ไข้", "ไอ", "จาม", "หวัด", "ปวดหัว", "ปวดท้อง","ยา",
|
| 164 |
+
"ยาน้ำ", "ยาฉีด", "เข็มฉีดยา", "ผ้าพันแผล", "รถเข็น", "ไม้เท้า",
|
| 165 |
+
|
| 166 |
+
# 🌪️ ธรรมชาติและภัยพิบัติ (Nature)
|
| 167 |
+
"แผ่นดินไหว", "น้ำท่วม", "ไฟไหม้", "พายุ", "สึนามิ", "ภูเขาไฟระเบิด", "โรคระบาด",
|
| 168 |
+
"อากาศ", "ออกซิเจน", "คาร์บอน", "ฝุ่น", "ควัน", "หมอก", "น้ำค้าง", "ลูกเห็บ",
|
| 169 |
+
"รุ้งกินน้ำ", "ดาวตก", "สุริยุปราคา", "จันทรุปราคา", "ข้างขึ้น", "ข้างแรม",
|
| 170 |
+
"น้ำขึ้น", "น้ำลง", "บ่อน้ำ", "หนองน้ำ", "บึง", "คลอง", "เขื่อน",
|
| 171 |
+
"ถ้ำ", "หน้าผา", "หุบเขา", "ทะเลทราย", "ขั้วโลก", "ป่าชายเลน", "ป่าดงดิบ",
|
| 172 |
+
|
| 173 |
+
# 👨👩👧👦 อาชีพและบทบาท (More Careers)
|
| 174 |
+
"ประธานาธิบดี", "นายก", "ผู้ว่า", "กำนัน", "ผู้ใหญ่บ้าน", "นักการเมือง",
|
| 175 |
+
"นักธุรกิจ", "พนักงาน", "เลขา", "เจ้านาย", "ลูกน้อง",
|
| 176 |
+
"แม่บ้าน", "คนสวน", "คนขับรถ", "วินมอไซค์", "กระเป๋ารถเมล์", "แอร์โฮสเตส",
|
| 177 |
+
"กัปตัน", "นักบินอวกาศ", "นักวิทยาศาสตร์", "นักสืบ", "ทนาย", "อัยการ", "ผู้พิพากษา",
|
| 178 |
+
"ช่างไฟ", "ช่างประปา", "ช่างไม้", "ช่างปูน", "ช่างแอร์", "ช่างคอม", "ช่างภาพ",
|
| 179 |
+
"นักข่าว", "นักเขียน", "บรรณาธิการ", "ผู้กำกับ", "ดารา", "นายแบบ", "นางแบบ",
|
| 180 |
+
"นักกีฬา","กรรมการ", "เชียร์ลีดเดอร์", "ชาวประมง", "ชาวสวน", "ชาวไร่",
|
| 181 |
+
"หมอดู", "พระสงฆ์", "แม่ชี", "สามเณร", "บาทหลวง"
|
| 182 |
+
]
|
| 183 |
+
|
| 184 |
+
# --- SETUP ---
|
| 185 |
+
log = logging.getLogger('werkzeug')
|
| 186 |
+
log.setLevel(logging.ERROR)
|
| 187 |
+
app = Flask(__name__)
|
| 188 |
+
|
| 189 |
+
vocabulary = []
|
| 190 |
+
vocab_vectors = None
|
| 191 |
+
active_servers = {}
|
| 192 |
+
|
| 193 |
+
def initialize_system():
|
| 194 |
+
global vocabulary, vocab_vectors
|
| 195 |
+
print("------------------------------------------------")
|
| 196 |
+
print(f"🚀 System Initializing... (FastText TH Mode)")
|
| 197 |
+
|
| 198 |
+
if os.path.exists(VECTOR_FILE):
|
| 199 |
+
print(f"💾 Found {VECTOR_FILE}! Loading pre-computed data...")
|
| 200 |
+
try:
|
| 201 |
+
# โหลดไฟล์เข้า CPU
|
| 202 |
+
data = torch.load(VECTOR_FILE, map_location=torch.device('cpu'), weights_only=False)
|
| 203 |
+
|
| 204 |
+
vocabulary = data['vocabulary']
|
| 205 |
+
# แปลงเป็น FloatTensor และ Normalize เพื่อความเร็วแสง
|
| 206 |
+
vocab_vectors = data['vectors'].float()
|
| 207 |
+
vocab_vectors = F.normalize(vocab_vectors, p=2, dim=1)
|
| 208 |
+
|
| 209 |
+
print(f"✅ Loaded {len(vocabulary)} words and vectors instantly!")
|
| 210 |
+
except Exception as e:
|
| 211 |
+
print(f"❌ Error loading file: {e}")
|
| 212 |
+
raise e
|
| 213 |
+
else:
|
| 214 |
+
print(f"⚠️ {VECTOR_FILE} NOT FOUND! Please upload the file.")
|
| 215 |
+
return
|
| 216 |
+
|
| 217 |
+
threading.Thread(target=garbage_collector, daemon=True).start()
|
| 218 |
+
print("✅ SERVER READY! (Startup time: Ultra Fast!)")
|
| 219 |
+
print("------------------------------------------------")
|
| 220 |
+
|
| 221 |
+
def garbage_collector():
|
| 222 |
+
while True:
|
| 223 |
+
time.sleep(CLEANUP_INTERVAL)
|
| 224 |
+
try:
|
| 225 |
+
now = time.time()
|
| 226 |
+
to_delete = [sid for sid, data in active_servers.items() if now - data['last_active'] > MAX_IDLE_TIME]
|
| 227 |
+
for sid in to_delete:
|
| 228 |
+
del active_servers[sid]
|
| 229 |
+
if to_delete:
|
| 230 |
+
print(f"🧹 Cleaned up {len(to_delete)} inactive servers.", flush=True)
|
| 231 |
+
except Exception as e:
|
| 232 |
+
print(f"Error in cleanup: {e}", flush=True)
|
| 233 |
+
|
| 234 |
+
initialize_system()
|
| 235 |
+
|
| 236 |
+
@app.get("/")
|
| 237 |
+
def home():
|
| 238 |
+
return f"Contexto Thai (FastText) Server Running! Dict Size: {len(vocabulary)}"
|
| 239 |
+
|
| 240 |
+
@app.route('/new_game', methods=['POST'])
|
| 241 |
+
def start_new_game():
|
| 242 |
+
try:
|
| 243 |
+
data = request.json
|
| 244 |
+
server_id = data.get('server_id')
|
| 245 |
+
if not server_id: return jsonify({"error": "No server_id"}), 400
|
| 246 |
+
if not KIDS_WORDS:
|
| 247 |
+
return jsonify({"error": "KIDS_WORDS is empty in server script"}), 500
|
| 248 |
+
|
| 249 |
+
secret_word = random.choice(KIDS_WORDS)
|
| 250 |
+
|
| 251 |
+
try:
|
| 252 |
+
secret_index = vocabulary.index(secret_word)
|
| 253 |
+
except ValueError:
|
| 254 |
+
print(f"⚠️ คำลับ '{secret_word}' ไม่มีในดิกชันนารี (สุ่มใหม่)", flush=True)
|
| 255 |
+
secret_word = "หมา" # Fallback กันเหนียว
|
| 256 |
+
secret_index = vocabulary.index(secret_word)
|
| 257 |
+
|
| 258 |
+
secret_vec = vocab_vectors[secret_index].unsqueeze(0)
|
| 259 |
+
|
| 260 |
+
# คำนวณ Cosine Similarity ด้วย PyTorch ตรงๆ (เร็วปรี๊ดดด)
|
| 261 |
+
scores = F.cosine_similarity(secret_vec, vocab_vectors)
|
| 262 |
+
scores_list = scores.tolist()
|
| 263 |
+
|
| 264 |
+
pairs = []
|
| 265 |
+
for i in range(len(vocabulary)):
|
| 266 |
+
pairs.append((vocabulary[i], scores_list[i]))
|
| 267 |
+
|
| 268 |
+
pairs.sort(key=lambda x: x[1], reverse=True)
|
| 269 |
+
|
| 270 |
+
# ตัดคำลับ (ตัวเอง) ทิ้ง แล้วค่อยเรียงลิสต์
|
| 271 |
+
sorted_words = [p[0] for p in pairs if p[0] != secret_word]
|
| 272 |
+
# ยัดคำลับกลับไปที่อันดับ 0 (Rank 1) เสมอ
|
| 273 |
+
sorted_words.insert(0, secret_word)
|
| 274 |
+
|
| 275 |
+
active_servers[server_id] = {
|
| 276 |
+
"words": sorted_words,
|
| 277 |
+
"last_active": time.time()
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
print(f"🔥 GAME START: Server [{server_id}] | Secret: {secret_word}", flush=True)
|
| 281 |
+
return jsonify({"message": "OK", "server_id": server_id})
|
| 282 |
+
|
| 283 |
+
except Exception as e:
|
| 284 |
+
print(f"❌ ERROR: {e}", flush=True)
|
| 285 |
+
return jsonify({"error": str(e)}), 500
|
| 286 |
+
|
| 287 |
+
@app.route('/guess', methods=['POST'])
|
| 288 |
+
def guess_word():
|
| 289 |
+
try:
|
| 290 |
+
data = request.json
|
| 291 |
+
server_id = data.get('server_id')
|
| 292 |
+
guess = data.get('word', '').strip()
|
| 293 |
+
|
| 294 |
+
if server_id not in active_servers:
|
| 295 |
+
return jsonify({"error": "Server not found"}), 404
|
| 296 |
+
|
| 297 |
+
active_servers[server_id]['last_active'] = time.time()
|
| 298 |
+
ranked_list = active_servers[server_id]['words']
|
| 299 |
+
|
| 300 |
+
if guess == ranked_list[0]:
|
| 301 |
+
return jsonify({"rank": 1, "word": guess})
|
| 302 |
+
|
| 303 |
+
try:
|
| 304 |
+
rank = ranked_list.index(guess) + 1
|
| 305 |
+
return jsonify({"rank": rank, "word": guess})
|
| 306 |
+
except ValueError:
|
| 307 |
+
return jsonify({"rank": 99999, "word": guess})
|
| 308 |
+
|
| 309 |
+
except Exception as e:
|
| 310 |
+
return jsonify({"error": str(e)}), 500
|
| 311 |
+
|
| 312 |
+
@app.route('/hint', methods=['POST'])
|
| 313 |
+
def get_hint():
|
| 314 |
+
try:
|
| 315 |
+
data = request.json
|
| 316 |
+
server_id = data.get('server_id')
|
| 317 |
+
current_rank = data.get('current_rank')
|
| 318 |
+
|
| 319 |
+
if not server_id or server_id not in active_servers:
|
| 320 |
+
return jsonify({"error": "Game not found"}), 404
|
| 321 |
+
|
| 322 |
+
if current_rank is None:
|
| 323 |
+
return jsonify({"error": "current_rank is required"}), 400
|
| 324 |
+
|
| 325 |
+
current_rank = int(current_rank)
|
| 326 |
+
hint_rank = current_rank // 2
|
| 327 |
+
|
| 328 |
+
if hint_rank < 1:
|
| 329 |
+
hint_rank = 1
|
| 330 |
+
|
| 331 |
+
word_list = active_servers[server_id]['words']
|
| 332 |
+
|
| 333 |
+
if hint_rank > len(word_list):
|
| 334 |
+
hint_rank = len(word_list)
|
| 335 |
+
|
| 336 |
+
hint_word = word_list[hint_rank - 1]
|
| 337 |
+
|
| 338 |
+
return jsonify({"rank": hint_rank, "word": hint_word})
|
| 339 |
+
|
| 340 |
+
except Exception as e:
|
| 341 |
+
return jsonify({"error": str(e)}), 500
|
| 342 |
+
|
| 343 |
+
@app.route('/answer', methods=['POST'])
|
| 344 |
+
def get_answer():
|
| 345 |
+
try:
|
| 346 |
+
data = request.json
|
| 347 |
+
server_id = data.get('server_id')
|
| 348 |
+
|
| 349 |
+
if server_id not in active_servers:
|
| 350 |
+
return jsonify({"error": "Game not found"}), 404
|
| 351 |
+
|
| 352 |
+
answer = active_servers[server_id]['words'][0]
|
| 353 |
+
return jsonify({"answer": answer})
|
| 354 |
+
|
| 355 |
+
except Exception as e:
|
| 356 |
+
return jsonify({"error": str(e)}), 500
|
| 357 |
+
|
| 358 |
+
if __name__ == '__main__':
|
| 359 |
+
app.run(host='0.0.0.0', port=7860)
|