diff --git a/www/html/Admin/admin.css b/www/html/Admin/admin.css index e3c8c05..e9682a3 100644 --- a/www/html/Admin/admin.css +++ b/www/html/Admin/admin.css @@ -2007,6 +2007,10 @@ code { flex-direction: column; gap: 0.65rem; } +/* ตัวกรองหมวด: ซ่อนแถวที่ไม่ตรงหมวด (display:flex ด้านบนทับ [hidden] ของ UA ต้อง override) */ +.qb-battle-block[hidden] { + display: none !important; +} .qb-battle-block-head { display: flex; diff --git a/www/html/Admin/admin.js b/www/html/Admin/admin.js index 6272f8c..e7927d9 100644 --- a/www/html/Admin/admin.js +++ b/www/html/Admin/admin.js @@ -2108,7 +2108,7 @@ } } return { - categoryId: catSel && catSel.value ? catSel.value : 'cybercrime', + categoryId: catSel && catSel.value ? catSel.value : 'topic1', text: qInp && qInp.value ? String(qInp.value).trim() : '', choices: [ a0 && a0.value ? String(a0.value).trim() : '', @@ -2141,7 +2141,7 @@ 'การใช้ WI-FI สาธารณะเพื่อดูข่าว', 'การอัปเดตซอฟต์แวร์เพื่อความปลอดภัย', ]; - hudCat.textContent = d ? qbBattleCategoryLabel(d.categoryId) : qbBattleCategoryLabel('cybercrime'); + hudCat.textContent = d ? qbBattleCategoryLabel(d.categoryId) : qbBattleCategoryLabel('topic1'); qtext.textContent = d && d.text ? d.text : defQ; var ch = d ? d.choices : defC; for (var s = 0; s < 3; s++) { @@ -2191,7 +2191,7 @@ var uid = 'r' + Math.random().toString(36).slice(2, 10); var block = document.createElement('div'); block.className = 'qb-battle-block'; - block.setAttribute('data-category', q.categoryId || 'cybercrime'); + block.setAttribute('data-category', q.categoryId || 'topic1'); var head = document.createElement('div'); head.className = 'qb-battle-block-head'; @@ -2205,7 +2205,7 @@ var o = document.createElement('option'); o.value = c.id; o.textContent = c.labelTh; - if ((q.categoryId || 'cybercrime') === c.id) o.selected = true; + if ((q.categoryId || 'topic1') === c.id) o.selected = true; selCat.appendChild(o); }); selCat.addEventListener('change', function () { diff --git a/www/html/Game/data/quiz-battle-leaderboard.json b/www/html/Game/data/quiz-battle-leaderboard.json new file mode 100644 index 0000000..f22a9f3 --- /dev/null +++ b/www/html/Game/data/quiz-battle-leaderboard.json @@ -0,0 +1 @@ +{"qbroom1":[{"name":"ผู้เล่น8916","score":4,"characterId":"char-1777017632279","ts":1781074083031},{"name":"ผู้เล่น2821","score":4,"characterId":"char-1777017632279","ts":1781079179108},{"name":"Q","score":0,"characterId":"char-1777017632279","ts":1781082837883}],"qbroom2":[{"name":"ผู้เล่น2612","score":1,"characterId":"char-1777017632279","ts":1781079252376}]} \ No newline at end of file diff --git a/www/html/Game/data/quiz-settings.json b/www/html/Game/data/quiz-settings.json index cb09517..2622cdd 100644 --- a/www/html/Game/data/quiz-settings.json +++ b/www/html/Game/data/quiz-settings.json @@ -279,501 +279,2001 @@ "battleQuizMcq": [ { "categoryId": "topic1", - "text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "อายุที่บรรลุนิติภาวะตามกฎหมายไทยคือกี่ปี?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "20 ปีบริบูรณ์", + "18 ปี", + "15 ปี" ], "correctIndex": 0 }, { "categoryId": "topic1", - "text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "การทำบัตรประชาชนครั้งแรกต้องทำเมื่ออายุเท่าใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "10 ปี", + "7 ปี", + "15 ปี" ], "correctIndex": 1 }, { "categoryId": "topic1", - "text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "เอกสารใดใช้เป็นหลักฐานแสดงตนตามกฎหมาย?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "บัตรสมาชิกห้าง", + "บัตรนักเรียนเก่า", + "บัตรประจำตัวประชาชน" ], "correctIndex": 2 }, { "categoryId": "topic1", - "text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "การหมั้นตามกฎหมายไทย ฝ่ายชายต้องมอบสิ่งใดให้ฝ่ายหญิง?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ของหมั้น", + "ค่าปรับ", + "ภาษี" ], "correctIndex": 0 }, { "categoryId": "topic1", - "text": "[กฎหมายใกล้ตัว] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "พินัยกรรมคือเอกสารแสดงเจตนาเกี่ยวกับสิ่งใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "การกู้เงิน", + "การจัดการทรัพย์สินหลังเสียชีวิต", + "การเช่าบ้าน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic1", + "text": "การจดทะเบียนสมรสทำได้ที่ใด?", + "choices": [ + "ธนาคาร", + "โรงพยาบาล", + "ที่ว่าการอำเภอหรือสำนักงานเขต" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic1", + "text": "ทำไมสัญญาเช่าบ้านจึงควรทำเป็นลายลักษณ์อักษร?", + "choices": [ + "เป็นหลักฐานป้องกันข้อพิพาท", + "เพื่อเสียภาษีมากขึ้น", + "เพื่อความสวยงาม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic1", + "text": "หากเก็บเงินที่ผู้อื่นทำหล่นได้ ควรทำอย่างไรตามกฎหมาย?", + "choices": [ + "เก็บไว้เป็นของตน", + "ส่งคืนเจ้าของหรือแจ้งตำรวจ", + "ทิ้งไป" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic1", + "text": "การกู้ยืมเงินเกินกว่าเท่าใดควรมีหลักฐานเป็นหนังสือจึงฟ้องร้องได้?", + "choices": [ + "50 บาท", + "1 ล้านบาท", + "2,000 บาท" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic1", + "text": "ดอกเบี้ยเงินกู้ระหว่างบุคคลตามกฎหมายห้ามเกินร้อยละเท่าใดต่อปี?", + "choices": [ + "ร้อยละ 15", + "ร้อยละ 50", + "ร้อยละ 100" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic1", + "text": "การรับบุตรบุญธรรมต้องจดทะเบียนที่ใด?", + "choices": [ + "ศาล", + "ที่ว่าการอำเภอหรือสำนักงานเขต", + "สถานีตำรวจ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic1", + "text": "เมื่อซื้อสินค้าชำรุด ผู้บริโภคมีสิทธิทำสิ่งใด?", + "choices": [ + "ทำอะไรไม่ได้เลย", + "ต้องจ่ายเงินเพิ่ม", + "ขอเปลี่ยนหรือคืนตามเงื่อนไข" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic1", + "text": "การเซ็นค้ำประกันเงินกู้ให้ผู้อื่นหมายความว่าอย่างไร?", + "choices": [ + "ต้องรับผิดชอบหนี้หากลูกหนี้ไม่ชำระ", + "ได้รับเงินฟรี", + "ไม่มีผลผูกพันใด" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic1", + "text": "เอกสารสิทธิ์ที่ดินที่มีกรรมสิทธิ์สมบูรณ์ที่สุดคือ?", + "choices": [ + "ใบจอง", + "โฉนดที่ดิน (น.ส.4)", + "ส.ป.ก." + ], + "correctIndex": 1 + }, + { + "categoryId": "topic1", + "text": "การแจ้งเกิดเด็กต้องแจ้งภายในกี่วัน?", + "choices": [ + "ภายใน 1 ปี", + "ภายใน 90 วัน", + "ภายใน 15 วัน" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic1", + "text": "หากถูกละเมิดสิทธิผู้บริโภค ร้องเรียนได้ที่หน่วยงานใด?", + "choices": [ + "สำนักงานคุ้มครองผู้บริโภค (สคบ.)", + "กรมศุลกากร", + "กรมป่าไม้" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic1", + "text": "การทำสัญญาที่เกิดจากการถูกข่มขู่ มีผลอย่างไร?", + "choices": [ + "สมบูรณ์เสมอ", + "เป็นโมฆียะ (บอกล้างได้)", + "ผิดอาญาทันที" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic1", + "text": "บุคคลใดทำนิติกรรมเองไม่ได้ ต้องมีผู้แทนโดยชอบธรรม?", + "choices": [ + "ผู้ใหญ่ทั่วไป", + "ข้าราชการ", + "ผู้เยาว์" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic1", + "text": "การเช่าซื้อรถยนต์ กรรมสิทธิ์จะเป็นของผู้เช่าซื้อเมื่อใด?", + "choices": [ + "เมื่อชำระค่างวดครบตามสัญญา", + "ทันทีที่รับรถ", + "ไม่มีวันเป็นของผู้เช่าซื้อ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic1", + "text": "หนังสือมอบอำนาจใช้เพื่อสิ่งใด?", + "choices": [ + "ยกทรัพย์ให้ฟรี", + "ให้ผู้อื่นทำการแทนตามที่ระบุ", + "จ่ายภาษีแทน" ], "correctIndex": 1 }, { "categoryId": "topic2", - "text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "สิทธิเสรีภาพขั้นพื้นฐานของประชาชนได้รับการรับรองในกฎหมายใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "รัฐธรรมนูญ", + "กฎกระทรวง", + "ประกาศของห้าง" ], "correctIndex": 0 }, { "categoryId": "topic2", - "text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "สิทธิในการเลือกตั้งระดับชาติ เริ่มเมื่ออายุเท่าใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "15 ปี", + "18 ปี", + "25 ปี" ], "correctIndex": 1 }, { "categoryId": "topic2", - "text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "หลัก \"บุคคลย่อมเสมอกันตามกฎหมาย\" หมายถึงสิ่งใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "คนรวยมีสิทธิมากกว่า", + "ผู้ชายเหนือกว่าผู้หญิง", + "ได้รับการคุ้มครองอย่างเท่าเทียม" ], "correctIndex": 2 }, { "categoryId": "topic2", - "text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "เสรีภาพในการนับถือศาสนา หมายความว่าอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "เลือกนับถือศาสนาใดก็ได้", + "ต้องนับถือศาสนาเดียวเท่านั้น", + "ห้ามนับถือศาสนา" ], "correctIndex": 0 }, { "categoryId": "topic2", - "text": "[กฎหมายสิทธิ์พื้นฐาน] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "รัฐจัดการศึกษาขั้นพื้นฐานให้ฟรีกี่ปี?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "5 ปี", + "15 ปี", + "3 ปี" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic2", + "text": "การถูกจับกุมโดยไม่มีหมายและไม่มีเหตุตามกฎหมาย ละเมิดสิ่งใด?", + "choices": [ + "สิทธิในทรัพย์สิน", + "ลิขสิทธิ์", + "สิทธิเสรีภาพในร่างกาย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic2", + "text": "เสรีภาพในการแสดงความคิดเห็นมีขอบเขตอย่างไร?", + "choices": [ + "ต้องไม่ละเมิดสิทธิผู้อื่นหรือผิดกฎหมาย", + "ทำอะไรก็ได้ไม่จำกัด", + "ห้ามพูดทุกอย่าง" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic2", + "text": "สิทธิของผู้ต้องหาในคดีอาญาข้อใดถูกต้อง?", + "choices": [ + "ต้องถือว่าผิดทันที", + "ได้รับการสันนิษฐานว่าบริสุทธิ์จนกว่าจะพิสูจน์ได้", + "ห้ามมีทนายความ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic2", + "text": "การเข้าถึงข้อมูลข่าวสารของราชการเป็นสิทธิตามกฎหมายใด?", + "choices": [ + "กฎจราจร", + "กฎหมายแพ่ง", + "พ.ร.บ.ข้อมูลข่าวสารของราชการ" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic2", + "text": "สิทธิความเป็นส่วนตัว (privacy) คุ้มครองสิ่งใด?", + "choices": [ + "ข้อมูลส่วนบุคคลและชีวิตส่วนตัว", + "ทรัพย์สินสาธารณะ", + "ที่ดินของรัฐ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic2", + "text": "ผู้พิการมีสิทธิได้รับสิ่งใดจากรัฐ?", + "choices": [ + "ไม่มีสิทธิใด ๆ", + "สิ่งอำนวยความสะดวกและสวัสดิการ", + "เสียภาษีเพิ่ม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic2", + "text": "เด็กมีสิทธิพื้นฐานข้อใด?", + "choices": [ + "ทำงานหนักเท่าผู้ใหญ่", + "ไม่มีสิทธิใด ๆ", + "ได้รับการเลี้ยงดูและการศึกษา" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic2", + "text": "เสรีภาพในการชุมนุมต้องเป็นไปอย่างไร?", + "choices": [ + "โดยสงบและปราศจากอาวุธ", + "ใช้อาวุธได้", + "ทำลายทรัพย์สินได้" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic2", + "text": "สิทธิได้รับการพิจารณาคดีอย่างเป็นธรรมเรียกว่าอะไร?", + "choices": [ + "สิทธิในการหลบหนี", + "สิทธิในกระบวนการยุติธรรมที่เป็นธรรม", + "สิทธิในการติดสินบน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic2", + "text": "การเลือกปฏิบัติเพราะเพศ เชื้อชาติ หรือศาสนา กฎหมายมองว่าอย่างไร?", + "choices": [ + "ทำได้อย่างเสรี", + "ควรส่งเสริม", + "ต้องห้ามและผิดกฎหมาย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic2", + "text": "หน่วยงานใดมีหน้าที่คุ้มครองสิทธิมนุษยชนในไทย?", + "choices": [ + "คณะกรรมการสิทธิมนุษยชนแห่งชาติ", + "กรมที่ดิน", + "การไฟฟ้า" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic2", + "text": "สิทธิแรงงานข้อใดถูกต้อง?", + "choices": [ + "ต้องทำงานฟรี", + "ได้รับค่าจ้างขั้นต่ำตามกฎหมาย", + "ห้ามหยุดพัก" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic2", + "text": "PDPA เป็นกฎหมายที่คุ้มครองสิ่งใด?", + "choices": [ + "ที่ดิน", + "รถยนต์", + "ข้อมูลส่วนบุคคล" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic2", + "text": "สิทธิในการรักษาพยาบาลขั้นพื้นฐานของคนไทยเรียกว่าอะไร?", + "choices": [ + "หลักประกันสุขภาพถ้วนหน้า (บัตรทอง)", + "ประกันรถยนต์", + "ภาษีมูลค่าเพิ่ม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic2", + "text": "การกระทำใดถือเป็นการละเมิดสิทธิมนุษยชน?", + "choices": [ + "การไปใช้สิทธิเลือกตั้ง", + "การบังคับใช้แรงงานเด็กโดยไม่เต็มใจ", + "การแสดงความคิดเห็นอย่างสุภาพ" ], "correctIndex": 1 }, { "categoryId": "topic3", - "text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "ผู้ขับขี่รถจักรยานยนต์ต้องสวมสิ่งใดทุกครั้ง?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "หมวกนิรภัย", + "แว่นกันแดด", + "ถุงมือ" ], "correctIndex": 0 }, { "categoryId": "topic3", - "text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "สัญญาณไฟจราจรสีแดงหมายถึงอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ให้ไปได้", + "ให้หยุด", + "ให้เตรียมตัว" ], "correctIndex": 1 }, { "categoryId": "topic3", - "text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การขับรถขณะเมาสุรา ระดับแอลกอฮอล์ในเลือดห้ามเกินเท่าใด (ผู้ขับทั่วไป)?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "200 มิลลิกรัมเปอร์เซ็นต์", + "ไม่จำกัด", + "50 มิลลิกรัมเปอร์เซ็นต์" ], "correctIndex": 2 }, { "categoryId": "topic3", - "text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "ใบอนุญาตขับรถยนต์ส่วนบุคคลครั้งแรกออกให้ผู้มีอายุอย่างน้อยกี่ปี?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "18 ปี", + "15 ปี", + "12 ปี" ], "correctIndex": 0 }, { "categoryId": "topic3", - "text": "[กฎหมายจราจร] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "การคาดเข็มขัดนิรภัยมีไว้เพื่อสิ่งใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "เพิ่มความเร็วรถ", + "ลดการบาดเจ็บเมื่อเกิดอุบัติเหตุ", + "ประหยัดน้ำมัน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic3", + "text": "เมื่อถึงทางม้าลายที่มีคนกำลังข้าม ผู้ขับขี่ควรทำอย่างไร?", + "choices": [ + "เร่งความเร็วผ่านไป", + "บีบแตรไล่", + "ชะลอและหยุดให้คนข้าม" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic3", + "text": "การใช้โทรศัพท์มือถือขณะขับรถโดยไม่มีอุปกรณ์เสริม มีผลอย่างไร?", + "choices": [ + "ผิดกฎจราจร", + "ถูกต้องตามกฎหมาย", + "ได้คะแนนสะสม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic3", + "text": "สัญญาณไฟเลี้ยวใช้เพื่อสิ่งใด?", + "choices": [ + "ประดับรถให้สวย", + "บอกทิศทางแก่ผู้ร่วมทาง", + "ไล่แมลง" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic3", + "text": "เมื่อรถพยาบาลเปิดสัญญาณไซเรนมา ผู้ขับขี่ควรทำอย่างไร?", + "choices": [ + "ขับขวางไว้", + "เร่งแซงขึ้นหน้า", + "หลีกทางให้" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic3", + "text": "การจอดรถในที่ห้ามจอดมีผลอย่างไร?", + "choices": [ + "ถูกปรับหรือล็อกล้อ", + "ได้รับรางวัล", + "ไม่มีผลใด ๆ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic3", + "text": "ป้ายจราจรวงกลมขอบแดงพื้นขาวโดยทั่วไปหมายถึงอะไร?", + "choices": [ + "ป้ายแนะนำ", + "ป้ายบังคับหรือห้าม", + "ป้ายโฆษณา" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic3", + "text": "การขับรถย้อนศรเป็นการกระทำอย่างไร?", + "choices": [ + "ปลอดภัยดี", + "ควรส่งเสริม", + "ผิดกฎหมายและอันตราย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic3", + "text": "หากเกิดอุบัติเหตุมีผู้บาดเจ็บ ผู้ขับขี่ควรทำสิ่งใดก่อน?", + "choices": [ + "ช่วยเหลือผู้บาดเจ็บและแจ้งเหตุ", + "รีบหลบหนี", + "ลบหลักฐาน" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic3", + "text": "การชนแล้วหนีหลังก่ออุบัติเหตุ มีผลอย่างไร?", + "choices": [ + "ไม่มีความผิด", + "มีความผิดตามกฎหมาย", + "ได้รับการลดโทษ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic3", + "text": "เด็กเล็กควรนั่งรถยนต์อย่างไรให้ปลอดภัย?", + "choices": [ + "นั่งบนตักคนขับ", + "ยืนหน้ารถ", + "ใช้ที่นั่งนิรภัยสำหรับเด็ก (คาร์ซีท)" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic3", + "text": "การบรรทุกเกินพิกัดน้ำหนักมีผลอย่างไร?", + "choices": [ + "ผิดกฎหมายและเสี่ยงอุบัติเหตุ", + "ปลอดภัยมากขึ้น", + "ประหยัดเวลา" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic3", + "text": "การขับรถเร็วเกินกว่ากฎหมายกำหนดมีผลอย่างไร?", + "choices": [ + "ได้รับรางวัล", + "ถูกปรับและเสี่ยงอันตราย", + "ไม่ผิดกฎหมาย" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic3", + "text": "การแซงรถควรทำเมื่อใด?", + "choices": [ + "ในทางโค้ง", + "บนสะพาน", + "เมื่อปลอดภัยและทัศนวิสัยดี" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic3", + "text": "พ.ร.บ. (ประกันภัยรถภาคบังคับ) มีไว้เพื่อสิ่งใด?", + "choices": [ + "คุ้มครองผู้ประสบภัยจากรถ", + "ตกแต่งรถ", + "ลดภาษีบ้าน" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic3", + "text": "การเปิดไฟหน้ารถในเวลากลางคืนมีไว้เพื่ออะไร?", + "choices": [ + "เพิ่มความเร็ว", + "เพิ่มการมองเห็นและความปลอดภัย", + "ประหยัดแบตเตอรี่" ], "correctIndex": 1 }, { "categoryId": "topic4", - "text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "การเอาทรัพย์ของผู้อื่นไปโดยทุจริตเรียกว่าความผิดฐานใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ลักทรัพย์", + "หมิ่นประมาท", + "บุกรุก" ], "correctIndex": 0 }, { "categoryId": "topic4", - "text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "การลักทรัพย์โดยใช้กำลังประทุษร้ายหรือขู่เข็ญเรียกว่าอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ยักยอกทรัพย์", + "ชิงทรัพย์", + "ฉ้อโกง" ], "correctIndex": 1 }, { "categoryId": "topic4", - "text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การชิงทรัพย์โดยมีผู้ร่วมตั้งแต่สามคนขึ้นไปเรียกว่าอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ลักทรัพย์", + "รับของโจร", + "ปล้นทรัพย์" ], "correctIndex": 2 }, { "categoryId": "topic4", - "text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "การหลอกลวงให้ผู้อื่นมอบทรัพย์ให้เรียกว่าความผิดฐานใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ฉ้อโกง", + "ลักทรัพย์", + "ทำร้ายร่างกาย" ], "correctIndex": 0 }, { "categoryId": "topic4", - "text": "[คดีเกี่ยวกับทรัพย์] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "ผู้ได้รับมอบหมายให้ดูแลทรัพย์แล้วเบียดบังเอาเป็นของตนเรียกว่าอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ชิงทรัพย์", + "ยักยอกทรัพย์", + "ปล้นทรัพย์" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic4", + "text": "การซื้อหรือรับทรัพย์ที่รู้ว่าได้มาจากการกระทำผิดเรียกว่าอะไร?", + "choices": [ + "ลักทรัพย์", + "ฉ้อโกง", + "รับของโจร" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic4", + "text": "การทำให้ทรัพย์สินของผู้อื่นเสียหายเรียกว่าความผิดฐานใด?", + "choices": [ + "ทำให้เสียทรัพย์", + "หมิ่นประมาท", + "บุกรุก" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic4", + "text": "การเข้าไปในเคหสถานของผู้อื่นโดยไม่มีสิทธิเรียกว่าอะไร?", + "choices": [ + "ลักทรัพย์", + "บุกรุก", + "ฉ้อโกง" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic4", + "text": "เมื่อถูกลักทรัพย์ควรทำอย่างไร?", + "choices": [ + "แก้แค้นด้วยตนเอง", + "นิ่งเฉย", + "แจ้งความต่อเจ้าหน้าที่ตำรวจ" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic4", + "text": "การลักทรัพย์ในเวลากลางคืนมีผลต่อโทษอย่างไร?", + "choices": [ + "โทษหนักขึ้น (เหตุฉกรรจ์)", + "ไม่มีผลต่อโทษ", + "ได้ลดโทษ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic4", + "text": "การกรรโชกทรัพย์หมายถึงอะไร?", + "choices": [ + "การขอยืมตามปกติ", + "ข่มขืนใจให้ผู้อื่นยอมให้ทรัพย์โดยขู่เข็ญ", + "การซื้อขายทั่วไป" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic4", + "text": "การยักยอกทรัพย์ต่างจากลักทรัพย์อย่างไร?", + "choices": [ + "ต้องใช้กำลังเสมอ", + "ไม่มีความผิด", + "ผู้ครอบครองทรัพย์อยู่แล้วเบียดบังเอาไป" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic4", + "text": "การวิ่งราวทรัพย์หมายถึงอะไร?", + "choices": [ + "ลักทรัพย์โดยฉกฉวยซึ่งหน้าแล้ววิ่งหนี", + "ปล้นโดยมีอาวุธ", + "การฉ้อโกง" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic4", + "text": "ความผิดเกี่ยวกับทรัพย์ส่วนใหญ่อยู่ในกฎหมายใด?", + "choices": [ + "กฎจราจร", + "ประมวลกฎหมายอาญา", + "กฎหมายแรงงาน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic4", + "text": "การทำลายเอกสารสำคัญของผู้อื่นถือเป็นความผิดหรือไม่?", + "choices": [ + "ไม่ผิด", + "ควรส่งเสริม", + "เป็นความผิด" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic4", + "text": "การปล้นทรัพย์โดยมีอาวุธมีผลต่อโทษอย่างไร?", + "choices": [ + "โทษหนักขึ้น", + "ได้ลดโทษ", + "ไม่มีผล" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic4", + "text": "คดีลักทรัพย์ระหว่างญาติบางกรณีจัดเป็นความผิดประเภทใด?", + "choices": [ + "คดีอุกฉกรรจ์เสมอ", + "ความผิดอันยอมความได้", + "คดีแพ่งล้วน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic4", + "text": "การฉ้อโกงประชาชนต่างจากฉ้อโกงทั่วไปอย่างไร?", + "choices": [ + "เหมือนกันทุกอย่าง", + "ไม่เป็นความผิด", + "หลอกลวงคนจำนวนมาก โทษหนักขึ้น" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic4", + "text": "ทรัพย์ที่ถูกลักไปแล้วได้คืน เจ้าของควรทำอย่างไร?", + "choices": [ + "รับคืนและดำเนินคดีตามกฎหมาย", + "ทำลายทิ้ง", + "นำไปขายต่อ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic4", + "text": "สิ่งของที่ผู้อื่นทำหายแล้วเก็บได้ หากเบียดบังเป็นของตนผิดฐานใด?", + "choices": [ + "ปล้นทรัพย์", + "ยักยอกทรัพย์สินหาย", + "ทำร้ายร่างกาย" ], "correctIndex": 1 }, { "categoryId": "topic5", - "text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "การใส่ความผู้อื่นต่อบุคคลที่สามจนเสียชื่อเสียงเรียกว่าอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "หมิ่นประมาท", + "ลักทรัพย์", + "บุกรุก" ], "correctIndex": 0 }, { "categoryId": "topic5", - "text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "การหมิ่นประมาทด้วยการโฆษณาหรือสื่อสิ่งพิมพ์ มีผลต่อโทษอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ได้ลดโทษ", + "โทษหนักขึ้น", + "ไม่เป็นความผิด" ], "correctIndex": 1 }, { "categoryId": "topic5", - "text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การหมิ่นประมาททางออนไลน์เข้าข่ายกฎหมายใดเพิ่มเติม?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "กฎจราจร", + "กฎหมายแรงงาน", + "พ.ร.บ.ว่าด้วยการกระทำผิดเกี่ยวกับคอมพิวเตอร์" ], "correctIndex": 2 }, { "categoryId": "topic5", - "text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "ข้อใดอาจเป็นเหตุยกเว้นความผิดฐานหมิ่นประมาท?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "การติชมโดยสุจริตและเป็นธรรม", + "การใส่ร้ายด้วยข้อมูลเท็จ", + "การนินทาให้เสียหาย" ], "correctIndex": 0 }, { "categoryId": "topic5", - "text": "[คดีหมิ่นประมาท] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "การหมิ่นประมาทบุคคลทั่วไปเป็นความผิดประเภทใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "คดีอุกฉกรรจ์", + "ความผิดอันยอมความได้", + "คดีแพ่งล้วน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic5", + "text": "การด่าทอผู้อื่นซึ่งหน้าด้วยถ้อยคำหยาบคายเข้าข่ายความผิดใด?", + "choices": [ + "ลักทรัพย์", + "ฉ้อโกง", + "ดูหมิ่นซึ่งหน้า" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic5", + "text": "ผู้เสียหายจากการหมิ่นประมาทสามารถทำสิ่งใดได้?", + "choices": [ + "ฟ้องร้องเรียกค่าเสียหาย", + "ทำร้ายผู้กระทำ", + "ยึดทรัพย์เอง" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic5", + "text": "การแชร์ข้อความหมิ่นประมาทผู้อื่นต่อ มีความเสี่ยงอย่างไร?", + "choices": [ + "ปลอดภัยเสมอ", + "อาจมีความผิดร่วมด้วย", + "ได้รับรางวัล" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic5", + "text": "องค์ประกอบสำคัญของการหมิ่นประมาทคืออะไร?", + "choices": [ + "การพูดกับตัวเองคนเดียว", + "การคิดอยู่ในใจ", + "การใส่ความต่อบุคคลที่สาม" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic5", + "text": "การลงรูปผู้อื่นพร้อมข้อความใส่ร้ายในโซเชียลมีเดียผิดหรือไม่?", + "choices": [ + "ผิด", + "ไม่ผิด", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic5", + "text": "หากถูกหมิ่นประมาทออนไลน์ ควรทำอย่างไร?", + "choices": [ + "ลบทุกอย่างทันที", + "เก็บหลักฐานและแจ้งความ", + "ตอบโต้ด้วยการด่ากลับ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic5", + "text": "การวิจารณ์สินค้าหรือบริการตามความจริงโดยสุจริตเป็นอย่างไร?", + "choices": [ + "ผิดกฎหมายเสมอ", + "ต้องติดคุกทันที", + "โดยทั่วไปทำได้" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic5", + "text": "โทษของการหมิ่นประมาทโดยทั่วไปคืออะไร?", + "choices": [ + "ปรับและ/หรือจำคุกตามที่กฎหมายกำหนด", + "ไม่มีโทษใด ๆ", + "ได้รับรางวัล" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic5", + "text": "ความแตกต่างระหว่าง \"ดูหมิ่น\" กับ \"หมิ่นประมาท\" คือ?", + "choices": [ + "เหมือนกันทุกประการ", + "ดูหมิ่นคือสบประมาทซึ่งหน้า หมิ่นประมาทคือใส่ความต่อผู้อื่น", + "ไม่เป็นความผิดทั้งคู่" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic5", + "text": "การกล่าวหาผู้อื่นว่ากระทำผิดโดยไม่มีมูลความจริง เข้าข่ายใด?", + "choices": [ + "ถูกต้องตามกฎหมาย", + "ควรส่งเสริม", + "หมิ่นประมาทหรือแจ้งความเท็จ" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic5", + "text": "ผู้กระทำหมิ่นประมาทอาจต้องรับผิดทางใดบ้าง?", + "choices": [ + "ทั้งทางอาญาและทางแพ่ง", + "ไม่มีความรับผิดใด", + "ได้รับเฉพาะรางวัล" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic5", + "text": "การขอโทษและแก้ไขข้อความ มีผลอย่างไรในคดีหมิ่นประมาท?", + "choices": [ + "ไม่มีผลใด ๆ", + "อาจช่วยบรรเทาโทษหรือยอมความ", + "เพิ่มโทษให้หนักขึ้น" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic5", + "text": "สื่อมวลชนรายงานข่าวตามข้อเท็จจริงเพื่อประโยชน์สาธารณะ โดยทั่วไปเป็นอย่างไร?", + "choices": [ + "ผิดกฎหมายเสมอ", + "ต้องปิดสำนักงาน", + "ได้รับการคุ้มครองหากทำโดยสุจริต" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic5", + "text": "การหมิ่นประมาทผู้ที่เสียชีวิตไปแล้วมีกฎหมายเกี่ยวข้องหรือไม่?", + "choices": [ + "มี เพราะกระทบต่อทายาท", + "ไม่มีเลย", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic5", + "text": "การพูดความจริงเพื่อประโยชน์สาธารณะโดยสุจริต โดยทั่วไปเป็นอย่างไร?", + "choices": [ + "ผิดเสมอ", + "อาจไม่เป็นความผิด", + "ผิดร้ายแรงที่สุด" ], "correctIndex": 1 }, { "categoryId": "topic6", - "text": "[คดีทางเพศ] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "การล่วงละเมิดทางเพศโดยผู้อื่นไม่ยินยอมเป็นความผิดประเภทใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ความผิดทางอาญาที่ร้ายแรง", + "เรื่องส่วนตัว", + "ไม่เป็นความผิด" ], "correctIndex": 0 }, { "categoryId": "topic6", - "text": "[คดีทางเพศ] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "\"ความยินยอม\" ในเรื่องเพศต้องเป็นอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "บังคับให้ยินยอมได้", + "สมัครใจและรู้สึกตัว ไม่ถูกบังคับ", + "ไม่จำเป็นต้องมี" ], "correctIndex": 1 }, { "categoryId": "topic6", - "text": "[คดีทางเพศ] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การล่วงละเมิดทางเพศเด็ก กฎหมายมองอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ไม่ผิดหากเด็กยินยอม", + "เป็นเรื่องเล็กน้อย", + "เป็นความผิดร้ายแรงแม้เด็กจะยินยอม" ], "correctIndex": 2 }, { "categoryId": "topic6", - "text": "[คดีทางเพศ] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "การคุกคามทางเพศในที่ทำงานเป็นอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "เป็นความผิดและร้องเรียนได้", + "เป็นเรื่องปกติ", + "ควรส่งเสริม" ], "correctIndex": 0 }, { "categoryId": "topic6", - "text": "[คดีทางเพศ] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "ผู้เสียหายจากความผิดทางเพศควรทำอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "นิ่งเฉยเสมอ", + "แจ้งความและขอความช่วยเหลือ", + "โทษตัวเอง" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic6", + "text": "การเผยแพร่ภาพลับของผู้อื่นโดยไม่ยินยอมผิดกฎหมายใด?", + "choices": [ + "ไม่ผิดกฎหมาย", + "กฎจราจร", + "กฎหมายอาญาและ พ.ร.บ.คอมพิวเตอร์" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic6", + "text": "การแอบถ่ายภาพผู้อื่นในที่ลับโดยไม่ยินยอมเป็นอย่างไร?", + "choices": [ + "เป็นความผิด", + "ทำได้ตามปกติ", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic6", + "text": "หน่วยงานใดช่วยเหลือผู้เสียหายจากความรุนแรงทางเพศ?", + "choices": [ + "กรมที่ดิน", + "ศูนย์ช่วยเหลือสังคม สายด่วน 1300", + "การไฟฟ้า" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic6", + "text": "การล่อลวงเด็กเพื่อการค้าประเวณีเป็นความผิดอย่างไร?", + "choices": [ + "ไม่เป็นความผิด", + "เป็นเรื่องเล็กน้อย", + "ความผิดร้ายแรง โทษหนัก" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic6", + "text": "การส่งข้อความหรือรูปลามกให้ผู้อื่นที่ไม่ต้องการรับ เป็นอย่างไร?", + "choices": [ + "เป็นการคุกคามและอาจผิดกฎหมาย", + "เป็นการสุภาพ", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic6", + "text": "หลักฐานสำคัญในคดีล่วงละเมิดทางเพศควรทำอย่างไร?", + "choices": [ + "ทำลายทิ้ง", + "เก็บรักษาและรีบแจ้งเจ้าหน้าที่", + "เพิกเฉย" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic6", + "text": "การข่มขืนกระทำชำเราโดยมีอาวุธหรือร่วมกันหลายคน มีผลต่อโทษอย่างไร?", + "choices": [ + "ได้ลดโทษ", + "ไม่มีผล", + "โทษหนักขึ้น" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic6", + "text": "เด็กและเยาวชนที่เป็นผู้เสียหายได้รับการคุ้มครองอย่างไร?", + "choices": [ + "ปกปิดข้อมูลและสอบสวนเป็นพิเศษ", + "เปิดเผยต่อสาธารณะ", + "ไม่มีการคุ้มครอง" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic6", + "text": "การกระทำอนาจารต่อผู้อื่นโดยไม่ยินยอมเป็นความผิดหรือไม่?", + "choices": [ + "ไม่ผิด", + "เป็นความผิด", + "ควรส่งเสริม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic6", + "text": "การให้ความรู้เรื่องการป้องกันภัยทางเพศมีประโยชน์อย่างไร?", + "choices": [ + "ไม่มีประโยชน์", + "เป็นอันตราย", + "ช่วยลดความเสี่ยงและรู้สิทธิของตน" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic6", + "text": "ผู้พบเห็นการล่วงละเมิดทางเพศเด็กควรทำอย่างไร?", + "choices": [ + "แจ้งเจ้าหน้าที่ทันที", + "เพิกเฉย", + "ร่วมกระทำด้วย" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic6", + "text": "การบังคับให้ผู้อื่นค้าประเวณีเข้าข่ายความผิดใด?", + "choices": [ + "ลักทรัพย์", + "การค้ามนุษย์", + "จราจร" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic6", + "text": "ความยินยอมที่ได้มาจากการหลอกลวงหรือข่มขู่ ถือว่าอย่างไร?", + "choices": [ + "ใช้ได้ตามปกติ", + "ดีที่สุด", + "ไม่ถือเป็นความยินยอมที่ชอบด้วยกฎหมาย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic6", + "text": "การเคารพสิทธิในเนื้อตัวร่างกายของผู้อื่นหมายถึงอะไร?", + "choices": [ + "ไม่แตะต้องหรือล่วงละเมิดโดยไม่ยินยอม", + "ทำได้ตามใจ", + "บังคับได้" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic6", + "text": "สายด่วนแจ้งเหตุค้ามนุษย์หรือช่วยเหลือเด็กในภาวะเสี่ยงคือหมายเลขใด?", + "choices": [ + "1137", + "1300 (ศูนย์ช่วยเหลือสังคม)", + "1234" ], "correctIndex": 1 }, { "categoryId": "topic7", - "text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "การทำร้ายร่างกายผู้อื่นจนได้รับอันตรายเป็นความผิดฐานใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ทำร้ายร่างกาย", + "หมิ่นประมาท", + "ลักทรัพย์" ], "correctIndex": 0 }, { "categoryId": "topic7", - "text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "การฆ่าผู้อื่นโดยเจตนาเป็นความผิดฐานใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "กระทำโดยประมาท", + "ฆ่าผู้อื่นโดยเจตนา", + "ความผิดลหุโทษ" ], "correctIndex": 1 }, { "categoryId": "topic7", - "text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การฆ่าโดยไตร่ตรองไว้ก่อนมีผลต่อโทษอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ได้ลดโทษ", + "ไม่มีผล", + "โทษหนักขึ้นถึงประหารชีวิต" ], "correctIndex": 2 }, { "categoryId": "topic7", - "text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "การป้องกันตัวพอสมควรแก่เหตุ มีผลทางกฎหมายอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ไม่มีความผิด", + "ผิดเสมอ", + "ได้รับรางวัล" ], "correctIndex": 0 }, { "categoryId": "topic7", - "text": "[คดีอาชญากรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "การกระทำโดยประมาทเป็นเหตุให้ผู้อื่นถึงแก่ความตายเป็นอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ไม่เป็นความผิด", + "มีความผิดฐานประมาท", + "เป็นการฆ่าโดยเจตนา" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic7", + "text": "การข่มขู่ว่าจะทำร้ายผู้อื่นให้เกิดความกลัวเป็นความผิดฐานใด?", + "choices": [ + "ลักทรัพย์", + "จราจร", + "ข่มขืนใจหรือทำให้ตกใจกลัว" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic7", + "text": "ผู้ใช้ให้ผู้อื่นกระทำความผิด มีความรับผิดอย่างไร?", + "choices": [ + "รับผิดในฐานะผู้ใช้", + "ไม่มีความผิด", + "ได้รับรางวัล" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic7", + "text": "ผู้สนับสนุนการกระทำความผิดมีความรับผิดหรือไม่?", + "choices": [ + "ไม่มี", + "มี ในฐานะผู้สนับสนุน", + "ควรส่งเสริม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic7", + "text": "การพยายามกระทำความผิดแต่ไม่สำเร็จ มีความรับผิดหรือไม่?", + "choices": [ + "ไม่มีความรับผิด", + "โทษเท่าเดิมเสมอ", + "มี แต่โทษอาจลดลง" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic7", + "text": "ความผิดอาญาส่วนใหญ่ถูกบัญญัติไว้ในกฎหมายใด?", + "choices": [ + "ประมวลกฎหมายอาญา", + "กฎหมายแพ่ง", + "กฎจราจร" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic7", + "text": "การครอบครองอาวุธปืนโดยไม่ได้รับอนุญาตเป็นอย่างไร?", + "choices": [ + "ถูกกฎหมาย", + "ผิดกฎหมาย", + "ควรส่งเสริม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic7", + "text": "การมั่วสุมก่อความวุ่นวายในที่สาธารณะเป็นความผิดหรือไม่?", + "choices": [ + "ไม่ผิด", + "ควรส่งเสริม", + "เป็นความผิด" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic7", + "text": "หลัก \"ไม่มีความผิดและไม่มีโทษโดยไม่มีกฎหมาย\" หมายถึงอะไร?", + "choices": [ + "ต้องมีกฎหมายบัญญัติไว้ก่อนจึงลงโทษได้", + "ลงโทษได้ตามใจ", + "ไม่ต้องมีกฎหมายก็ได้" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic7", + "text": "การกระทำความผิดซ้ำมีผลอย่างไร?", + "choices": [ + "ได้ลดโทษเสมอ", + "อาจถูกเพิ่มโทษ", + "ไม่มีผล" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic7", + "text": "การวางเพลิงเผาทรัพย์ของผู้อื่นเป็นความผิดฐานใด?", + "choices": [ + "ลักทรัพย์", + "หมิ่นประมาท", + "วางเพลิง" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic7", + "text": "การให้การเท็จต่อศาลในฐานะพยานเป็นความผิดฐานใด?", + "choices": [ + "เบิกความเท็จ", + "เรื่องปกติ", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic7", + "text": "ผู้เสพหรือครอบครองยาเสพติดเข้าสู่กระบวนการใดได้บ้าง?", + "choices": [ + "ไม่มีอะไรเกิดขึ้น", + "บำบัดรักษาหรือดำเนินคดีตามกฎหมาย", + "ได้รับรางวัล" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic7", + "text": "การช่วยผู้กระทำผิดหลบหนีหรือซ่อนหลักฐานเป็นความผิดหรือไม่?", + "choices": [ + "ไม่ผิด", + "ควรส่งเสริม", + "เป็นความผิด" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic7", + "text": "โทษทางอาญาตามประมวลกฎหมายอาญ ามีประเภทใดบ้าง?", + "choices": [ + "ประหารชีวิต จำคุก กักขัง ปรับ ริบทรัพย์สิน", + "มีเพียงแบบเดียว", + "ไม่มีโทษใด ๆ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic7", + "text": "เด็กอายุน้อยที่กระทำผิด กฎหมายปฏิบัติอย่างไร?", + "choices": [ + "ลงโทษเท่าผู้ใหญ่", + "ใช้วิธีการสำหรับเด็กเน้นแก้ไขฟื้นฟู", + "ไม่ทำอะไรเลย" ], "correctIndex": 1 }, { "categoryId": "topic8", - "text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "การหลอกให้โอนเงินผ่านออนไลน์ (แก๊งคอลเซ็นเตอร์) เป็นความผิดฐานใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ฉ้อโกงหรือฉ้อโกงประชาชน", + "เรื่องปกติ", + "ควรส่งเสริม" ], "correctIndex": 0 }, { "categoryId": "topic8", - "text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "การเข้าถึงระบบคอมพิวเตอร์ของผู้อื่นโดยไม่ได้รับอนุญาตผิดกฎหมายใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "กฎจราจร", + "พ.ร.บ.คอมพิวเตอร์", + "กฎหมายแรงงาน" ], "correctIndex": 1 }, { "categoryId": "topic8", - "text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "การนำข้อมูลเท็จเข้าสู่ระบบจนผู้อื่นเสียหายเป็นอย่างไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ถูกกฎหมาย", + "ควรส่งเสริม", + "ผิด พ.ร.บ.คอมพิวเตอร์" ], "correctIndex": 2 }, { "categoryId": "topic8", - "text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "สิ่งใดที่ \"ไม่ควรทำ\" เพื่อป้องกันบัญชีถูกแฮก?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "บอกรหัส OTP ให้ผู้อื่น", + "ตั้งรหัสผ่านที่คาดเดายาก", + "เปิดการยืนยันสองชั้น (2FA)" ], "correctIndex": 0 }, { "categoryId": "topic8", - "text": "[อาชญากรรมออนไลน์] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "ลิงก์ปลอมที่ขอข้อมูลส่วนตัวหรือรหัสผ่าน เรียกว่ากลโกงแบบใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "การอัปเดตปกติ", + "ฟิชชิ่ง (Phishing)", + "โปรโมชั่นจริง" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic8", + "text": "การกลั่นแกล้งรังแกกันบนโลกออนไลน์เรียกว่าอะไร?", + "choices": [ + "อีคอมเมิร์ซ", + "อีเลิร์นนิง", + "ไซเบอร์บูลลี่ (Cyberbullying)" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic8", + "text": "ควรทำอย่างไรเมื่อถูกหลอกโอนเงินออนไลน์?", + "choices": [ + "รีบแจ้งธนาคารและสายด่วน 1441", + "เงียบไว้ไม่บอกใคร", + "โอนเงินเพิ่ม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic8", + "text": "การปลอมโปรไฟล์ผู้อื่นเพื่อหลอกลวงเป็นความผิดหรือไม่?", + "choices": [ + "ไม่ผิด", + "เป็นความผิด", + "ควรส่งเสริม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic8", + "text": "รหัสผ่านที่ปลอดภัยควรเป็นอย่างไร?", + "choices": [ + "ใช้วันเกิดของตน", + "ใช้เลข 1234", + "ยาว ผสมตัวอักษร ตัวเลข และสัญลักษณ์" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic8", + "text": "การซื้อของออนไลน์ให้ปลอดภัยควรทำอย่างไร?", + "choices": [ + "ตรวจสอบร้านค้าและรีวิวก่อนโอนเงิน", + "โอนเงินทันทีทุกครั้ง", + "ไม่ต้องตรวจสอบ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic8", + "text": "การเผยแพร่ภาพหรือข้อมูลส่วนตัวผู้อื่นโดยไม่ยินยอมเป็นอย่างไร?", + "choices": [ + "ถูกต้อง", + "อาจผิดกฎหมาย PDPA หรือคอมพิวเตอร์", + "ควรส่งเสริม" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic8", + "text": "มัลแวร์ (Malware) คืออะไร?", + "choices": [ + "แอปธนาคารทางการ", + "เกมการศึกษา", + "โปรแกรมประสงค์ร้าย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic8", + "text": "สายด่วนแจ้งอายัดบัญชีเมื่อถูกหลอกโอนเงินออนไลน์คือหมายเลขใด?", + "choices": [ + "1441", + "1669", + "1112" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic8", + "text": "การติดตั้งแอปจากลิงก์ที่ไม่น่าเชื่อถือเสี่ยงอย่างไร?", + "choices": [ + "ปลอดภัยเสมอ", + "ถูกควบคุมเครื่องหรือดูดเงิน", + "ได้รับเงิน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic8", + "text": "การพนันออนไลน์ในประเทศไทยเป็นอย่างไร?", + "choices": [ + "ถูกกฎหมาย", + "ควรส่งเสริม", + "ผิดกฎหมาย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic8", + "text": "การหลอกขายสินค้าออนไลน์แล้วไม่ส่งของเป็นความผิดฐานใด?", + "choices": [ + "ฉ้อโกง", + "เรื่องปกติ", + "ควรส่งเสริม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic8", + "text": "ควรปฏิบัติกับรหัส OTP ที่ได้รับอย่างไร?", + "choices": [ + "แชร์ในกลุ่มเพื่อน", + "เก็บเป็นความลับ ไม่บอกใคร", + "โพสต์สาธารณะ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic8", + "text": "การแฮกบัญชีโซเชียลของผู้อื่นเป็นอย่างไร?", + "choices": [ + "เรื่องปกติ", + "ควรส่งเสริม", + "ผิดกฎหมาย" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic8", + "text": "เมื่อพบข่าวปลอม (Fake News) ควรทำอย่างไร?", + "choices": [ + "ตรวจสอบให้แน่ใจก่อนแชร์", + "แชร์ต่อทันที", + "สร้างข่าวปลอมเพิ่ม" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic8", + "text": "การกรอกข้อมูลบัตรเครดิตในเว็บที่ไม่ปลอดภัยเสี่ยงอย่างไร?", + "choices": [ + "ปลอดภัยเสมอ", + "ถูกขโมยเงินหรือข้อมูล", + "ได้รับแต้มสะสม" ], "correctIndex": 1 }, { "categoryId": "topic9", - "text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "หน่วยงานใดมีหน้าที่สืบสวนสอบสวนคดีอาญาในเบื้องต้น?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ตำรวจ", + "ศาล", + "กรมราชทัณฑ์" ], "correctIndex": 0 }, { "categoryId": "topic9", - "text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "ผู้มีหน้าที่ฟ้องคดีอาญาแทนรัฐคือใคร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ผู้พิพากษา", + "พนักงานอัยการ", + "ทนายจำเลย" ], "correctIndex": 1 }, { "categoryId": "topic9", - "text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "ผู้ทำหน้าที่พิจารณาพิพากษาคดีคือใคร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ตำรวจ", + "อัยการ", + "ผู้พิพากษาหรือศาล" ], "correctIndex": 2 }, { "categoryId": "topic9", - "text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "หลัก \"สันนิษฐานว่าบริสุทธิ์\" หมายถึงอะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ถือว่าบริสุทธิ์จนกว่าศาลจะตัดสินว่าผิด", + "ถือว่าผิดทันที", + "ไม่ต้องพิสูจน์" ], "correctIndex": 0 }, { "categoryId": "topic9", - "text": "[กระบวนการยุติธรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "ผู้ต้องหามีสิทธิข้อใดในชั้นสอบสวน?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ต้องรับสารภาพ", + "มีสิทธิมีทนายและจะไม่ให้การก็ได้", + "ห้ามนิ่งเงียบ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic9", + "text": "การปล่อยตัวชั่วคราวระหว่างดำเนินคดีเรียกว่าอะไร?", + "choices": [ + "การจำคุก", + "การปรับ", + "การประกันตัว" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic9", + "text": "ศาลชั้นต้น อุทธรณ์ และฎีกา เป็นลำดับของอะไร?", + "choices": [ + "ลำดับชั้นของศาล", + "ชื่อเรือนจำ", + "ชื่อสถานีตำรวจ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic9", + "text": "หากไม่พอใจคำพิพากษาศาลชั้นต้น คู่ความทำสิ่งใดได้?", + "choices": [ + "แก้แค้นด้วยตนเอง", + "ยื่นอุทธรณ์", + "เพิกเฉยเสมอ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic9", + "text": "ผู้ไม่มีเงินจ้างทนายในคดีอาญา มีสิทธิอย่างไร?", + "choices": [ + "ต้องสู้คดีด้วยตนเอง", + "ถูกตัดสินทันที", + "ขอทนายความที่รัฐจัดให้" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic9", + "text": "หน่วยงานใดดูแลผู้ต้องขังหลังศาลพิพากษาจำคุก?", + "choices": [ + "กรมราชทัณฑ์", + "อัยการ", + "ตำรวจจราจร" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic9", + "text": "คดีแพ่งต่างจากคดีอาญาอย่างไร?", + "choices": [ + "เหมือนกันทุกอย่าง", + "แพ่งเป็นข้อพิพาทเรื่องสิทธิ/หนี้ อาญาเป็นการลงโทษผู้กระทำผิด", + "ไม่มีความแตกต่าง" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic9", + "text": "พยานมีหน้าที่อย่างไรต่อศาล?", + "choices": [ + "โกหกได้", + "ไม่ต้องมาศาล", + "ให้การตามความจริง" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic9", + "text": "การไกล่เกลี่ยข้อพิพาทมีประโยชน์อย่างไร?", + "choices": [ + "ยุติข้อพิพาทได้เร็วและประหยัด", + "เพิ่มความขัดแย้ง", + "ผิดกฎหมาย" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic9", + "text": "หมายค้นหรือหมายจับออกโดยใคร?", + "choices": [ + "เพื่อนบ้าน", + "ศาล", + "ห้างสรรพสินค้า" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic9", + "text": "สิทธิของผู้เสียหายในคดีอาญาข้อใดถูกต้อง?", + "choices": [ + "ห้ามยุ่งเกี่ยว", + "ต้องนิ่งเงียบ", + "ร้องทุกข์และเป็นโจทก์ร่วมได้" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic9", + "text": "ทนายความมีบทบาทอย่างไร?", + "choices": [ + "ให้คำปรึกษาและว่าความแทนคู่ความ", + "ตัดสินคดี", + "จับกุมผู้ต้องหา" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic9", + "text": "การบังคับคดีแพ่งทำเพื่อสิ่งใด?", + "choices": [ + "ลงโทษจำคุก", + "ให้เป็นไปตามคำพิพากษา เช่น ยึดทรัพย์ชำระหนี้", + "ไม่มีผลใด ๆ" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic9", + "text": "ระบบยุติธรรมสำหรับเด็กและเยาวชนเน้นสิ่งใด?", + "choices": [ + "การลงโทษที่รุนแรงที่สุด", + "ไม่สนใจ", + "การแก้ไขฟื้นฟูมากกว่าการลงโทษ" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic9", + "text": "การอุทธรณ์หรือฎีกาต้องทำภายในกำหนดเวลาหรือไม่?", + "choices": [ + "ต้องทำภายในระยะเวลาที่กฎหมายกำหนด", + "ไม่มีกำหนดเวลา", + "ทำเมื่อใดก็ได้" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic9", + "text": "กระบวนการยุติธรรมเชิงสมานฉันท์มีเป้าหมายอย่างไร?", + "choices": [ + "เพิ่มโทษให้หนัก", + "เยียวยาและคืนความสัมพันธ์ระหว่างคู่กรณี", + "ส่งเสริมการแก้แค้น" ], "correctIndex": 1 }, { "categoryId": "topic10", - "text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 1 (แก้ได้ใน Admin)", + "text": "กองทุนยุติธรรมช่วยเหลือประชาชนในเรื่องใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "ค่าใช้จ่ายในการเข้าถึงความยุติธรรม เช่น ค่าทนาย/ประกันตัว", + "ค่าท่องเที่ยว", + "ค่าอาหารประจำวัน" ], "correctIndex": 0 }, { "categoryId": "topic10", - "text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 2 (แก้ได้ใน Admin)", + "text": "สายด่วนกระทรวงยุติธรรมคือหมายเลขใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "1669", + "1111 กด 77", + "199" ], "correctIndex": 1 }, { "categoryId": "topic10", - "text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 3 (แก้ได้ใน Admin)", + "text": "กรมคุ้มครองสิทธิและเสรีภาพมีหน้าที่หลักด้านใด?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "เก็บภาษี", + "ออกใบขับขี่", + "คุ้มครองสิทธิและช่วยเหลือเยียวยาผู้เสียหาย" ], "correctIndex": 2 }, { "categoryId": "topic10", - "text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 4 (แก้ได้ใน Admin)", + "text": "ผู้เสียหายในคดีอาญาที่ไม่ได้มีส่วนผิด อาจได้รับสิ่งใดจากรัฐ?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "เงินช่วยเหลือหรือค่าตอบแทนผู้เสียหาย", + "ค่าปรับ", + "ไม่ได้รับสิ่งใด" ], "correctIndex": 0 }, { "categoryId": "topic10", - "text": "[งานบริการกระทรวงยุติธรรม] คำถามตัวอย่างที่ 5 (แก้ได้ใน Admin)", + "text": "กรมบังคับคดีมีหน้าที่อะไร?", "choices": [ - "ตัวเลือก ก", - "ตัวเลือก ข", - "ตัวเลือก ค" + "สอนหนังสือ", + "บังคับคดีตามคำพิพากษา เช่น ยึดและขายทอดตลาด", + "รักษาพยาบาล" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic10", + "text": "ศูนย์ยุติธรรมชุมชนมีไว้เพื่อสิ่งใด?", + "choices": [ + "ขายสินค้า", + "จัดคอนเสิร์ต", + "ให้บริการและไกล่เกลี่ยในระดับชุมชน" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic10", + "text": "การไกล่เกลี่ยข้อพิพาทโดยหน่วยงานรัฐมีค่าใช้จ่ายอย่างไร?", + "choices": [ + "ส่วนใหญ่ไม่มีค่าใช้จ่ายหรือค่าใช้จ่ายต่ำ", + "แพงมาก", + "ต้องติดสินบน" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic10", + "text": "กรมพินิจและคุ้มครองเด็กและเยาวชนดูแลเรื่องใด?", + "choices": [ + "ผู้สูงอายุทั่วไป", + "เด็กและเยาวชนที่เข้าสู่กระบวนการยุติธรรม", + "การจัดเก็บภาษี" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic10", + "text": "สถาบันนิติวิทยาศาสตร์มีบทบาทอย่างไร?", + "choices": [ + "ออกใบขับขี่", + "เก็บภาษี", + "ตรวจพิสูจน์หลักฐานทางวิทยาศาสตร์" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic10", + "text": "ประชาชนขอคำปรึกษากฎหมายเบื้องต้นจากกระทรวงยุติธรรมได้หรือไม่?", + "choices": [ + "ได้ มีบริการให้คำปรึกษา", + "ไม่ได้", + "ต้องจ่ายเงินจำนวนมาก" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic10", + "text": "กรมสอบสวนคดีพิเศษ (DSI) ดูแลคดีประเภทใด?", + "choices": [ + "คดีจราจรเล็กน้อย", + "คดีพิเศษที่ซับซ้อนหรือกระทบส่วนรวม", + "คดีทั่วไปในชุมชน" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic10", + "text": "การช่วยเหลือทางการเงินแก่ผู้ต้องหายากจนเพื่อประกันตัว มาจากแหล่งใด?", + "choices": [ + "เงินส่วนตัวของศาล", + "ภาษีท้องถิ่น", + "กองทุนยุติธรรม" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic10", + "text": "การคุ้มครองพยานในคดีสำคัญเป็นภารกิจด้านใด?", + "choices": [ + "งานคุ้มครองพยาน", + "งานออกใบขับขี่", + "งานเก็บขยะ" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic10", + "text": "หากประชาชนไม่ได้รับความเป็นธรรม ร้องเรียนได้ที่ใดบ้าง?", + "choices": [ + "ร้านสะดวกซื้อ", + "ศูนย์บริการหรือสายด่วนกระทรวงยุติธรรม", + "ธนาคาร" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic10", + "text": "การฟื้นฟูสมรรถภาพผู้ติดยาเสพติดเกี่ยวข้องกับหน่วยงานด้านใด?", + "choices": [ + "กรมที่ดิน", + "ไปรษณีย์", + "หน่วยงานด้านยาเสพติดและสาธารณสุข" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic10", + "text": "บริการ \"ทนายความอาสา\" มีไว้เพื่อสิ่งใด?", + "choices": [ + "ช่วยเหลือผู้ขาดแคลนทุนทรัพย์", + "เก็บค่าธรรมเนียมราคาแพง", + "โฆษณาสินค้า" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic10", + "text": "การขอรับค่าตอบแทนผู้เสียหายต้องยื่นภายในกำหนดเวลาหรือไม่?", + "choices": [ + "ไม่มีกำหนดเวลา", + "ต้องยื่นภายในระยะเวลาที่กฎหมายกำหนด", + "ยื่นเมื่อใดก็ได้" + ], + "correctIndex": 1 + }, + { + "categoryId": "topic10", + "text": "กระทรวงยุติธรรมส่งเสริมความรู้กฎหมายแก่ประชาชนเพื่ออะไร?", + "choices": [ + "เพิ่มจำนวนคดี", + "จัดเก็บภาษี", + "ให้ประชาชนรู้สิทธิและเข้าถึงความยุติธรรม" + ], + "correctIndex": 2 + }, + { + "categoryId": "topic10", + "text": "แนวคิด \"ยุติธรรมสร้างสุข\" เกี่ยวกับสิ่งใด?", + "choices": [ + "บริการประชาชนให้เข้าถึงความยุติธรรมอย่างทั่วถึง", + "การท่องเที่ยว", + "การกีฬา" + ], + "correctIndex": 0 + }, + { + "categoryId": "topic10", + "text": "การตรวจสอบประวัติอาชญากรรมเพื่อสมัครงานเกี่ยวข้องกับหน่วยงานใด?", + "choices": [ + "การไฟฟ้า", + "หน่วยงานตำรวจที่เกี่ยวข้อง", + "ไปรษณีย์" ], "correctIndex": 1 } diff --git a/www/html/Game/public/img/qb-ui/Quiz-Battle-bg.png b/www/html/Game/public/img/qb-ui/Quiz-Battle-bg.png new file mode 100644 index 0000000..ff19a39 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Quiz-Battle-bg.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-01.png b/www/html/Game/public/img/qb-ui/Room-01.png new file mode 100644 index 0000000..2c73d18 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-01.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-02.png b/www/html/Game/public/img/qb-ui/Room-02.png new file mode 100644 index 0000000..5749176 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-02.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-03.png b/www/html/Game/public/img/qb-ui/Room-03.png new file mode 100644 index 0000000..2123b93 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-03.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-04.png b/www/html/Game/public/img/qb-ui/Room-04.png new file mode 100644 index 0000000..d69eb8d Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-04.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-05.png b/www/html/Game/public/img/qb-ui/Room-05.png new file mode 100644 index 0000000..fe8b513 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-05.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-06.png b/www/html/Game/public/img/qb-ui/Room-06.png new file mode 100644 index 0000000..2c8c77b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-06.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-07.png b/www/html/Game/public/img/qb-ui/Room-07.png new file mode 100644 index 0000000..ee1450b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-07.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-08.png b/www/html/Game/public/img/qb-ui/Room-08.png new file mode 100644 index 0000000..a4e67ad Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-08.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-09.png b/www/html/Game/public/img/qb-ui/Room-09.png new file mode 100644 index 0000000..f33cb1b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-09.png differ diff --git a/www/html/Game/public/img/qb-ui/Room-10.png b/www/html/Game/public/img/qb-ui/Room-10.png new file mode 100644 index 0000000..96e940c Binary files /dev/null and b/www/html/Game/public/img/qb-ui/Room-10.png differ diff --git a/www/html/Game/public/img/qb-ui/btn-exit-room.png b/www/html/Game/public/img/qb-ui/btn-exit-room.png new file mode 100644 index 0000000..afea9a0 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/btn-exit-room.png differ diff --git a/www/html/Game/public/img/qb-ui/btn-more.png b/www/html/Game/public/img/qb-ui/btn-more.png new file mode 100644 index 0000000..2499517 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/btn-more.png differ diff --git a/www/html/Game/public/img/qb-ui/btn-my-result.png b/www/html/Game/public/img/qb-ui/btn-my-result.png new file mode 100644 index 0000000..40244e3 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/btn-my-result.png differ diff --git a/www/html/Game/public/img/qb-ui/btn-ranking.png b/www/html/Game/public/img/qb-ui/btn-ranking.png new file mode 100644 index 0000000..63eeb22 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/btn-ranking.png differ diff --git a/www/html/Game/public/img/qb-ui/btn-start-quiz.png b/www/html/Game/public/img/qb-ui/btn-start-quiz.png new file mode 100644 index 0000000..06c3e2e Binary files /dev/null and b/www/html/Game/public/img/qb-ui/btn-start-quiz.png differ diff --git a/www/html/Game/public/img/qb-ui/icon-001.png b/www/html/Game/public/img/qb-ui/icon-001.png new file mode 100644 index 0000000..5eea5c7 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/icon-001.png differ diff --git a/www/html/Game/public/img/qb-ui/icon-002.png b/www/html/Game/public/img/qb-ui/icon-002.png new file mode 100644 index 0000000..eb80c3a Binary files /dev/null and b/www/html/Game/public/img/qb-ui/icon-002.png differ diff --git a/www/html/Game/public/img/qb-ui/icon-003.png b/www/html/Game/public/img/qb-ui/icon-003.png new file mode 100644 index 0000000..22d1266 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/icon-003.png differ diff --git a/www/html/Game/public/img/qb-ui/popup-myresult.png b/www/html/Game/public/img/qb-ui/popup-myresult.png new file mode 100644 index 0000000..9119046 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/popup-myresult.png differ diff --git a/www/html/Game/public/img/qb-ui/popup-result.png b/www/html/Game/public/img/qb-ui/popup-result.png new file mode 100644 index 0000000..4a0177d Binary files /dev/null and b/www/html/Game/public/img/qb-ui/popup-result.png differ diff --git a/www/html/Game/public/img/qb-ui/q-correct.png b/www/html/Game/public/img/qb-ui/q-correct.png new file mode 100644 index 0000000..5af32d0 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/q-correct.png differ diff --git a/www/html/Game/public/img/qb-ui/q-scroll-bar.png b/www/html/Game/public/img/qb-ui/q-scroll-bar.png new file mode 100644 index 0000000..c3bbc37 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/q-scroll-bar.png differ diff --git a/www/html/Game/public/img/qb-ui/q-scroll-bg.png b/www/html/Game/public/img/qb-ui/q-scroll-bg.png new file mode 100644 index 0000000..36fb0aa Binary files /dev/null and b/www/html/Game/public/img/qb-ui/q-scroll-bg.png differ diff --git a/www/html/Game/public/img/qb-ui/q-wrong.png b/www/html/Game/public/img/qb-ui/q-wrong.png new file mode 100644 index 0000000..cd43c1b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/q-wrong.png differ diff --git a/www/html/Game/public/img/qb-ui/quiz-room.png b/www/html/Game/public/img/qb-ui/quiz-room.png new file mode 100644 index 0000000..bfeca65 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/quiz-room.png differ diff --git a/www/html/Game/public/img/qb-ui/result-01.png b/www/html/Game/public/img/qb-ui/result-01.png new file mode 100644 index 0000000..fb0e48c Binary files /dev/null and b/www/html/Game/public/img/qb-ui/result-01.png differ diff --git a/www/html/Game/public/img/qb-ui/result-02.png b/www/html/Game/public/img/qb-ui/result-02.png new file mode 100644 index 0000000..577b69d Binary files /dev/null and b/www/html/Game/public/img/qb-ui/result-02.png differ diff --git a/www/html/Game/public/img/qb-ui/result-03.png b/www/html/Game/public/img/qb-ui/result-03.png new file mode 100644 index 0000000..dca9852 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/result-03.png differ diff --git a/www/html/Game/public/img/qb-ui/result-04-line.png b/www/html/Game/public/img/qb-ui/result-04-line.png new file mode 100644 index 0000000..499860b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/result-04-line.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-01.png b/www/html/Game/public/img/qb-ui/tag-01.png new file mode 100644 index 0000000..b4e1a05 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-01.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-02.png b/www/html/Game/public/img/qb-ui/tag-02.png new file mode 100644 index 0000000..f460ad9 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-02.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-03.png b/www/html/Game/public/img/qb-ui/tag-03.png new file mode 100644 index 0000000..865a30b Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-03.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-04.png b/www/html/Game/public/img/qb-ui/tag-04.png new file mode 100644 index 0000000..0e6013f Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-04.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-05.png b/www/html/Game/public/img/qb-ui/tag-05.png new file mode 100644 index 0000000..53a5128 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-05.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-06.png b/www/html/Game/public/img/qb-ui/tag-06.png new file mode 100644 index 0000000..ed65824 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-06.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-07.png b/www/html/Game/public/img/qb-ui/tag-07.png new file mode 100644 index 0000000..ad28a36 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-07.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-08.png b/www/html/Game/public/img/qb-ui/tag-08.png new file mode 100644 index 0000000..1a7ee1d Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-08.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-09.png b/www/html/Game/public/img/qb-ui/tag-09.png new file mode 100644 index 0000000..51d74e3 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-09.png differ diff --git a/www/html/Game/public/img/qb-ui/tag-10.png b/www/html/Game/public/img/qb-ui/tag-10.png new file mode 100644 index 0000000..20fc4e1 Binary files /dev/null and b/www/html/Game/public/img/qb-ui/tag-10.png differ diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js index 2e6b38f..6624a8a 100644 --- a/www/html/Game/public/js/play.js +++ b/www/html/Game/public/js/play.js @@ -3155,6 +3155,19 @@ let quizBattleAnsweredComps = new Set(); let quizBattleModalCompId = null; let qbAutoLastComp = null; // โดมล่าสุดที่ trigger อัตโนมัติ (กันเด้งซ้ำขณะยืนค้าง) + /** ประวัติคำตอบต่อโดม (สำหรับ MY RESULT): compId → { qIndex, firstTry(bool), correct(bool), submittedIdx, q } */ + let quizBattleAnswerLog = new Map(); + /** เวลาเริ่มเล่นห้อง quiz_battle (ms) — สำหรับ Total time */ + let quizBattleSessionStartMs = 0; + let quizBattleScoreSubmittedAt = 0; + /** ล็อกตัวเลือกระหว่างโชว์ผลถูก/ผิด (กันกดซ้ำ + กันเด้งซ้ำ) */ + let quizBattleChoiceLocked = false; + /** โชว์ popup Completed แล้วหรือยัง (กันเด้งซ้ำเมื่อตอบครบทุกโดม) */ + let quizBattleCompletedShown = false; + /** โดมที่ "ผ่านแล้ว" (ตอบถูกหรือผิดก็ผ่าน) — ใช้ปลดล็อกเส้นทาง + จำว่าเคยตอบ ไม่ต้องตอบซ้ำ */ + let quizBattlePassedComps = new Set(); + /** ซูมที่ผู้เล่นปรับเองในฉาก quiz_battle (ล้อเมาส์ / ปุ่ม +−) */ + let quizBattleUserZoomMul = 1; const SPACE_SHOOTER_SHIP_COLORS = ['#50fa7b', '#ff79c6', '#ff5555', '#f1fa8c', '#bd93f9', '#8be9fd']; document.getElementById('room-id').textContent = spaceId; @@ -3204,6 +3217,10 @@ if (isQuizQuestionMissionUiMapPlay()) { wrap.classList.add('is-hidden'); } + /* Quiz Battle: ใช้ HUD ใหม่ (#qb-game-hud) — ซ่อนกล่อง "คะแนน" เดิม */ + if (isQuizBattle()) { + wrap.classList.add('is-hidden'); + } } function initPlayLiveQuizScoresZeros() { @@ -5469,6 +5486,8 @@ const mwPx = w * tileSize; const mhPx = h * tileSize; zDraw = Math.min(canvas.width / mwPx, canvas.height / mhPx) * 0.96; + } else if (isQuizBattle()) { + zDraw *= quizBattleUserZoomMul; } if (isStackTowerEmbedZoomLockedPlay()) { playEmbedUserZoomMul = PLAY_EMBED_STACK_TOWER_FIXED_ZOOM_MUL; @@ -9834,6 +9853,80 @@ } } + /** Quiz Battle (qbroom*) เลขห้องจาก mapId → tag/หมวด */ + function quizBattleRoomNoPlay() { + const m = String(currentPlayMapId() || '').match(/qbroom(\d+)/i); + return m ? Math.max(1, Math.min(10, parseInt(m[1], 10))) : 0; + } + + /** + * Quiz Battle in-game HUD → overlay #qb-game-hud (design plane 1920×1080 scale ตาม stage) + * header หมวด (tag-NN), PLAYERS x/50, SCORE (ตอบถูก), host avatar. EXIT/MY RESULT/RANKING wire แยก + */ + function syncQuizBattleHudPlay() { + const root = document.getElementById('qb-game-hud'); + if (!root) return; + const on = !!(mapData && isQuizBattle()); + root.classList.toggle('is-hidden', !on); + root.setAttribute('aria-hidden', on ? 'false' : 'true'); + if (!on) return; + /* ซ่อนกล่อง dev instruction ('QUIZ BATTLE · โหลดคำถามแล้ว...') มุมซ้ายล่าง — ไม่มีใน design */ + const qgOv = document.getElementById('quiz-game-overlay'); + if (qgOv && !qgOv.classList.contains('is-hidden')) qgOv.classList.add('is-hidden'); + const stack = document.getElementById('play-canvas-stack'); + if (stack) { + const r = stack.getBoundingClientRect(); + const cw = Math.max(1, r.width || 0); + const ch = Math.max(1, r.height || 0); + const s = Math.min(cw / 1920, ch / 1080); + if (s > 0 && isFinite(s)) { + const left = Math.round(r.left + (cw - 1920 * s) / 2); + const top = Math.round(r.top + (ch - 1080 * s) / 2); + const key = left + ',' + top + ',' + s.toFixed(4); + if (root.dataset.box !== key) { + root.dataset.box = key; + root.style.left = left + 'px'; + root.style.top = top + 'px'; + root.style.transform = 'scale(' + s + ')'; + } + } + } + const roomNo = quizBattleRoomNoPlay(); + const tag = document.getElementById('qb-hud-tag'); + if (tag && roomNo > 0) { + const want = BASE + '/img/qb-ui/tag-' + (roomNo < 10 ? '0' + roomNo : String(roomNo)) + '.png'; + if (tag.dataset.src !== want) { tag.dataset.src = want; tag.src = want; } + } + const pv = document.getElementById('qb-hud-players-val'); + if (pv) { + const n = countPlayHumans(); + const max = (mapData && mapData.maxPlayers) || 50; + const txt = n + '/' + max; + if (pv.textContent !== txt) pv.textContent = txt; + } + const sv = document.getElementById('qb-hud-score-val'); + if (sv) { + const sc = quizBattleAnsweredComps ? quizBattleAnsweredComps.size : 0; + if (sv.textContent !== String(sc)) sv.textContent = String(sc); + } + const av = document.getElementById('qb-hud-host-av'); + if (av) { + const cid = me.characterId || getPlayCharacterId(); + if (cid && av.dataset.cid !== String(cid)) { + av.dataset.cid = String(cid); + /* full-body down avatar (เหมือนหน้า Quiz-Battle/.qb-room-profile-avatar) clip โชว์แค่ส่วนบน */ + ensurePlayLobbyIdleAvatarImage(cid); + const src = playLobbyIdleAvatarSrcForCharacter(cid); + if (src) { + av.src = src; + } else { + const im = getCharacterImg(cid, 'down'); + if (im && im.src) av.src = im.src; + } + } + } + } + function resetQuizCarryPlayState() { cancelQuizCarrySessionCompleteResultToSummary(); const qcmo = document.getElementById('quiz-carry-mission-overlay'); @@ -13649,6 +13742,7 @@ ov.classList.add('is-hidden'); ov.setAttribute('aria-hidden', 'true'); } + quizBattleChoiceLocked = false; } function flashQuizBattleFeedback(text, ok) { @@ -13725,20 +13819,30 @@ const ov = document.getElementById('quiz-battle-mcq-overlay'); const textEl = document.getElementById('quiz-battle-mcq-text'); if (!ov || !textEl || !q) return; + const titleEl = document.getElementById('quiz-battle-mcq-title'); + if (titleEl) titleEl.textContent = 'QUESTION #' + (quizBattleModalCompId || ''); textEl.textContent = q.text || ''; const labels = ['A', 'B', 'C']; for (let i = 0; i < 3; i++) { const btn = ov.querySelector('.quiz-battle-choice[data-idx="' + i + '"]'); - if (btn) { - const ch = (q.choices && q.choices[i]) ? String(q.choices[i]) : ''; - btn.textContent = labels[i] + (ch ? (': ' + ch.slice(0, 96)) : ''); - } + if (!btn) continue; + const ch = (q.choices && q.choices[i]) ? String(q.choices[i]) : ''; + const letterEl = btn.querySelector('.qbc-letter'); + const txtEl = btn.querySelector('.qbc-text'); + const markEl = btn.querySelector('.qbc-mark'); + if (letterEl) letterEl.textContent = labels[i]; + if (txtEl) txtEl.textContent = ch; + if (markEl) { markEl.removeAttribute('src'); markEl.alt = ''; } + btn.classList.remove('is-correct', 'is-wrong', 'is-locked'); + btn.disabled = false; } + quizBattleChoiceLocked = false; ov.classList.remove('is-hidden'); ov.setAttribute('aria-hidden', 'false'); } function trySubmitQuizBattleChoice(idx) { + if (quizBattleChoiceLocked) return; if (quizBattleModalCompId == null || !mapData || !isQuizBattle()) return; const compId = quizBattleModalCompId; const pool = quizBattleMcqPool; @@ -13751,6 +13855,34 @@ const q = pool[(compId - 1) % pool.length]; if (!q) return; const ok = Number(q.correctIndex) === Number(idx); + /* ตอบครั้งเดียวจบ — ผิดก็ "ผ่าน" และจำว่าผิด (ไม่ให้ตอบซ้ำ) · log ใช้ทำ MY RESULT (O/X) + accuracy */ + quizBattleAnswerLog.set(compId, { + qIndex: (compId - 1) % pool.length, + firstTry: ok, + correct: ok, + submittedIdx: idx, + q: q, + }); + quizBattlePassedComps.add(compId); /* ผ่านโดมนี้แล้ว (ถูกหรือผิดก็ผ่าน — ปลดล็อกเส้นทาง) */ + /* โชว์ผลถูก/ผิดบนตัวเลือกทันที (q-correct.png / q-wrong.png) แล้วล็อกกันกดซ้ำ */ + quizBattleChoiceLocked = true; + const ov = document.getElementById('quiz-battle-mcq-overlay'); + if (ov) { + ov.querySelectorAll('.quiz-battle-choice').forEach((b) => { b.classList.add('is-locked'); b.disabled = true; }); + const setMark = (i, kind) => { + const b = ov.querySelector('.quiz-battle-choice[data-idx="' + i + '"]'); + if (!b) return; + b.classList.add(kind === 'correct' ? 'is-correct' : 'is-wrong'); + const m = b.querySelector('.qbc-mark'); + if (m) m.src = BASE + '/img/qb-ui/' + (kind === 'correct' ? 'q-correct.png' : 'q-wrong.png'); + }; + if (ok) { + setMark(idx, 'correct'); + } else { + setMark(idx, 'wrong'); + setMark(Number(q.correctIndex), 'correct'); /* เฉลยคำตอบที่ถูก */ + } + } if (ok) { quizBattleAnsweredComps.add(compId); if (typeof socket !== 'undefined' && socket && socket.connected) { @@ -13761,12 +13893,343 @@ playLiveQuizScores[myId] = (playLiveQuizScores[myId] || 0) + 1; renderPlayQuizScoreboard(playLiveQuizScores); } + submitQuizBattleLeaderboardScore(); flashQuizBattleFeedback('ถูกต้อง · +1 · ทางไปข้างหน้าเปิดแล้ว', true); } else { - flashQuizBattleFeedback('ยังไม่ถูก — ลองใหม่ (กด E อีกครั้ง)', false); + flashQuizBattleFeedback('ตอบผิด — ผ่านได้เลย (บันทึกว่าผิด) ไม่ต้องตอบซ้ำ', false); } - quizBattleModalCompId = null; - hideQuizBattleMcqModal(); + saveQuizBattleProgress(); + /* ปิด popup แล้วเช็คจบ (ทั้งถูกและผิด) — ผิดหน่วงนานขึ้นให้เห็นเฉลยก่อน */ + setTimeout(() => { + quizBattleModalCompId = null; + hideQuizBattleMcqModal(); + const totalComps = quizBattleTotalCompsPlay(); + if (!quizBattleCompletedShown && totalComps > 0 && quizBattlePassedComps.size >= totalComps) { + quizBattleCompletedShown = true; + setTimeout(openQuizBattleCompleted, 280); + } + }, ok ? 950 : 1300); + } + + /** + * ชื่อผู้เล่นสำหรับ leaderboard/ranking — ผูกกับชื่อที่ตั้งใน Main-Lobby + * (localStorage 'roomLobbyDisplayName' → 'playerName' ผ่าน readStoredDisplayName / jdReadDisplayName) + * ก่อน fallback ไป me.nickname / ?nick= เพื่อให้ตรงกับโปรไฟล์เดียวกันทุกหน้า + */ + function quizBattlePlayerDisplayName() { + let stored = ''; + try { + if (typeof window.jdReadDisplayName === 'function') { + const v = String(window.jdReadDisplayName() || '').trim(); + if (v && v !== 'MONE') stored = v; /* 'MONE' = ค่า default เมื่อยังไม่ตั้งชื่อ → ไม่ถือว่าตั้งแล้ว */ + } + } catch (e) { /* ignore */ } + if (!stored) stored = readStoredDisplayName(); + const name = stored || (me && me.nickname) || nick || 'ผู้เล่น'; + return String(name || 'ผู้เล่น').trim().slice(0, 24) || 'ผู้เล่น'; + } + + /** ส่งคะแนน (จำนวนตอบถูก) ขึ้น global leaderboard ของห้อง/หมวด */ + function submitQuizBattleLeaderboardScore() { + if (!isQuizBattle() || !socket || !socket.connected) return; + const roomNo = quizBattleRoomNoPlay(); + if (roomNo <= 0) return; + const score = quizBattleAnsweredComps ? quizBattleAnsweredComps.size : 0; + try { + socket.emit('qb-leaderboard-submit', { + roomId: 'qbroom' + roomNo, + name: quizBattlePlayerDisplayName(), + score: score, + characterId: me.characterId || getPlayCharacterId() || '', + }); + } catch (e) { /* ignore */ } + quizBattleScoreSubmittedAt = Date.now(); + } + + /* ===== Quiz Battle: progress persistence (resume ต่อจากเดิม) ===== */ + function quizBattleProgressKey() { + const roomNo = quizBattleRoomNoPlay(); + const roomId = 'qbroom' + (roomNo > 0 ? roomNo : 1); + return 'qbProgress:' + roomId + ':' + quizBattlePlayerDisplayName(); + } + function saveQuizBattleProgress() { + if (!isQuizBattle()) return; + try { + const passed = []; + quizBattleAnswerLog.forEach((v, c) => { + passed.push({ c: c, qi: v.qIndex, ft: v.firstTry ? 1 : 0, ok: v.correct ? 1 : 0, idx: v.submittedIdx }); + }); + const nowMs = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); + const elapsed = quizBattleSessionStartMs ? (nowMs - quizBattleSessionStartMs) : 0; + const data = { + passed: passed, + pos: (me && Number.isFinite(me.x) && Number.isFinite(me.y)) ? { x: me.x, y: me.y } : null, + elapsed: Math.max(0, Math.round(elapsed)), + ts: Date.now(), + }; + localStorage.setItem(quizBattleProgressKey(), JSON.stringify(data)); + } catch (e) { /* ignore */ } + } + function loadQuizBattleProgress() { + try { + const raw = localStorage.getItem(quizBattleProgressKey()); + return raw ? JSON.parse(raw) : null; + } catch (e) { return null; } + } + /** คืนสถานะที่เคยเล่น (โดมที่ผ่าน/คำตอบ/เวลา) + ตำแหน่งล่าสุด — เรียกใน setupPlayQuizBattleUi */ + function restoreQuizBattleProgress() { + const data = loadQuizBattleProgress(); + if (!data || !Array.isArray(data.passed)) return; + data.passed.forEach((p) => { + if (!p || !(p.c > 0)) return; + quizBattleAnswerLog.set(p.c, { + qIndex: (p.qi != null ? p.qi : 0), + firstTry: !!p.ft, + correct: !!p.ok, + submittedIdx: p.idx, + q: null, /* q ผูกใหม่จาก pool ตอนเปิด MY RESULT */ + }); + quizBattlePassedComps.add(p.c); + if (p.ok) quizBattleAnsweredComps.add(p.c); + }); + /* เวลาเดินต่อ (offset session start ด้วยเวลาที่เคยใช้) */ + if (data.elapsed > 0) { + const nowMs = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); + quizBattleSessionStartMs = nowMs - data.elapsed; + } + /* sync score HUD + leaderboard ให้ตรงกับที่เคยทำ */ + if (myId != null) { + if (!playLiveQuizScores) playLiveQuizScores = {}; + playLiveQuizScores[myId] = quizBattleAnsweredComps.size; + renderPlayQuizScoreboard(playLiveQuizScores); + } + /* ย้ายตัวไปจุดเดิม (ถ้ายังเดินได้) แล้วบอกเซิร์ฟเวอร์ */ + if (data.pos && Number.isFinite(data.pos.x) && Number.isFinite(data.pos.y)) { + const px = data.pos.x, py = data.pos.y; + setTimeout(() => { + try { + if (!isQuizBattle() || !me) return; + if (typeof canWalkLikeLobby === 'function' && !canWalkLikeLobby(px, py)) return; + me.x = px; me.y = py; + if (socket && socket.connected) socket.emit('move', { x: me.x, y: me.y, direction: me.direction }); + draw(); + } catch (e) { /* ignore */ } + }, 350); + } + } + + /* ===== Quiz Battle: MY RESULT + RANKING popups (Stage 2) ===== */ + function qbEscHtml(s) { + return String(s == null ? '' : s) + .replace(/&/g, '&').replace(//g, '>') + .replace(/"/g, '"').replace(/'/g, '''); + } + function qbFmtDuration(ms) { + const s = Math.max(0, Math.round((ms || 0) / 1000)); + const m = Math.floor(s / 60), ss = s % 60; + if (m >= 60) { const h = Math.floor(m / 60); return h + 'h ' + (m % 60) + 'm'; } + if (m > 0) return m + 'm ' + ss + 's'; + return ss + ' s'; + } + /** จำนวนโดม (สถานีคำถาม) ทั้งหมดของแมป = ค่า comp สูงสุดใน quizBattleDomeComp */ + function quizBattleTotalCompsPlay() { + const md = mapData; + if (md && md.quizBattleDomeComp && Array.isArray(md.quizBattleDomeComp)) { + let mx = 0; + const dc = md.quizBattleDomeComp; + for (let y = 0; y < dc.length; y++) { + const row = dc[y]; if (!row) continue; + for (let x = 0; x < row.length; x++) { const v = row[x] | 0; if (v > mx) mx = v; } + } + if (mx > 0) return mx; + } + return quizBattleMcqPool.length || 0; + } + function qbSetText(id, txt) { const el = document.getElementById(id); if (el) el.textContent = txt; } + function qbAvatarSrcForCharacter(cid) { + if (!cid) return ''; + try { ensurePlayLobbyIdleAvatarImage(cid); } catch (e) { /* ignore */ } + const src = playLobbyIdleAvatarSrcForCharacter(cid); + if (src) return src; + const im = getCharacterImg(cid, 'down'); + return (im && im.src) ? im.src : ''; + } + + function openQuizBattleMyResult() { + if (!isQuizBattle()) return; + const pop = document.getElementById('qb-myresult-popup'); + if (!pop) return; + const total = quizBattleTotalCompsPlay(); + const passed = quizBattlePassedComps ? quizBattlePassedComps.size : 0; + let firstCorrect = 0, attempted = 0; + quizBattleAnswerLog.forEach((v) => { attempted++; if (v.firstTry) firstCorrect++; }); + const accPct = attempted ? Math.round((firstCorrect / attempted) * 100) : 0; + const progPct = total ? Math.round((passed / total) * 100) : 0; + const nowMs = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); + const elapsed = quizBattleSessionStartMs ? (nowMs - quizBattleSessionStartMs) : 0; + qbSetText('qb-mr-accuracy', accPct + '%'); + qbSetText('qb-mr-accuracy-sub', '(' + firstCorrect + '/' + attempted + ')'); + qbSetText('qb-mr-progress', progPct + '%'); + qbSetText('qb-mr-progress-sub', '(' + passed + '/' + total + ')'); + qbSetText('qb-mr-time', qbFmtDuration(elapsed)); + const grid = document.getElementById('qb-mr-grid'); + if (grid) { + const cells = Math.max(total, attempted, 0); + let html = ''; + for (let c = 1; c <= cells; c++) { + const log = quizBattleAnswerLog.get(c); + let cls = 'qb-mr-cell', mark = ''; + if (!log) { cls += ' is-unanswered'; } + else if (log.correct) { cls += ' is-correct'; mark = 'O'; } + else { cls += ' is-wrong'; mark = 'X'; } + html += '
' + c + '' + mark + '
'; + } + grid.innerHTML = html; + } + const det = document.getElementById('qb-mr-detail'); + if (det) { + const entries = Array.from(quizBattleAnswerLog.entries()).sort((a, b) => a[0] - b[0]); + if (!entries.length) { + det.innerHTML = '
ยังไม่ได้ตอบคำถาม — เดินเข้าโดมแล้วกด E เพื่อเริ่ม
'; + } else { + const letters = ['A', 'B', 'C']; + let html = ''; + entries.forEach(function (pair) { + const cid = pair[0], log = pair[1]; + const q = log.q || quizBattleMcqPool[log.qIndex] || {}; + const choices = Array.isArray(q.choices) ? q.choices : []; + const markImg = log.correct ? 'q-correct.png' : 'q-wrong.png'; + html += '
'; + html += '
ข้อ ' + cid + '
'; + html += '
' + qbEscHtml(q.text || '') + '
'; + choices.forEach(function (ch, i) { + let ocls = 'qb-mr-q-opt'; + if (i === Number(q.correctIndex)) ocls += ' is-correct'; + else if (i === Number(log.submittedIdx) && !log.correct) ocls += ' is-chosen-wrong'; + html += '
' + letters[i] + '. ' + qbEscHtml(ch) + '
'; + }); + html += '
'; + }); + det.innerHTML = html; + } + det.scrollTop = 0; + } + pop.classList.remove('is-hidden'); + pop.setAttribute('aria-hidden', 'false'); + } + + function renderQuizBattleRanking(data) { + const top = (data && Array.isArray(data.top)) ? data.top : []; + const meRow = data && data.me ? data.me : null; + const podium = document.getElementById('qb-rank-podium'); + if (podium) { + const order = [1, 0, 2]; /* แสดง 2-1-3 */ + let html = ''; + order.forEach(function (idx) { + const e = top[idx]; + if (!e) return; + const rank = idx + 1; + const av = qbAvatarSrcForCharacter(e.characterId); + html += '
'; + html += '
' + (av ? '' : '') + '
'; + html += '
' + rank + '
'; + html += '
' + qbEscHtml(e.name || '-') + '
'; + html += '
' + (e.score | 0) + '
'; + html += '
'; + }); + podium.innerHTML = html || '
ยังไม่มีคะแนน
'; + } + const list = document.getElementById('qb-rank-list'); + if (list) { + let html = ''; + for (let i = 3; i < top.length && i < 50; i++) { + const e = top[i]; + html += '
' + (e.rank || (i + 1)) + '' + + '' + qbEscHtml(e.name || '-') + '' + + '' + (e.score | 0) + '
'; + } + list.innerHTML = html; + } + const meBox = document.getElementById('qb-rank-me'); + if (meBox) { + if (meRow && (meRow.rank || 0) > 0) { + meBox.innerHTML = '
' + (meRow.rank || '-') + '' + + '' + qbEscHtml(meRow.name || 'คุณ') + ' (คุณ)' + + '' + (meRow.score | 0) + '
'; + } else { + meBox.innerHTML = ''; + } + } + } + + function openQuizBattleRanking() { + if (!isQuizBattle()) return; + const pop = document.getElementById('qb-ranking-popup'); + if (!pop) return; + /* ส่งคะแนนล่าสุดก่อน เพื่อให้อันดับตัวเองเป็นปัจจุบัน */ + try { submitQuizBattleLeaderboardScore(); } catch (e) { /* ignore */ } + const roomNo = quizBattleRoomNoPlay(); + const roomId = 'qbroom' + (roomNo > 0 ? roomNo : 1); + const myName = quizBattlePlayerDisplayName(); + const list = document.getElementById('qb-rank-list'); + if (list) list.innerHTML = '
กำลังโหลดอันดับ…
'; + const podium = document.getElementById('qb-rank-podium'); + if (podium) podium.innerHTML = ''; + const meBox = document.getElementById('qb-rank-me'); + if (meBox) meBox.innerHTML = ''; + pop.classList.remove('is-hidden'); + pop.setAttribute('aria-hidden', 'false'); + if (socket && socket.connected) { + try { + socket.emit('qb-leaderboard-get', { roomId: roomId, name: myName }, function (resp) { + renderQuizBattleRanking(resp || {}); + }); + } catch (e) { + if (list) list.innerHTML = '
โหลดอันดับไม่สำเร็จ
'; + } + } else if (list) { + list.innerHTML = '
ยังไม่ได้เชื่อมต่อเซิร์ฟเวอร์
'; + } + } + + function closeQuizBattlePopup(which) { + let id = 'qb-myresult-popup'; + if (which === 'ranking') id = 'qb-ranking-popup'; + else if (which === 'completed') id = 'qb-completed-popup'; + const pop = document.getElementById(id); + if (!pop) return; + pop.classList.add('is-hidden'); + pop.setAttribute('aria-hidden', 'true'); + } + + /** popup "Completed" (popup-result.png) — สรุป Correct / Time Taken / My Rank เมื่อตอบครบทุกโดม */ + function openQuizBattleCompleted() { + if (!isQuizBattle()) return; + const pop = document.getElementById('qb-completed-popup'); + if (!pop) return; + const total = quizBattleTotalCompsPlay(); + let firstCorrect = 0; + quizBattleAnswerLog.forEach((v) => { if (v.firstTry) firstCorrect++; }); + const nowMs = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); + const elapsed = quizBattleSessionStartMs ? (nowMs - quizBattleSessionStartMs) : 0; + qbSetText('qb-cp-correct', firstCorrect + ' / ' + total); + qbSetText('qb-cp-time', qbFmtDuration(elapsed)); + qbSetText('qb-cp-rank', '—'); + /* ส่งคะแนนล่าสุด แล้วดึงอันดับมาแสดง My Rank */ + try { submitQuizBattleLeaderboardScore(); } catch (e) { /* ignore */ } + const roomNo = quizBattleRoomNoPlay(); + const roomId = 'qbroom' + (roomNo > 0 ? roomNo : 1); + const myName = quizBattlePlayerDisplayName(); + if (socket && socket.connected) { + try { + socket.emit('qb-leaderboard-get', { roomId: roomId, name: myName }, function (resp) { + const rank = resp && resp.me && resp.me.rank ? ('#' + resp.me.rank) : '—'; + qbSetText('qb-cp-rank', rank); + }); + } catch (e) { /* ignore */ } + } + pop.classList.remove('is-hidden'); + pop.setAttribute('aria-hidden', 'false'); } /** หา comp โดมที่ตัวละครเหยียบอยู่ — เช็คหลายจุด + ช่องติดโดม ให้เด้งง่ายเมื่อถึงสถานี */ @@ -13790,7 +14253,7 @@ if (modalOpen) return; if (compNow === qbAutoLastComp) return; qbAutoLastComp = compNow; - if (quizBattleAnsweredComps.has(compNow)) return; + if (quizBattlePassedComps.has(compNow)) return; const pool = quizBattleMcqPool; if (!pool.length) { flashQuizBattleFeedback('ยังไม่มีคำถาม — บันทึกใน Admin → Quiz Battle แล้วรีเฟรช', false); @@ -13812,22 +14275,28 @@ ctx.arcTo(x, y, x + w, y, r); ctx.closePath(); } - /** หีบบนสถานีคำถาม — done=ปลดล็อก(เขียว+ติ๊ก) / ยังไม่ตอบ=ล็อก(น้ำตาล+กุญแจ) + เลขสถานี */ - function drawQuizBattleChest(ctx, cx, cy, size, done, num) { + /** หีบบนสถานีคำถาม — ตอบถูก=เขียว+ติ๊ก / ตอบผิด(ผ่านแล้ว)=แดง+กากบาท / ยังไม่ตอบ=ล็อก(น้ำตาล+กุญแจ) + เลขสถานี */ + function drawQuizBattleChest(ctx, cx, cy, size, done, num, wrong) { 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.shadowColor = done ? (wrong ? 'rgba(248,113,128,0.95)' : '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'; + ctx.fillStyle = done ? (wrong ? '#8a3340' : '#3f7d57') : '#8a5a2b'; qbRoundRect(ctx, x0, y0 + h * 0.34, w, h * 0.66, size * 0.08); ctx.fill(); - ctx.fillStyle = done ? '#57a875' : '#a86f33'; + ctx.fillStyle = done ? (wrong ? '#b3455a' : '#57a875') : '#a86f33'; qbRoundRect(ctx, x0, y0, w, h * 0.44, size * 0.1); ctx.fill(); ctx.shadowBlur = 0; - ctx.fillStyle = done ? '#d6f5e3' : '#f1c66a'; + ctx.fillStyle = done ? (wrong ? '#ffd6dc' : '#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) { + if (done && wrong) { + ctx.strokeStyle = '#fff0f2'; ctx.lineWidth = Math.max(2, size * 0.08); ctx.lineCap = 'round'; ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(cx - size * 0.12, cy - size * 0.10); ctx.lineTo(cx + size * 0.12, cy + size * 0.12); + ctx.moveTo(cx + size * 0.12, cy - size * 0.10); ctx.lineTo(cx - size * 0.12, cy + size * 0.12); + ctx.stroke(); + } else 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); @@ -13859,8 +14328,8 @@ flashQuizBattleFeedback('เข้าใกล้สถานีคำถาม (หีบ) แล้วกด E', false); return; } - if (quizBattleAnsweredComps.has(compId)) { - flashQuizBattleFeedback('ตอบโดมนี้ถูกแล้ว', false); + if (quizBattlePassedComps.has(compId)) { + flashQuizBattleFeedback('โดมนี้ผ่านแล้ว', false); return; } const pool = quizBattleMcqPool; @@ -13925,6 +14394,7 @@ function resetQuizBattlePlayState() { quizBattleMcqPool = []; quizBattleAnsweredComps = new Set(); + quizBattlePassedComps = new Set(); quizBattleModalCompId = null; hideQuizBattleMcqModal(); } @@ -13953,13 +14423,20 @@ : 'คำถามจาก Admin → Quiz Battle (battleQuizMcq) · ช่องโดมติดกัน = 1 ข้อ · ถูกแล้วได้ +1 ต่อโดม'; } quizBattleAnsweredComps = new Set(); + quizBattleAnswerLog = new Map(); + quizBattlePassedComps = new Set(); + quizBattleUserZoomMul = 1; + quizBattleSessionStartMs = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now(); quizBattleModalCompId = null; quizBattleMcqPool = []; + quizBattleCompletedShown = false; hideQuizBattleMcqModal(); playLiveQuizScores = {}; if (myId != null) playLiveQuizScores[myId] = 0; others.forEach((_, id) => { playLiveQuizScores[id] = 0; }); renderPlayQuizScoreboard(playLiveQuizScores); + /* คืนสถานะที่เคยเล่น (โดมที่ผ่าน/ตำแหน่งล่าสุด) — เล่นต่อจากเดิมไม่ต้องตอบซ้ำ */ + restoreQuizBattleProgress(); loadQuizBattleMcqPool().then(() => { const q2 = document.getElementById('quiz-game-question'); if (!q2) return; @@ -18161,22 +18638,32 @@ const stack = document.getElementById('play-canvas-stack'); if (!stack) return; const wheelZoomHandler = (e) => { - if (!previewMode || !editorEmbedReturn || !mapData) return; + if (!mapData) return; + const embedZoom = previewMode && editorEmbedReturn; + const qbZoom = isQuizBattle(); + if (!embedZoom && !qbZoom) return; if (isStackTowerEmbedZoomLockedPlay()) return; if (isQuizQuestionMissionHudActivePlay()) return; const t = e.target; if (t && typeof t.closest === 'function') { if (t.closest('button, input, textarea, select, a[href]')) return; } - /* ล้อธรรม / trackpad pinch มักไม่มี ctrl — ให้ซูมได้ใน embed; Ctrl/⌘+ล้อยังใช้ได้ */ + /* ล้อธรรม / trackpad pinch มักไม่มี ctrl — ให้ซูมได้; Ctrl/⌘+ล้อยังใช้ได้ */ e.preventDefault(); e.stopPropagation(); const raw = e.deltaMode === 1 ? e.deltaY * 14 : e.deltaMode === 2 ? e.deltaY * 320 : e.deltaY; const k = Math.exp(-raw * 0.002); - playEmbedUserZoomMul = Math.max( - PLAY_EMBED_USER_ZOOM_MIN, - Math.min(PLAY_EMBED_USER_ZOOM_MAX, playEmbedUserZoomMul * k), - ); + if (qbZoom) { + quizBattleUserZoomMul = Math.max( + PLAY_EMBED_USER_ZOOM_MIN, + Math.min(PLAY_EMBED_USER_ZOOM_MAX, quizBattleUserZoomMul * k), + ); + } else { + playEmbedUserZoomMul = Math.max( + PLAY_EMBED_USER_ZOOM_MIN, + Math.min(PLAY_EMBED_USER_ZOOM_MAX, playEmbedUserZoomMul * k), + ); + } draw(); }; stack.addEventListener('wheel', wheelZoomHandler, { passive: false, capture: true }); @@ -18532,8 +19019,8 @@ if (isQuizCarry() && quizCarryFootprintOverlapsHub(x, y)) return false; if (isQuizBattle() && quizBattlePathModeActive(mapData)) { if (!quizBattlePositionAllowedPlay(mapData, x, y)) return false; - if (!quizBattlePathGateAllowsPlay(mapData, x, y, quizBattleAnsweredComps)) { - quizBattleFlashGateBlocked(mapData, x, y, quizBattleAnsweredComps); + if (!quizBattlePathGateAllowsPlay(mapData, x, y, quizBattlePassedComps)) { + quizBattleFlashGateBlocked(mapData, x, y, quizBattlePassedComps); return false; } } @@ -18585,7 +19072,7 @@ if (isQuizBattle() && quizBattlePathModeActive(mapData)) { if (!quizBattlePositionAllowedPlay(mapData, x, y)) return false; if (o && isPreviewBotId(o.id || o.peerId)) { /* preview bots ไม่ล็อกประตู */ } - else if (!quizBattlePathGateAllowsPlay(mapData, x, y, quizBattleAnsweredComps)) return false; + else if (!quizBattlePathGateAllowsPlay(mapData, x, y, quizBattlePassedComps)) return false; } return true; } @@ -20504,6 +20991,9 @@ camX = qmc.cx; camY = qmc.cy; } + } else if (isQuizBattle()) { + /* บอร์ดควิซแนวตั้ง (20×40) — ล็อกกล้องกลางแนวนอน (ไม่ไถลซ้าย/ขวาตามผู้เล่น) เลื่อนตามแนวตั้งเท่านั้น ตรง mock */ + camX = (w * tileSize) / 2; } const gauntletGroupCam = getGauntletCrownHeistGroupCameraCenterPxPlay(tileSize, canvas.width, canvas.height, zDraw); if (gauntletGroupCam) { @@ -20779,8 +21269,9 @@ 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); + const passed = cid > 0 && quizBattlePassedComps.has(cid); + const wrong = passed && !quizBattleAnsweredComps.has(cid); + drawQuizBattleChest(ctx, sx + size / 2, sy + size / 2, size, passed, cid || 0, wrong); } } if (isStack()) { @@ -21405,6 +21896,7 @@ syncStackTowerDropButtonPlay(); syncStackTowerMissionDomHudPlay(); syncSpaceShooterLifeDomHudPlay(); + syncQuizBattleHudPlay(); } document.addEventListener('keydown', (e) => { @@ -21817,14 +22309,57 @@ window.location.replace(playDesignMainMenuHref()); } }); + (function wireQuizBattleHudButtons() { + /* EXIT → ออกห้อง กลับหน้าเลือกห้อง Quiz Battle */ + const exitBtn = document.getElementById('qb-hud-exit'); + if (exitBtn) { + exitBtn.addEventListener('click', () => { + try { saveQuizBattleProgress(); } catch (e) { /* ignore */ } + try { socket.emit('leave-space'); } catch (e) { /* ignore */ } + let href = '../Quiz-Battle/'; + try { if (typeof appPath === 'function') href = appPath('/Quiz-Battle/'); } catch (e2) { /* ignore */ } + window.location.href = href; + }); + } + /* MY RESULT → popup ผลตอบของฉัน */ + const myResultBtn = document.getElementById('qb-hud-myresult'); + if (myResultBtn) myResultBtn.addEventListener('click', function () { openQuizBattleMyResult(); }); + /* RANKING → popup อันดับ (global leaderboard) */ + const rankingBtn = document.getElementById('qb-hud-ranking'); + if (rankingBtn) rankingBtn.addEventListener('click', function () { openQuizBattleRanking(); }); + /* ZOOM เข้า/ออก ในฉาก */ + const applyQbZoom = function (mul) { + quizBattleUserZoomMul = Math.max(PLAY_EMBED_USER_ZOOM_MIN, Math.min(PLAY_EMBED_USER_ZOOM_MAX, quizBattleUserZoomMul * mul)); + try { draw(); } catch (e) { /* ignore */ } + }; + const zoomInBtn = document.getElementById('qb-hud-zoom-in'); + if (zoomInBtn) zoomInBtn.addEventListener('click', function () { applyQbZoom(1.2); }); + const zoomOutBtn = document.getElementById('qb-hud-zoom-out'); + if (zoomOutBtn) zoomOutBtn.addEventListener('click', function () { applyQbZoom(1 / 1.2); }); + /* ปิด popup: ปุ่ม X / backdrop (data-qb-close) */ + ['qb-myresult-popup', 'qb-ranking-popup', 'qb-completed-popup'].forEach(function (pid) { + const pop = document.getElementById(pid); + if (!pop) return; + pop.addEventListener('click', function (e) { + const t = e.target; + if (t && t.getAttribute && t.getAttribute('data-qb-close')) { + closeQuizBattlePopup(t.getAttribute('data-qb-close')); + } + }); + }); + document.addEventListener('keydown', function (e) { + if (e.key === 'Escape') { closeQuizBattlePopup('myresult'); closeQuizBattlePopup('ranking'); closeQuizBattlePopup('completed'); } + }); + })(); (function wireQuizBattleMcqModal() { const ov = document.getElementById('quiz-battle-mcq-overlay'); if (!ov) return; ov.addEventListener('click', (e) => { const t = e.target; if (!t) return; - if (t.classList && t.classList.contains('quiz-battle-choice')) { - const idx = parseInt(t.getAttribute('data-idx'), 10); + const choice = t.closest ? t.closest('.quiz-battle-choice') : null; + if (choice) { + const idx = parseInt(choice.getAttribute('data-idx'), 10); if (Number.isFinite(idx) && idx >= 0 && idx <= 2) trySubmitQuizBattleChoice(idx); return; } @@ -22106,7 +22641,7 @@ socket.emit('quiz-carry-lobby-ready', { ready: next }); }); })(); - window.addEventListener('beforeunload', () => socket.emit('leave-space')); + window.addEventListener('beforeunload', () => { try { saveQuizBattleProgress(); } catch (e) { /* ignore */ } socket.emit('leave-space'); }); window.addEventListener('resize', () => { if (!mapData || !canvas) return; resizeCanvas(); diff --git a/www/html/Game/public/play.html b/www/html/Game/public/play.html index 34127a7..bf0ad83 100644 --- a/www/html/Game/public/play.html +++ b/www/html/Game/public/play.html @@ -2123,6 +2123,157 @@ display: flex; align-items: center; gap: 10px; } .mg6-life-hud .mg6-life-hearts img { height: 52px; width: auto; } + /* ===== Quiz Battle in-game HUD — design plane 1920×1080 scale ตาม stage ===== */ + .qb-game-hud { + position: fixed; + width: 1920px; height: 1080px; + transform-origin: 0 0; + pointer-events: none; + z-index: 55; + font-family: 'NotoSansThai', system-ui, sans-serif; + } + .qb-game-hud.is-hidden { display: none !important; } + .qb-game-hud img { display: block; image-rendering: pixelated; } + .qb-game-hud button { pointer-events: auto; background: none; border: 0; padding: 0; cursor: pointer; } + .qb-game-hud button:active { transform: translateY(1px); } + /* header หมวด (tag-NN.png 389×135) ซ้ายบน */ + .qb-hud-tag { position: absolute; left: 26px; top: 18px; width: 389px; height: auto; } + /* PLAYERS กลางบน */ + .qb-hud-players { + position: absolute; left: 50%; top: 44px; transform: translateX(-50%); + font-weight: 800; font-size: 40px; line-height: 1; color: #e8f6ff; + letter-spacing: 0.04em; text-shadow: 0 2px 10px rgba(0,0,0,0.7), 0 0 18px rgba(70,200,255,0.5); + white-space: nowrap; + } + .qb-hud-players span { color: #7df9ff; } + /* SCORE — ซ้ายของ host avatar */ + .qb-hud-score { + position: absolute; right: 210px; top: 44px; + font-weight: 800; font-size: 40px; line-height: 1; color: #e8f6ff; + letter-spacing: 0.04em; text-shadow: 0 2px 10px rgba(0,0,0,0.7), 0 0 18px rgba(70,200,255,0.5); + white-space: nowrap; + } + .qb-hud-score span { color: #ffd93d; } + /* host avatar — กรอบ btn-profile-bg.png 159×157 + clip avatar ข้างใน (เหมือน Quiz-Battle/.qb-room-profile) */ + .qb-hud-host { + position: absolute; right: 18px; top: 14px; width: 159px; height: 157px; + background: url(/Game/img/btn-profile-bg.png) center/100% 100% no-repeat; + overflow: hidden; + } + .qb-hud-host-clip { + position: absolute; left: 18px; top: 10px; width: 124px; height: 118px; + overflow: hidden; border-radius: 12px; + } + .qb-hud-host-av { + position: absolute; left: 50%; top: 5px; width: 120%; height: auto; max-width: none; + object-fit: contain; object-position: center top; transform: translateX(-50%); + image-rendering: pixelated; + } + /* ปุ่มข้าง (btn-*.png 122×142) */ + .qb-hud-btn img { width: 108px; height: auto; } + .qb-hud-exit { position: absolute; left: 26px; top: 184px; } + .qb-hud-myresult { position: absolute; right: 30px; top: 240px; } + .qb-hud-ranking { position: absolute; right: 30px; top: 384px; } + /* mic ขวาล่าง (ตาม mockup) */ + .qb-hud-mic { position: absolute; right: 34px; bottom: 40px; } + .qb-hud-mic img { width: 96px; height: 96px; object-fit: contain; } + /* ปุ่มซูมเข้า/ออก (ซ้ายล่าง) */ + .qb-hud-zoom { position: absolute; left: 30px; bottom: 40px; display: flex; flex-direction: column; gap: 12px; } + .qb-hud-zoom-btn { width: 66px; height: 66px; border-radius: 16px; border: 2px solid rgba(96,210,255,0.7); background: rgba(16,34,56,0.85); color: #aef0ff; font-size: 38px; font-weight: 800; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 14px rgba(64,200,255,0.3); padding: 0; } + .qb-hud-zoom-btn:hover { border-color: rgba(96,210,255,1); background: rgba(24,48,74,0.95); } + .qb-hud-zoom-btn:active { transform: scale(0.94); } + /* ===== Quiz Battle popups (MY RESULT / RANKING) ===== */ + .qb-popup { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; font-family: 'Noto Sans Thai','Prompt',sans-serif; } + .qb-popup.is-hidden { display: none !important; } + .qb-popup-backdrop { position: absolute; inset: 0; background: rgba(2,8,20,0.74); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); } + .qb-popup-frame { position: relative; } + .qb-popup-close { position: absolute; background: transparent; border: 0; cursor: pointer; z-index: 6; } + /* ---- MY RESULT ---- */ + .qb-mr-frame { + width: min(92vw, 1160px); aspect-ratio: 1290/951; + background: url(/Game/img/qb-ui/popup-myresult.png) center/100% 100% no-repeat; + } + .qb-mr-frame .qb-popup-close { width: 6.6%; aspect-ratio: 1; right: 3%; top: 5.2%; } + .qb-mr-body { + position: absolute; left: 7.5%; right: 6.8%; top: 17.5%; bottom: 6.5%; + display: flex; flex-direction: column; gap: 2.2%; color: #eaf6ff; + } + .qb-mr-stats { display: grid; grid-template-columns: repeat(3,1fr); gap: 2.4%; flex: 0 0 auto; } + .qb-mr-stat { background: rgba(20,42,66,0.66); border: 1px solid rgba(96,210,255,0.42); border-radius: 12px; padding: 1.4% 2%; text-align: center; } + .qb-mr-stat-h { font-size: clamp(11px,1.15vw,16px); color: rgba(168,222,255,0.85); letter-spacing: .03em; } + .qb-mr-stat-v { font-size: clamp(16px,1.9vw,27px); font-weight: 800; color: #7fe9ff; margin-top: 2px; line-height: 1.1; } + .qb-mr-stat-v small { font-size: 58%; font-weight: 600; color: rgba(200,235,255,.78); } + .qb-mr-grid { display: grid; grid-template-columns: repeat(10,1fr); gap: .55%; flex: 0 0 auto; } + .qb-mr-cell { position: relative; aspect-ratio: 1; border-radius: 8px; background: rgba(16,34,54,0.55); border: 1px solid rgba(96,210,255,0.28); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; } + .qb-mr-cell.is-correct { border-color: rgba(64,210,140,0.7); background: rgba(24,60,44,0.5); } + .qb-mr-cell.is-wrong { border-color: rgba(232,90,110,0.7); background: rgba(64,26,34,0.5); } + .qb-mr-cell.is-unanswered { opacity: .42; } + .qb-mr-cell .qb-mr-n { font-size: clamp(9px,.85vw,13px); color: rgba(180,225,255,.82); line-height: 1; } + .qb-mr-cell .qb-mr-mark { width: 58%; height: auto; } + .qb-mr-detail { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 12px; display: flex; flex-direction: column; gap: 8px; } + .qb-mr-q { background: rgba(18,38,60,0.62); border: 1px solid rgba(96,210,255,0.28); border-radius: 10px; padding: 9px 13px; } + .qb-mr-q-head { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: clamp(12px,1.05vw,16px); color: #cfeeff; } + .qb-mr-q-head img { width: 20px; height: 20px; flex: 0 0 auto; } + .qb-mr-q-text { font-size: clamp(11px,1vw,15px); margin: 5px 0 7px; color: #dff1ff; } + .qb-mr-q-opt { font-size: clamp(10px,.92vw,14px); padding: 4px 9px; border-radius: 6px; margin: 3px 0; background: rgba(255,255,255,0.05); color: rgba(220,238,255,.85); } + .qb-mr-q-opt.is-correct { background: rgba(40,160,90,0.34); color: #bfffd6; font-weight: 600; } + .qb-mr-q-opt.is-chosen-wrong { background: rgba(195,62,74,0.36); color: #ffd0d4; font-weight: 600; } + .qb-mr-detail::-webkit-scrollbar, .qb-rank-list::-webkit-scrollbar { width: 11px; } + .qb-mr-detail::-webkit-scrollbar-track, .qb-rank-list::-webkit-scrollbar-track { background: url(/Game/img/qb-ui/q-scroll-bg.png) center/100% 100% no-repeat; } + .qb-mr-detail::-webkit-scrollbar-thumb, .qb-rank-list::-webkit-scrollbar-thumb { background: url(/Game/img/qb-ui/q-scroll-bar.png) center/100% 100% no-repeat; border-radius: 6px; } + /* ---- RANKING ---- */ + .qb-rank-frame { + position: relative; width: min(88vw, 820px); max-height: 88vh; padding: 30px 34px 30px; box-sizing: border-box; + background: linear-gradient(180deg, rgba(18,40,64,0.98), rgba(11,24,42,0.98)); + border: 2px solid rgba(96,210,255,0.85); border-radius: 22px; + box-shadow: 0 0 34px rgba(64,200,255,0.45), inset 0 0 22px rgba(64,200,255,0.16); + display: flex; flex-direction: column; color: #eaf6ff; + } + .qb-rank-title { position: absolute; left: 50%; top: -26px; transform: translateX(-50%); background: linear-gradient(180deg,#0c2238,#0a1c30); border: 2px solid rgba(96,210,255,0.9); border-radius: 14px; padding: 9px 48px; font-size: clamp(18px,2vw,28px); font-weight: 800; color: #aef0ff; letter-spacing: .05em; box-shadow: 0 0 18px rgba(64,200,255,0.5); white-space: nowrap; } + .qb-rank-frame .qb-popup-close { width: 46px; height: 46px; right: 6px; top: 6px; border-radius: 10px; } + .qb-rank-frame .qb-popup-close::before, .qb-rank-frame .qb-popup-close::after { content: ''; position: absolute; left: 50%; top: 50%; width: 26px; height: 4px; background: #8fe7ff; border-radius: 2px; box-shadow: 0 0 8px rgba(96,210,255,0.7); } + .qb-rank-frame .qb-popup-close::before { transform: translate(-50%,-50%) rotate(45deg); } + .qb-rank-frame .qb-popup-close::after { transform: translate(-50%,-50%) rotate(-45deg); } + .qb-rank-body { display: flex; flex-direction: column; min-height: 0; margin-top: 14px; } + .qb-rank-podium { display: flex; align-items: flex-end; justify-content: center; gap: 16px; margin-bottom: 16px; flex: 0 0 auto; } + .qb-rank-pod { display: flex; flex-direction: column; align-items: center; } + .qb-rank-pod-av { border-radius: 50%; background: rgba(12,30,50,0.9); border: 3px solid rgba(96,210,255,0.7); overflow: hidden; display: flex; align-items: flex-end; justify-content: center; } + .qb-rank-pod-av img { width: 100%; height: 100%; object-fit: cover; object-position: center top; } + .qb-rank-pod-1 .qb-rank-pod-av { width: 108px; height: 108px; border-color: #ffd34d; box-shadow: 0 0 18px rgba(255,200,60,0.6); } + .qb-rank-pod-2 .qb-rank-pod-av { width: 86px; height: 86px; border-color: #cfe2ff; } + .qb-rank-pod-3 .qb-rank-pod-av { width: 86px; height: 86px; border-color: #ff9d6b; } + .qb-rank-pod-badge { margin-top: -14px; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 15px; color: #06121f; } + .qb-rank-pod-1 .qb-rank-pod-badge { background: #ffd34d; } + .qb-rank-pod-2 .qb-rank-pod-badge { background: #cfe2ff; } + .qb-rank-pod-3 .qb-rank-pod-badge { background: #ff9d6b; } + .qb-rank-pod-name { font-size: clamp(11px,1vw,14px); font-weight: 700; margin-top: 6px; max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; } + .qb-rank-pod-score { font-size: clamp(11px,1vw,15px); color: #7fe9ff; font-weight: 800; } + .qb-rank-listhead, .qb-rank-row { display: grid; grid-template-columns: 64px 1fr 90px; align-items: center; padding: 7px 14px; } + .qb-rank-listhead { color: rgba(168,222,255,0.8); font-size: clamp(10px,.9vw,13px); letter-spacing: .06em; border-bottom: 1px solid rgba(96,210,255,0.3); } + .qb-rank-c3 { text-align: right; } + .qb-rank-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; } + .qb-rank-row { background: rgba(18,38,60,0.5); border: 1px solid rgba(96,210,255,0.22); border-radius: 10px; margin: 5px 0; font-size: clamp(11px,1vw,15px); } + .qb-rank-row .qb-rank-c1 { font-weight: 800; color: #aef0ff; } + .qb-rank-row .qb-rank-c3 { font-weight: 800; color: #7fe9ff; } + .qb-rank-me { flex: 0 0 auto; margin-top: 8px; } + .qb-rank-me .qb-rank-row { background: rgba(96,210,255,0.18); border-color: rgba(96,210,255,0.7); box-shadow: 0 0 14px rgba(64,200,255,0.35); margin: 0; } + .qb-rank-empty { text-align: center; color: rgba(190,225,255,0.7); padding: 24px 0; font-size: 14px; } + /* ---- COMPLETED ---- */ + .qb-completed-frame { + width: min(92vw, 1180px); aspect-ratio: 1344/781; + background: url(/Game/img/qb-ui/popup-result.png) center/100% 100% no-repeat; + } + .qb-completed-frame .qb-popup-close { width: 6%; aspect-ratio: 1; right: 5%; top: 9%; } + .qb-completed-body { + position: absolute; left: 11.2%; right: 11.1%; top: 50.5%; height: 16%; + display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.86%; + } + .qb-cp-val { + display: flex; align-items: center; justify-content: center; text-align: center; + font-family: 'Noto Sans Thai','Prompt',sans-serif; font-weight: 800; + font-size: clamp(20px, 2.6vw, 40px); color: #7fe9ff; + text-shadow: 0 0 14px rgba(64,200,255,0.4); + } #play-cyber-hud.play-cyber-hud--question-mission .play-cyber-ss-meta { font-size: 0.5rem; letter-spacing: 0.06em; @@ -4423,68 +4574,119 @@ } .quiz-battle-mcq-card { position: relative; - max-width: min(92vw, 440px); - width: 100%; - background: linear-gradient(165deg, rgba(14, 18, 36, 0.97), rgba(8, 12, 28, 0.98)); - border: 1px solid rgba(0, 255, 240, 0.28); - border-radius: 14px; - padding: 1.1rem 1.15rem 1rem; - box-shadow: - 0 0 0 1px rgba(0, 0, 0, 0.5), - 0 0 40px rgba(0, 200, 255, 0.12); - font-family: 'Share Tech Mono', ui-monospace, monospace; + width: min(94vw, 640px); + box-sizing: border-box; + padding: 40px 34px 30px; + background: linear-gradient(180deg, rgba(20, 42, 68, 0.98), rgba(12, 24, 44, 0.98)); + border: 2px solid rgba(96, 210, 255, 0.85); + border-radius: 22px; + box-shadow: 0 0 34px rgba(64, 200, 255, 0.45), inset 0 0 22px rgba(64, 200, 255, 0.16); + font-family: 'Noto Sans Thai', 'Prompt', sans-serif; } .quiz-battle-mcq-title { - margin: 0 0 0.6rem; - font-family: 'Orbitron', sans-serif; - font-size: 0.78rem; + position: absolute; + left: 50%; + top: -24px; + transform: translateX(-50%); + margin: 0; + white-space: nowrap; + background: linear-gradient(180deg, #ff5bd0, #c01e88); + border: 2px solid rgba(255, 150, 225, 0.9); + border-radius: 14px; + padding: 8px 40px; + font-size: clamp(15px, 1.7vw, 22px); font-weight: 800; - letter-spacing: 0.16em; - color: #5cf0ff; - text-shadow: 0 0 12px rgba(92, 240, 255, 0.4); + letter-spacing: 0.08em; + color: #fff; + text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4); + box-shadow: 0 0 18px rgba(255, 90, 200, 0.5); } + #quiz-battle-mcq-close { + position: absolute; + right: 10px; + top: 10px; + width: 42px; + height: 42px; + padding: 0; + border: 0; + border-radius: 10px; + background: transparent; + cursor: pointer; + } + #quiz-battle-mcq-close::before, + #quiz-battle-mcq-close::after { + content: ''; + position: absolute; + left: 50%; + top: 50%; + width: 24px; + height: 4px; + background: #8fe7ff; + border-radius: 2px; + box-shadow: 0 0 8px rgba(96, 210, 255, 0.7); + } + #quiz-battle-mcq-close::before { transform: translate(-50%, -50%) rotate(45deg); } + #quiz-battle-mcq-close::after { transform: translate(-50%, -50%) rotate(-45deg); } .quiz-battle-mcq-text { - margin: 0 0 1rem; - font-size: clamp(0.9rem, 2.8vw, 1.05rem); + margin: 10px 0 18px; + padding: 14px 18px; + background: rgba(10, 24, 42, 0.7); + border: 1px solid rgba(96, 210, 255, 0.35); + border-radius: 12px; + font-size: clamp(15px, 1.6vw, 20px); line-height: 1.5; - color: #e2e8f0; - font-weight: 600; + color: #eaf6ff; + font-weight: 700; + text-align: center; } .quiz-battle-mcq-actions { display: flex; flex-direction: column; - gap: 0.45rem; - margin-bottom: 0.65rem; + gap: 12px; } .quiz-battle-choice { + position: relative; + display: flex; + align-items: center; + gap: 14px; width: 100%; text-align: left; - padding: 0.55rem 0.75rem; - border-radius: 8px; - border: 1px solid rgba(122, 162, 247, 0.45); - background: rgba(20, 28, 48, 0.95); - color: #c0caf5; - font-size: 0.82rem; + padding: 12px 16px; + border-radius: 14px; + border: 2px solid rgba(96, 210, 255, 0.5); + background: rgba(16, 34, 56, 0.92); + color: #dff1ff; + font-size: clamp(13px, 1.4vw, 17px); font-weight: 600; cursor: pointer; - transition: border-color 0.15s, box-shadow 0.15s; + transition: border-color 0.15s, box-shadow 0.15s, background 0.15s; } .quiz-battle-choice:hover { - border-color: rgba(0, 255, 240, 0.55); - box-shadow: 0 0 16px rgba(0, 200, 255, 0.15); + border-color: rgba(96, 210, 255, 0.95); + box-shadow: 0 0 16px rgba(64, 200, 255, 0.3); } - #quiz-battle-mcq-close { - width: 100%; - margin-top: 0.15rem; - padding: 0.45rem; - border: none; - border-radius: 8px; - background: rgba(60, 70, 100, 0.6); - color: #a9b1d6; - font-weight: 700; - cursor: pointer; - font-size: 0.78rem; + .quiz-battle-choice .qbc-letter { + flex: 0 0 auto; + width: 34px; + height: 34px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + background: rgba(96, 210, 255, 0.2); + border: 1px solid rgba(96, 210, 255, 0.7); + font-weight: 800; + color: #aef0ff; } + .quiz-battle-choice .qbc-text { flex: 1 1 auto; } + .quiz-battle-choice .qbc-mark { flex: 0 0 auto; width: 28px; height: 28px; display: none; } + .quiz-battle-choice.is-correct { border-color: #38d98a; background: rgba(28, 84, 58, 0.92); color: #d6ffe7; } + .quiz-battle-choice.is-correct .qbc-letter { background: rgba(56, 217, 138, 0.3); border-color: #38d98a; color: #d6ffe7; } + .quiz-battle-choice.is-wrong { border-color: #ff5a6e; background: rgba(86, 28, 38, 0.92); color: #ffd6db; } + .quiz-battle-choice.is-wrong .qbc-letter { background: rgba(255, 90, 110, 0.3); border-color: #ff5a6e; color: #ffd6db; } + .quiz-battle-choice.is-correct .qbc-mark, + .quiz-battle-choice.is-wrong .qbc-mark { display: block; } + .quiz-battle-choice.is-locked { pointer-events: none; } @@ -4618,6 +4820,82 @@
+ + + + + + + +