game 50 users 2.1
This commit is contained in:
+10
-7
@@ -2022,13 +2022,16 @@
|
||||
var QB_LABELS_ABC = ['A', 'B', 'C'];
|
||||
|
||||
var QUIZ_BATTLE_CATEGORIES = [
|
||||
{ id: 'cybercrime', labelTh: 'อาชญากรรมออนไลน์', labelEn: 'Cybercrime' },
|
||||
{ id: 'cyber_law', labelTh: 'กฎหมายไซเบอร์', labelEn: 'Cyber law' },
|
||||
{ id: 'privacy', labelTh: 'ความเป็นส่วนตัวและข้อมูลส่วนบุคคล', labelEn: 'Privacy & PDPA' },
|
||||
{ id: 'digital_security', labelTh: 'ความปลอดภัยดิจิทัล', labelEn: 'Digital security' },
|
||||
{ id: 'social_media', labelTh: 'สื่อสังคมออนไลน์', labelEn: 'Social media' },
|
||||
{ id: 'ethics', labelTh: 'จริยธรรมดิจิทัล', labelEn: 'Digital ethics' },
|
||||
{ id: 'ai_data', labelTh: 'AI และข้อมูล', labelEn: 'AI & data' },
|
||||
{ id: 'topic1', labelTh: 'ห้อง 1 — กฎหมายใกล้ตัว', labelEn: 'Room 1' },
|
||||
{ id: 'topic2', labelTh: 'ห้อง 2 — กฎหมายสิทธิ์พื้นฐาน', labelEn: 'Room 2' },
|
||||
{ id: 'topic3', labelTh: 'ห้อง 3 — กฎหมายจราจร', labelEn: 'Room 3' },
|
||||
{ id: 'topic4', labelTh: 'ห้อง 4 — คดีเกี่ยวกับทรัพย์', labelEn: 'Room 4' },
|
||||
{ id: 'topic5', labelTh: 'ห้อง 5 — คดีหมิ่นประมาท', labelEn: 'Room 5' },
|
||||
{ id: 'topic6', labelTh: 'ห้อง 6 — คดีทางเพศ', labelEn: 'Room 6' },
|
||||
{ id: 'topic7', labelTh: 'ห้อง 7 — คดีอาชญากรรม', labelEn: 'Room 7' },
|
||||
{ id: 'topic8', labelTh: 'ห้อง 8 — อาชญากรรมออนไลน์', labelEn: 'Room 8' },
|
||||
{ id: 'topic9', labelTh: 'ห้อง 9 — กระบวนการยุติธรรม', labelEn: 'Room 9' },
|
||||
{ id: 'topic10', labelTh: 'ห้อง 10 — งานบริการกระทรวงยุติธรรม', labelEn: 'Room 10' },
|
||||
];
|
||||
|
||||
function qbBattleCategoryLabel(catId) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -278,214 +278,504 @@
|
||||
],
|
||||
"battleQuizMcq": [
|
||||
{
|
||||
"categoryId": "cybercrime",
|
||||
"text": "การเข้าถึงระบบคอมพิวเตอร์ของผู้อื่นโดยไม่ได้รับอนุญาต ผิดกฎหมายใด?",
|
||||
"categoryId": "topic1",
|
||||
"text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"พ.ร.บ.จราจร",
|
||||
"พ.ร.บ.คอมพิวเตอร์",
|
||||
"กฎหมายแรงงาน"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "cybercrime",
|
||||
"text": "การหลอกให้เหยื่อโอนเงินผ่านเว็บ/ข้อความปลอม เรียกว่าอะไร?",
|
||||
"choices": [
|
||||
"Phishing",
|
||||
"Backup",
|
||||
"Caching"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "cybercrime",
|
||||
"text": "มัลแวร์ที่เข้ารหัสไฟล์แล้วเรียกค่าไถ่ คือ?",
|
||||
"categoryId": "topic1",
|
||||
"text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"Adware",
|
||||
"Ransomware",
|
||||
"Firewall"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "cyber_law",
|
||||
"text": "การนำเข้าข้อมูลเท็จสู่ระบบคอมพิวเตอร์ที่ทำให้ผู้อื่นเสียหาย มีโทษตามกฎหมายใด?",
|
||||
"categoryId": "topic1",
|
||||
"text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"พ.ร.บ.คอมพิวเตอร์",
|
||||
"พ.ร.บ.ลิขสิทธิ์",
|
||||
"ไม่มีความผิด"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "cyber_law",
|
||||
"text": "ข้อมูล log การเข้าใช้งานระบบ จัดเป็นพยานหลักฐานประเภทใด?",
|
||||
"choices": [
|
||||
"พยานบุคคล",
|
||||
"พยานเอกสารอิเล็กทรอนิกส์",
|
||||
"ไม่ถือเป็นหลักฐาน"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "cyber_law",
|
||||
"text": "ผู้ให้บริการต้องเก็บข้อมูลจราจรทางคอมพิวเตอร์ (log) อย่างน้อยกี่วันตาม พ.ร.บ.คอมพิวเตอร์?",
|
||||
"choices": [
|
||||
"7 วัน",
|
||||
"90 วัน",
|
||||
"1 ปี"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "privacy",
|
||||
"text": "กฎหมายคุ้มครองข้อมูลส่วนบุคคลของไทย เรียกย่อว่าอะไร?",
|
||||
"choices": [
|
||||
"PDPA",
|
||||
"GDPR",
|
||||
"DMCA"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "privacy",
|
||||
"text": "ก่อนเก็บข้อมูลส่วนบุคคล โดยทั่วไปต้องทำสิ่งใดก่อน?",
|
||||
"choices": [
|
||||
"ขอความยินยอม",
|
||||
"เผยแพร่ทันที",
|
||||
"ขายต่อ"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "privacy",
|
||||
"text": "ข้อใดเป็น “ข้อมูลส่วนบุคคลอ่อนไหว”?",
|
||||
"choices": [
|
||||
"ชื่อเล่น",
|
||||
"ข้อมูลสุขภาพ",
|
||||
"รหัสไปรษณีย์จังหวัด"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "digital_security",
|
||||
"text": "วิธีใดช่วยเพิ่มความปลอดภัยบัญชีได้ดีที่สุด?",
|
||||
"choices": [
|
||||
"ใช้รหัสผ่านเดียวทุกที่",
|
||||
"เปิดยืนยันตัวตน 2 ชั้น (2FA)",
|
||||
"จดรหัสไว้หน้าจอ"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "digital_security",
|
||||
"text": "รหัสผ่านแบบใดปลอดภัยที่สุด?",
|
||||
"choices": [
|
||||
"123456",
|
||||
"วันเกิดตัวเอง",
|
||||
"ยาว+ผสมอักขระหลายแบบ"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "digital_security",
|
||||
"text": "ควรทำอย่างไรเมื่อได้รับลิงก์แปลกจากคนไม่รู้จัก?",
|
||||
"categoryId": "topic1",
|
||||
"text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"กดทันที",
|
||||
"ไม่กดและตรวจสอบที่มา",
|
||||
"ส่งต่อให้เพื่อน"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "social_media",
|
||||
"text": "การโพสต์ข้อความหมิ่นประมาทผู้อื่นบนโซเชียล มีผลอย่างไร?",
|
||||
"choices": [
|
||||
"ไม่ผิดเพราะเป็นออนไลน์",
|
||||
"อาจมีความผิดทางกฎหมาย",
|
||||
"ผิดเฉพาะถ้าใช้ชื่อจริง"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "social_media",
|
||||
"text": "ก่อนแชร์ข่าว ควรทำสิ่งใด?",
|
||||
"choices": [
|
||||
"ตรวจสอบความถูกต้องของแหล่งข่าว",
|
||||
"แชร์ให้เร็วที่สุด",
|
||||
"แชร์เฉพาะพาดหัว"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "social_media",
|
||||
"text": "การตั้งค่าความเป็นส่วนตัวของโพสต์ช่วยเรื่องใด?",
|
||||
"categoryId": "topic1",
|
||||
"text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ควบคุมว่าใครเห็นได้",
|
||||
"เพิ่มความเร็วเน็ต",
|
||||
"ลบไวรัส"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic2",
|
||||
"text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "ethics",
|
||||
"text": "การคัดลอกผลงานผู้อื่นมาเป็นของตนเรียกว่าอะไร?",
|
||||
"categoryId": "topic2",
|
||||
"text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"การอ้างอิง",
|
||||
"การลอกเลียน (plagiarism)",
|
||||
"การสำรองข้อมูล"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "ethics",
|
||||
"text": "พฤติกรรมใดถือว่า “กลั่นแกล้งทางออนไลน์” (cyberbullying)?",
|
||||
"categoryId": "topic2",
|
||||
"text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ให้กำลังใจเพื่อน",
|
||||
"ส่งข้อความข่มขู่ซ้ำ ๆ",
|
||||
"กดไลก์รูปภาพ"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "ethics",
|
||||
"text": "การใช้ข้อมูลของผู้อื่นโดยไม่ขออนุญาตถือว่า?",
|
||||
"categoryId": "topic2",
|
||||
"text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ยอมรับได้เสมอ",
|
||||
"ไม่เหมาะสมและอาจผิดกฎหมาย",
|
||||
"เป็นมารยาทที่ดี"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "ai_data",
|
||||
"text": "ข้อมูลที่ใช้สอนโมเดล AI ควรมีลักษณะใด?",
|
||||
"choices": [
|
||||
"มีอคติมาก ๆ",
|
||||
"มีคุณภาพและได้รับอนุญาต",
|
||||
"ละเมิดลิขสิทธิ์ก็ได้"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "ai_data",
|
||||
"text": "ผลลัพธ์จาก AI ควรถูกตรวจสอบโดยใคร?",
|
||||
"choices": [
|
||||
"ไม่ต้องตรวจ",
|
||||
"มนุษย์ผู้รับผิดชอบ",
|
||||
"AI ตัวอื่นเท่านั้น"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "ai_data",
|
||||
"text": "Deepfake คือสิ่งใด?",
|
||||
"choices": [
|
||||
"สื่อปลอมที่สร้างด้วย AI",
|
||||
"โปรแกรมป้องกันไวรัส",
|
||||
"ระบบสำรองข้อมูล"
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic2",
|
||||
"text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic3",
|
||||
"text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic3",
|
||||
"text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic3",
|
||||
"text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic3",
|
||||
"text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic3",
|
||||
"text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic4",
|
||||
"text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic4",
|
||||
"text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic4",
|
||||
"text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic4",
|
||||
"text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic4",
|
||||
"text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic5",
|
||||
"text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic5",
|
||||
"text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic5",
|
||||
"text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic5",
|
||||
"text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic5",
|
||||
"text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic6",
|
||||
"text": "[คดีทางเพศ] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic6",
|
||||
"text": "[คดีทางเพศ] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic6",
|
||||
"text": "[คดีทางเพศ] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic6",
|
||||
"text": "[คดีทางเพศ] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic6",
|
||||
"text": "[คดีทางเพศ] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic7",
|
||||
"text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic7",
|
||||
"text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic7",
|
||||
"text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic7",
|
||||
"text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic7",
|
||||
"text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic8",
|
||||
"text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic8",
|
||||
"text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic8",
|
||||
"text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic8",
|
||||
"text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic8",
|
||||
"text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic9",
|
||||
"text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic9",
|
||||
"text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic9",
|
||||
"text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic9",
|
||||
"text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic9",
|
||||
"text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic10",
|
||||
"text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic10",
|
||||
"text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
},
|
||||
{
|
||||
"categoryId": "topic10",
|
||||
"text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 2
|
||||
},
|
||||
{
|
||||
"categoryId": "topic10",
|
||||
"text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 0
|
||||
},
|
||||
{
|
||||
"categoryId": "topic10",
|
||||
"text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)",
|
||||
"choices": [
|
||||
"ตัวเลือก ก",
|
||||
"ตัวเลือก ข",
|
||||
"ตัวเลือก ค"
|
||||
],
|
||||
"correctIndex": 1
|
||||
}
|
||||
],
|
||||
"specialQuizSets": {
|
||||
@@ -1990,4 +2280,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3048,6 +3048,7 @@
|
||||
let quizBattleMcqPool = [];
|
||||
let quizBattleAnsweredComps = new Set();
|
||||
let quizBattleModalCompId = null;
|
||||
let qbAutoLastComp = null; // โดมล่าสุดที่ trigger อัตโนมัติ (กันเด้งซ้ำขณะยืนค้าง)
|
||||
const SPACE_SHOOTER_SHIP_COLORS = ['#50fa7b', '#ff79c6', '#ff5555', '#f1fa8c', '#bd93f9', '#8be9fd'];
|
||||
|
||||
document.getElementById('room-id').textContent = spaceId;
|
||||
@@ -12811,6 +12812,86 @@
|
||||
hideQuizBattleMcqModal();
|
||||
}
|
||||
|
||||
/** หา comp โดมที่ตัวละครเหยียบอยู่ — เช็คหลายจุด (กลาง/เท้า/หัว/ซ้าย-ขวา) ให้เด้งง่ายเมื่อถึงสถานี */
|
||||
function quizBattleDomeAtMe() {
|
||||
if (!isQuizBattle()) return null;
|
||||
const pts = [[me.x, me.y], [me.x, me.y + 0.45], [me.x, me.y - 0.25], [me.x + 0.3, me.y], [me.x - 0.3, me.y]];
|
||||
for (let i = 0; i < pts.length; i++) {
|
||||
const c = getPrimaryQuizBattleDomeCompAt(pts[i][0], pts[i][1]);
|
||||
if (c != null) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** ZEP-style: เหยียบสถานี (โดม) ที่ยังไม่ตอบ → เปิดคำถามอัตโนมัติ (ครั้งเดียวต่อการเข้า · เดินออกแล้วกลับมาใหม่ถึงเด้งอีก) */
|
||||
function maybeAutoOpenQuizBattle() {
|
||||
if (!isQuizBattle() || myId == null) return;
|
||||
const compNow = quizBattleDomeAtMe();
|
||||
if (compNow == null) { qbAutoLastComp = null; return; }
|
||||
const ov = document.getElementById('quiz-battle-mcq-overlay');
|
||||
const modalOpen = quizBattleModalCompId != null || (ov && !ov.classList.contains('is-hidden'));
|
||||
if (modalOpen) return;
|
||||
if (compNow === qbAutoLastComp) return;
|
||||
qbAutoLastComp = compNow;
|
||||
if (quizBattleAnsweredComps.has(compNow)) return;
|
||||
const pool = quizBattleMcqPool;
|
||||
if (!pool.length) return;
|
||||
const q = pool[(compNow - 1) % pool.length];
|
||||
if (!q) return;
|
||||
quizBattleModalCompId = compNow;
|
||||
showQuizBattleMcqModal(q);
|
||||
}
|
||||
|
||||
function qbRoundRect(ctx, x, y, w, h, r) {
|
||||
r = Math.min(r, w / 2, h / 2);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.arcTo(x + w, y, x + w, y + h, r);
|
||||
ctx.arcTo(x + w, y + h, x, y + h, r);
|
||||
ctx.arcTo(x, y + h, x, y, r);
|
||||
ctx.arcTo(x, y, x + w, y, r);
|
||||
ctx.closePath();
|
||||
}
|
||||
/** หีบบนสถานีคำถาม — done=ปลดล็อก(เขียว+ติ๊ก) / ยังไม่ตอบ=ล็อก(น้ำตาล+กุญแจ) + เลขสถานี */
|
||||
function drawQuizBattleChest(ctx, cx, cy, size, done, num) {
|
||||
const w = size * 0.84, h = size * 0.64;
|
||||
const x0 = cx - w / 2, y0 = cy - h / 2;
|
||||
ctx.save();
|
||||
ctx.shadowColor = done ? 'rgba(52,211,153,0.95)' : 'rgba(255,200,70,0.95)';
|
||||
ctx.shadowBlur = Math.max(4, size * 0.3);
|
||||
ctx.fillStyle = done ? '#3f7d57' : '#8a5a2b';
|
||||
qbRoundRect(ctx, x0, y0 + h * 0.34, w, h * 0.66, size * 0.08); ctx.fill();
|
||||
ctx.fillStyle = done ? '#57a875' : '#a86f33';
|
||||
qbRoundRect(ctx, x0, y0, w, h * 0.44, size * 0.1); ctx.fill();
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.fillStyle = done ? '#d6f5e3' : '#f1c66a';
|
||||
ctx.fillRect(x0, y0 + h * 0.30, w, h * 0.10);
|
||||
ctx.fillRect(cx - size * 0.045, y0, size * 0.09, h);
|
||||
if (done) {
|
||||
ctx.strokeStyle = '#eafff3'; ctx.lineWidth = Math.max(2, size * 0.08); ctx.lineCap = 'round'; ctx.lineJoin = 'round';
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx - size * 0.13, cy + size * 0.04);
|
||||
ctx.lineTo(cx - size * 0.02, cy + size * 0.15);
|
||||
ctx.lineTo(cx + size * 0.17, cy - size * 0.12);
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.strokeStyle = '#f1c66a'; ctx.lineWidth = Math.max(2, size * 0.05);
|
||||
ctx.beginPath(); ctx.arc(cx, cy + h * 0.04, size * 0.085, Math.PI, 0); ctx.stroke();
|
||||
ctx.fillStyle = '#f1c66a';
|
||||
qbRoundRect(ctx, cx - size * 0.085, cy + h * 0.04, size * 0.17, size * 0.13, size * 0.03); ctx.fill();
|
||||
}
|
||||
if (num) {
|
||||
ctx.fillStyle = 'rgba(8,12,28,0.82)';
|
||||
ctx.beginPath(); ctx.arc(cx, y0 - size * 0.14, size * 0.17, 0, Math.PI * 2); ctx.fill();
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.font = 'bold ' + Math.max(9, size * 0.23) + 'px Kanit, sans-serif';
|
||||
ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
|
||||
ctx.fillText(String(num), cx, y0 - size * 0.14);
|
||||
ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function tryOpenQuizBattleFromKey() {
|
||||
if (!isQuizBattle() || !mapData || myId == null) return;
|
||||
const compId = getPrimaryQuizBattleDomeCompAt(me.x, me.y);
|
||||
@@ -12835,10 +12916,13 @@
|
||||
|
||||
function pushSanitizedBattleMcqFromPayload(s) {
|
||||
if (!s || !Array.isArray(s.battleQuizMcq)) return 0;
|
||||
/* กรองเฉพาะคลังคำถามของหัวข้อห้องนี้ (mapData.quizBattleCategoryId เช่น topic1..topic10) — ไม่ระบุ = ใช้ทั้งหมด */
|
||||
const roomCat = (mapData && mapData.quizBattleCategoryId) ? String(mapData.quizBattleCategoryId).trim() : '';
|
||||
let n = 0;
|
||||
for (let i = 0; i < s.battleQuizMcq.length; i++) {
|
||||
const raw = s.battleQuizMcq[i];
|
||||
if (!raw || !String(raw.text || '').trim()) continue;
|
||||
if (roomCat && String(raw.categoryId || '').trim() !== roomCat) continue;
|
||||
const ch = Array.isArray(raw.choices) ? raw.choices : [];
|
||||
if (ch.length !== 3) continue;
|
||||
const a = String(ch[0] || '').trim();
|
||||
@@ -19481,20 +19565,20 @@
|
||||
}
|
||||
}
|
||||
if (isQuizBattle() && showGrid && mapData.quizBattlePathArea && mapData.quizBattlePathArea[y] && mapData.quizBattlePathArea[y][x] === 1) {
|
||||
ctx.fillStyle = 'rgba(186, 130, 255, 0.4)';
|
||||
/* ไฮไลต์เส้นทางบาง ๆ (โชว์เฉพาะตอนเปิดกริด) ให้เห็นถนนจาก design ทะลุ */
|
||||
ctx.fillStyle = 'rgba(150, 195, 255, 0.12)';
|
||||
ctx.fillRect(sx + 1, sy + 1, size - 2, size - 2);
|
||||
ctx.strokeStyle = 'rgba(220, 170, 255, 0.55)';
|
||||
ctx.strokeRect(sx + 1, sy + 1, size - 2, size - 2);
|
||||
}
|
||||
if (isQuizBattle() && showGrid && mapData.quizBattleDomeArea && mapData.quizBattleDomeArea[y] && mapData.quizBattleDomeArea[y][x] === 1) {
|
||||
if (isQuizBattle() && mapData.quizBattleDomeArea && mapData.quizBattleDomeArea[y] && mapData.quizBattleDomeArea[y][x] === 1) {
|
||||
const cid = mapData.quizBattleDomeComp && mapData.quizBattleDomeComp[y] && mapData.quizBattleDomeComp[y][x];
|
||||
const done = cid > 0 && quizBattleAnsweredComps.has(cid);
|
||||
ctx.fillStyle = done ? 'rgba(90, 90, 110, 0.4)' : 'rgba(100, 200, 255, 0.36)';
|
||||
ctx.fillRect(sx + 2, sy + 2, size - 4, size - 4);
|
||||
ctx.strokeStyle = done ? 'rgba(140, 140, 160, 0.65)' : 'rgba(255, 100, 130, 0.82)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(sx + 2, sy + 2, size - 4, size - 4);
|
||||
ctx.lineWidth = 1;
|
||||
const comp = mapData.quizBattleDomeComp;
|
||||
/* วาดหีบครั้งเดียวต่อโดม (ช่องบน-ซ้ายสุดของกลุ่ม comp) — กันวาดซ้อน */
|
||||
const upSame = cid > 0 && comp && comp[y - 1] && comp[y - 1][x] === cid;
|
||||
const leftSame = cid > 0 && comp && comp[y] && comp[y][x - 1] === cid;
|
||||
if (!upSame && !leftSame) {
|
||||
const done = cid > 0 && quizBattleAnsweredComps.has(cid);
|
||||
drawQuizBattleChest(ctx, sx + size / 2, sy + size / 2, size, done, cid || 0);
|
||||
}
|
||||
}
|
||||
if (isStack()) {
|
||||
const sr = mapData.stackReleaseArea, sl = mapData.stackLandArea;
|
||||
@@ -20424,6 +20508,7 @@
|
||||
enforceQuizBattleLaneOnMePlay();
|
||||
const t = Date.now();
|
||||
if (t - lastSend > 80) { lastSend = t; socket.emit('move', { x: me.x, y: me.y, direction: me.direction }); }
|
||||
maybeAutoOpenQuizBattle();
|
||||
draw();
|
||||
requestAnimationFrame(tick);
|
||||
return;
|
||||
@@ -20491,6 +20576,7 @@
|
||||
me.isWalking = !!(accX !== 0 || accY !== 0) || playPath.length > 0 || movedThisTick;
|
||||
const now = Date.now();
|
||||
if (now - lastSend > 80) { lastSend = now; socket.emit('move', { x: me.x, y: me.y, direction: me.direction }); }
|
||||
maybeAutoOpenQuizBattle();
|
||||
draw();
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3974,7 +3974,7 @@
|
||||
<script src="/app-base.js?v=2"></script>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0306"></script>
|
||||
<script src="js/play.js?v=0.0520"></script>
|
||||
<script src="js/play.js?v=0.006071209"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6454,10 +6454,21 @@
|
||||
hideQuizBattleMcqModal();
|
||||
}
|
||||
|
||||
/** หา comp โดมที่ตัวละครเหยียบอยู่ — เช็คหลายจุด (กลาง/เท้า/หัว) ให้ติดง่ายเมื่อเดินถึงสถานี */
|
||||
function quizBattleDomeAtMe() {
|
||||
if (!isQuizBattle()) return null;
|
||||
const pts = [[me.x, me.y], [me.x, me.y + 0.45], [me.x, me.y - 0.25], [me.x + 0.3, me.y], [me.x - 0.3, me.y]];
|
||||
for (let i = 0; i < pts.length; i++) {
|
||||
const c = getPrimaryQuizBattleDomeCompAt(pts[i][0], pts[i][1]);
|
||||
if (c != null) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** ZEP-style: เดินถึงสถานี (โดม) ที่ยังไม่ตอบ → เปิดคำถามอัตโนมัติ (ครั้งเดียวต่อการเข้า · เดินออกแล้วกลับมาใหม่ถึงเด้งอีก) */
|
||||
function maybeAutoOpenQuizBattle() {
|
||||
if (!isQuizBattle() || myId == null) return;
|
||||
const compNow = getPrimaryQuizBattleDomeCompAt(me.x, me.y);
|
||||
const compNow = quizBattleDomeAtMe();
|
||||
if (compNow == null) { qbAutoLastComp = null; return; }
|
||||
const ov = document.getElementById('quiz-battle-mcq-overlay');
|
||||
const modalOpen = quizBattleModalCompId != null || (ov && !ov.classList.contains('is-hidden'));
|
||||
@@ -6473,6 +6484,56 @@
|
||||
showQuizBattleMcqModal(q);
|
||||
}
|
||||
|
||||
function qbRoundRect(ctx, x, y, w, h, r) {
|
||||
r = Math.min(r, w / 2, h / 2);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.arcTo(x + w, y, x + w, y + h, r);
|
||||
ctx.arcTo(x + w, y + h, x, y + h, r);
|
||||
ctx.arcTo(x, y + h, x, y, r);
|
||||
ctx.arcTo(x, y, x + w, y, r);
|
||||
ctx.closePath();
|
||||
}
|
||||
/** วาดหีบสมบัติบนสถานีคำถาม — done=ปลดล็อก (เขียว+ติ๊กถูก) / ยังไม่ตอบ=ล็อก (น้ำตาล+กุญแจ) + เลขสถานี */
|
||||
function drawQuizBattleChest(ctx, cx, cy, size, done, num) {
|
||||
const w = size * 0.84, h = size * 0.64;
|
||||
const x0 = cx - w / 2, y0 = cy - h / 2;
|
||||
ctx.save();
|
||||
ctx.shadowColor = done ? 'rgba(52,211,153,0.95)' : 'rgba(255,200,70,0.95)';
|
||||
ctx.shadowBlur = Math.max(4, size * 0.3);
|
||||
ctx.fillStyle = done ? '#3f7d57' : '#8a5a2b';
|
||||
qbRoundRect(ctx, x0, y0 + h * 0.34, w, h * 0.66, size * 0.08); ctx.fill();
|
||||
ctx.fillStyle = done ? '#57a875' : '#a86f33';
|
||||
qbRoundRect(ctx, x0, y0, w, h * 0.44, size * 0.1); ctx.fill();
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.fillStyle = done ? '#d6f5e3' : '#f1c66a';
|
||||
ctx.fillRect(x0, y0 + h * 0.30, w, h * 0.10);
|
||||
ctx.fillRect(cx - size * 0.045, y0, size * 0.09, h);
|
||||
if (done) {
|
||||
ctx.strokeStyle = '#eafff3'; ctx.lineWidth = Math.max(2, size * 0.08); ctx.lineCap = 'round'; ctx.lineJoin = 'round';
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx - size * 0.13, cy + size * 0.04);
|
||||
ctx.lineTo(cx - size * 0.02, cy + size * 0.15);
|
||||
ctx.lineTo(cx + size * 0.17, cy - size * 0.12);
|
||||
ctx.stroke();
|
||||
} else {
|
||||
ctx.strokeStyle = '#f1c66a'; ctx.lineWidth = Math.max(2, size * 0.05);
|
||||
ctx.beginPath(); ctx.arc(cx, cy + h * 0.04, size * 0.085, Math.PI, 0); ctx.stroke();
|
||||
ctx.fillStyle = '#f1c66a';
|
||||
qbRoundRect(ctx, cx - size * 0.085, cy + h * 0.04, size * 0.17, size * 0.13, size * 0.03); ctx.fill();
|
||||
}
|
||||
if (num) {
|
||||
ctx.fillStyle = 'rgba(8,12,28,0.82)';
|
||||
ctx.beginPath(); ctx.arc(cx, y0 - size * 0.14, size * 0.17, 0, Math.PI * 2); ctx.fill();
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.font = 'bold ' + Math.max(9, size * 0.23) + 'px Kanit, sans-serif';
|
||||
ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
|
||||
ctx.fillText(String(num), cx, y0 - size * 0.14);
|
||||
ctx.textAlign = 'left'; ctx.textBaseline = 'alphabetic';
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function tryOpenQuizBattleFromKey() {
|
||||
if (!isQuizBattle() || !mapData || myId == null) return;
|
||||
const compId = getPrimaryQuizBattleDomeCompAt(me.x, me.y);
|
||||
@@ -6497,10 +6558,13 @@
|
||||
|
||||
function pushSanitizedBattleMcqFromPayload(s) {
|
||||
if (!s || !Array.isArray(s.battleQuizMcq)) return 0;
|
||||
/* กรองเฉพาะคลังคำถามของหัวข้อห้องนี้ (mapData.quizBattleCategoryId เช่น topic1..topic10) — ถ้าไม่ระบุ ใช้ทั้งหมด */
|
||||
const roomCat = (mapData && mapData.quizBattleCategoryId) ? String(mapData.quizBattleCategoryId).trim() : '';
|
||||
let n = 0;
|
||||
for (let i = 0; i < s.battleQuizMcq.length; i++) {
|
||||
const raw = s.battleQuizMcq[i];
|
||||
if (!raw || !String(raw.text || '').trim()) continue;
|
||||
if (roomCat && String(raw.categoryId || '').trim() !== roomCat) continue;
|
||||
const ch = Array.isArray(raw.choices) ? raw.choices : [];
|
||||
if (ch.length !== 3) continue;
|
||||
const a = String(ch[0] || '').trim();
|
||||
@@ -10884,20 +10948,20 @@
|
||||
}
|
||||
}
|
||||
if (isQuizBattle() && showGrid && mapData.quizBattlePathArea && mapData.quizBattlePathArea[y] && mapData.quizBattlePathArea[y][x] === 1) {
|
||||
ctx.fillStyle = 'rgba(186, 130, 255, 0.4)';
|
||||
/* ไฮไลต์เส้นทางบาง ๆ (โชว์เฉพาะตอนเปิดกริด) — ให้เห็นถนนจาก design ทะลุได้ */
|
||||
ctx.fillStyle = 'rgba(150, 195, 255, 0.12)';
|
||||
ctx.fillRect(sx + 1, sy + 1, size - 2, size - 2);
|
||||
ctx.strokeStyle = 'rgba(220, 170, 255, 0.55)';
|
||||
ctx.strokeRect(sx + 1, sy + 1, size - 2, size - 2);
|
||||
}
|
||||
if (isQuizBattle() && showGrid && mapData.quizBattleDomeArea && mapData.quizBattleDomeArea[y] && mapData.quizBattleDomeArea[y][x] === 1) {
|
||||
if (isQuizBattle() && mapData.quizBattleDomeArea && mapData.quizBattleDomeArea[y] && mapData.quizBattleDomeArea[y][x] === 1) {
|
||||
const cid = mapData.quizBattleDomeComp && mapData.quizBattleDomeComp[y] && mapData.quizBattleDomeComp[y][x];
|
||||
const done = cid > 0 && quizBattleAnsweredComps.has(cid);
|
||||
ctx.fillStyle = done ? 'rgba(90, 90, 110, 0.4)' : 'rgba(100, 200, 255, 0.36)';
|
||||
ctx.fillRect(sx + 2, sy + 2, size - 4, size - 4);
|
||||
ctx.strokeStyle = done ? 'rgba(140, 140, 160, 0.65)' : 'rgba(255, 100, 130, 0.82)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(sx + 2, sy + 2, size - 4, size - 4);
|
||||
ctx.lineWidth = 1;
|
||||
const comp = mapData.quizBattleDomeComp;
|
||||
/* วาดหีบครั้งเดียวต่อโดม (ช่องบน-ซ้ายสุดของกลุ่ม comp) — กันวาดซ้อนเมื่อโดมหลายช่อง */
|
||||
const upSame = cid > 0 && comp && comp[y - 1] && comp[y - 1][x] === cid;
|
||||
const leftSame = cid > 0 && comp && comp[y] && comp[y][x - 1] === cid;
|
||||
if (!upSame && !leftSame) {
|
||||
const done = cid > 0 && quizBattleAnsweredComps.has(cid);
|
||||
drawQuizBattleChest(ctx, sx + size / 2, sy + size / 2, size, done, cid || 0);
|
||||
}
|
||||
}
|
||||
if (isStack()) {
|
||||
const sr = mapData.stackReleaseArea, sl = mapData.stackLandArea;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1031,13 +1031,8 @@ function sanitizeCarryEmbedCountdownTheme(raw) {
|
||||
|
||||
/** หมวด Quiz Battle (อ้างอิงธีมหน้า Quiz-Battle) — id ต้องตรงกับแอดมิน */
|
||||
const QUIZ_BATTLE_CATEGORY_IDS = new Set([
|
||||
'cybercrime',
|
||||
'cyber_law',
|
||||
'privacy',
|
||||
'digital_security',
|
||||
'social_media',
|
||||
'ethics',
|
||||
'ai_data',
|
||||
'topic1', 'topic2', 'topic3', 'topic4', 'topic5',
|
||||
'topic6', 'topic7', 'topic8', 'topic9', 'topic10',
|
||||
]);
|
||||
|
||||
/** คำถาม 3 ตัวเลือก A/B/C แยกหมวด — สำหรับโหมด Quiz Battle / โดม */
|
||||
@@ -1048,7 +1043,7 @@ function sanitizeBattleQuizMcq(arr) {
|
||||
if (!q || typeof q !== 'object') continue;
|
||||
let categoryId = String(q.categoryId || '').trim();
|
||||
if (!categoryId || !QUIZ_BATTLE_CATEGORY_IDS.has(categoryId)) {
|
||||
categoryId = 'cybercrime';
|
||||
categoryId = 'topic1';
|
||||
}
|
||||
const text = String(q.text || '').trim().slice(0, 500);
|
||||
if (!text) continue;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user