var tdv_sdk = {}; tdv_sdk.list = [ // ==================== PART 1: MULTIPLE CHOICE (Q1-Q10) - DỄ → TRUNG BÌNH ==================== { "id": 1, "question": "“Hi! My name is Rosy. I am in class 4B.” Who is speaking?", "options": ["Tim", "Billy", "Rosy", "Miss Jones"], "answer": "Rosy", "audio": "" }, { "id": 2, "question": "Which is a day of the week AFTER Thursday?", "options": ["Wednesday", "Friday", "Monday", "Tuesday"], "answer": "Friday", "audio": "" }, { "id": 3, "question": "Who works at the airport?", "options": ["Pilot", "Firefighter", "Doctor", "Police officer"], "answer": "Pilot", "audio": "" }, { "id": 4, "question": "Which place is NOT a workplace?", "options": ["Hospital", "Fire station", "Bedroom", "Police station"], "answer": "Bedroom", "audio": "" }, { "id": 5, "question": "Choose the correct sentence.", "options": [ "She work at the hospital.", "She works at the hospital", "She working at the hospital", "She worked at hospital" ], "answer": "She works at the hospital", "audio": "" }, { "id": 6, "question": "What do the children like at the beach?", "options": [ "Surf and play with a ball", "Study English", "Write in notebooks", "Paint pictures" ], "answer": "Surf and play with a ball", "audio": "" }, { "id": 7, "question": "Which number is BETWEEN 29 and 40?", "options": ["30", "20", "50", "29"], "answer": "30", "audio": "" }, { "id": 8, "question": "Which sentence is correct?", "options": [ "I have English on Wednesday.", "I has English on Wednesday.", "I have English in Wednesday.", "I am have English on Wednesday." ], "answer": "I have English on Wednesday.", "audio": "" }, { "id": 9, "question": "Which activity is done in a group?", "options": [ "Write in a notebook", "Play with a ball", "Eat a sandwich", "Take a photo" ], "answer": "Play with a ball", "audio": "" }, { "id": 10, "question": "“The firefighter helps people every day.” What does the firefighter do?", "options": [ "Eats sandwiches", "Helps people", "Goes to school", "Collects shells" ], "answer": "Helps people", "audio": "" }, { "id": 11, "question": "Which is NOT a fast food?", "options": ["Fries", "Pizza", "Soup", "Chicken"], "answer": "Soup", "audio": "" }, { "id": 12, "question": "The funny monkey wears a hat and eats a sandwich. Then it takes a photo. Which is TRUE?", "options": [ "The monkey eats a sandwich first", "The monkey takes a photo before eating", "The monkey wears a hat first", "The monkey writes in a notebook" ], "answer": "The monkey wears a hat first", "audio": "" }, { "id": 13, "question": "What does Billy like?", "options": ["His school", "His bag", "His teacher", "His toys"], "answer": "His school", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_hello_im_billy_i_am_in_class_4a_today_is_monday_i__b775daf7.mp3" }, { "id": 14, "question": "What is her job?", "options": ["Nurse", "Doctor", "Teacher", "Pilot"], "answer": "Nurse", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_my_mom_works_at_a_hospital_she_is_not_a_doctor_she_130967d2.mp3" }, { "id": 15, "question": "What does the monkey do last?", "options": [ "Eats a sandwich", "Takes a photo", "Wears a hat", "Writes in a notebook" ], "answer": "Takes a photo", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_the_monkey_wears_a_hat_and_a_scarf_it_eats_a_sandw_ba8a2f89.mp3" }, { "id": 16, "question": "Which food does the speaker prefer?", "options": ["Pizza", "Bubble tea", "Chicken", "Fries"], "answer": "Bubble tea", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_i_have_a_bubble_tea_my_brother_has_pizza_i_like_bu_a94a29b8.mp3" }, { "id": 17, "question": "Why does the speaker like P.E?", "options": [ "Because it is difficult", "Because he can read books", "Because he can run and play", "Because it is in the art room" ], "answer": "Because he can run and play", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_look_at_the_school_subjects_i_have_english_math_ar_2f34d40d.mp3" }, { "id": 18, "question": "Which sentence is TRUE?", "options": [ "He is a police officer", "He works at a fire station", "He works at a hospital", "He collects shells" ], "answer": "He works at a fire station", "audio": "https://audio.senaai.tech/audio/Sena_Voice1_my_dad_is_a_firefighter_he_works_at_the_fire_stati_abd4086a.mp3" }, { "id": 19, "question": "In which lunar month does Tet (Vietnamese New Year) usually begin?", "answer": "January", "audio": "" }, { "id": 20, "question": "Banh Chung is made from sticky rice, green beans, and ____?", "answer": "pork", "audio": "" }, { "id": 21, "question": "What flower is most popular during Tet in the North of Vietnam?", "answer": "peach blossom", "audio": "" }, { "id": 22, "question": "Who do Vietnamese usually give lucky money to during Tet?", "answer": "children", "audio": "" }, { "id": 23, "question": "Which square-shaped cake represents the Earth during Tet?", "answer": "Banh Chung", "audio": "" }, { "id": 24, "question": "Where do people usually go during Tet to pray for health and good luck?", "answer": "pagoda", "audio": "" } ]; tdv_sdk.currentIndex = 0; tdv_sdk.shuffleArray = function (Array) { for (let i = Array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [Array[i], Array[j]] = [Array[j], Array[i]]; } }; tdv_sdk.start = function () { tdv_sdk.currentIndex = 0; tdv_sdk.listquestion = []; tdv_sdk.totalquestion = tdv_sdk.list.length; for (let i = 0; i < tdv_sdk.totalquestion; i++) { tdv_sdk.listquestion.push(tdv_sdk.list[i]); } }; tdv_sdk.loadquestion = function () { if (tdv_sdk.currentIndex >= tdv_sdk.totalquestion) { console.log("🎉 Game Over! No more questions."); tdv_sdk.curQuestion = null; tdv_sdk.questionState = -1; return 0; } tdv_sdk.curQuestion = tdv_sdk.listquestion[tdv_sdk.currentIndex]; tdv_sdk.correctAnswer = tdv_sdk.curQuestion.answer; // ✅ CHỈ shuffle nếu có options (Multiple choice) if (Array.isArray(tdv_sdk.curQuestion.options)) { tdv_sdk.shuffleArray(tdv_sdk.curQuestion.options); } tdv_sdk.questionState = 0; return 1; }; // ==================== QUESTION STATE MACHINE ==================== // State: 0 = Roll dice, 1 = Chờ start timer, 2 = Đang đếm, 3 = Chờ hiện đáp án, 4 = Chờ đóng layer tdv_sdk.questionState = 0; // Lấy state hiện tại (dùng để check trong Construct) tdv_sdk.getQuestionState = function () { return tdv_sdk.questionState; }; // Set state (dùng khi cần set thủ công) tdv_sdk.setQuestionState = function (state) { tdv_sdk.questionState = state; console.log("📍 Question State set to:", state); return state; }; // Xử lý khi bấm Space - trả về state mới // questionState: 0 = Roll dice, 1 = Start timer, 2 = Đang đếm, 3 = Show answer, 4 = Close layer tdv_sdk.handleSpacePress = function () { switch (tdv_sdk.questionState) { case 0: // Space: Roll dice console.log("🎲 Space 0: Roll dice!"); return 0; case 1: // Space: Bắt đầu đếm giờ (chờ hết giờ mới được bấm tiếp) tdv_sdk.questionState = 2; gameTimer.resetQuestionTimer(); console.log("▶️ Space 1: Timer started!"); return 1; case 2: // Đang đếm giờ - Bấm Space sẽ dừng timer và hiện đáp án ngay gameTimer.stopTimer(); tdv_sdk.questionState = 3; console.log("⏹️ Space 2: Timer stopped! Show answer."); return 2; case 3: // Space: Hiện đáp án đúng tdv_sdk.questionState = 4; console.log("✅ Space 3: Show correct answer!"); return 3; case 4: // Space: Đóng layer câu hỏi // LƯU Ý: KHÔNG gọi nextQuestion() ở đây vì Construct đã gọi riêng tdv_sdk.questionState = 0; console.log("🚪 Space 4: Close question layer!"); return 4; default: return tdv_sdk.questionState; } }; // Gọi khi bắt đầu hiện câu hỏi (sau khi thỏ di chuyển xong) // QUAN TRỌNG: Reset timer về 15s và KHÔNG start - chờ Space mới start tdv_sdk.startQuestion = function () { // Dừng timer cũ nếu đang chạy gameTimer.stopTimer(); // Reset timer về giá trị ban đầu (15s) nhưng KHÔNG start gameTimer.currentTime = gameTimer.questionTime; // Set state = 1 (chờ Space để start timer) tdv_sdk.questionState = 1; console.log("❓ Question ready! Timer set to", gameTimer.questionTime, "s. Press Space to start."); return 1; }; // Gọi khi hết giờ (timer = 0) tdv_sdk.onTimeUp = function () { if (tdv_sdk.questionState === 2) { gameTimer.currentTime = 0; // Đảm bảo hiển thị 0 gameTimer.stopTimer(); tdv_sdk.questionState = 3; console.log("⏰ Time up! Press Space to see answer."); } return 3; }; // Gọi khi người chơi trả lời xong (chỉ gọi 1 lần khi đang đếm giờ) tdv_sdk.onAnswered = function () { // Chỉ xử lý nếu đang ở state 2 (đang đếm giờ) if (tdv_sdk.questionState !== 2) { console.log("⚠️ onAnswered skipped - already processed"); return tdv_sdk.questionState; } gameTimer.stopTimer(); tdv_sdk.questionState = 3; console.log("📝 Answered! Press Space to see answer."); return 3; }; // Check xem câu hỏi hiện tại có phải dạng NGHE không (audio là mảng) // Trả về 1 nếu là Listening Question (Q21-Q30), 0 nếu là câu hỏi thường tdv_sdk.isListeningQuestion = function () { if (!tdv_sdk.curQuestion) return 0; return Array.isArray(tdv_sdk.curQuestion.audio) ? 1 : 0; }; tdv_sdk.getCurQuestion = function () { return tdv_sdk.curQuestion.question; }; tdv_sdk.getCurOptions = function (index) { if (!tdv_sdk.curQuestion.options) return ""; return tdv_sdk.curQuestion.options[index]; }; // Tính scale phù hợp dựa trên độ dài text đáp án // Trả về giá trị scale từ 0.5 đến 1.0 // maxLength: Độ dài tối đa trước khi bắt đầu thu nhỏ (mặc định 12) tdv_sdk.getOptionScale = function (index, maxLength) { var text = tdv_sdk.curQuestion.options[index] || ""; var maxLen = maxLength || 12; // Bắt đầu thu nhỏ khi > 12 ký tự var minScale = 0.65; // Scale nhỏ nhất var maxScale = 1; // Scale lớn nhất var len = text.length; if (len <= maxLen) { return maxScale; // Giữ nguyên scale = 1 nếu text ngắn } // Tính toán: giảm dần từ 1.0 đến 0.5 theo độ dài var ratio = Math.max(0, 1 - (len - maxLen) / 25); var newScale = minScale + (maxScale - minScale) * ratio; // Làm tròn 2 chữ số thập phân return Math.round(Math.max(minScale, newScale) * 100) / 100; }; // Phiên bản linh hoạt hơn - tính scale tuyến tính // Điều chỉnh scale mạnh hơn cho text dài tdv_sdk.getAnswerScale = function (index, maxLen) { // Sử dụng getCurOptions thay vì getAnswerByIndex var answer = tdv_sdk.getCurOptions(index); if (!answer) return 1; var standardLen = maxLen || 8; // Độ dài chuẩn (giảm từ 10 xuống 8) var len = String(answer).length; // Scale mạnh hơn cho text dài if (len <= standardLen) return 1; // <= 8 ký tự: scale 1.0 if (len <= 10) return 0.9; // 9-10 ký tự if (len <= 12) return 0.85; // 11-12 ký tự if (len <= 14) return 0.8; // 13-14 ký tự (Lunar New Year) if (len <= 18) return 0.75; // 15-18 ký tự if (len <= 22) return 0.7; // 19-22 ký tự return 0.65; // > 22 ký tự: scale tối thiểu }; // HÀM MỚI: Nhận TEXT trực tiếp thay vì index (tránh lỗi LoopIndex) // Sử dụng: tdv_sdk.getTextScale("Lunar New Year") tdv_sdk.getTextScale = function (text, maxLen) { if (!text) return 1; var standardLen = maxLen || 8; var len = String(text).length; // Scale mạnh hơn cho text dài if (len <= standardLen) return 1; // <= 8 ký tự: scale 1.0 if (len <= 10) return 0.85; // 9-10 ký tự if (len <= 12) return 0.75; // 11-12 ký tự if (len <= 14) return 0.65; // 13-14 ký tự if (len <= 18) return 0.55; // 15-18 ký tự if (len <= 22) return 0.5; // 19-22 ký tự return 0.45; // > 22 ký tự: scale tối thiểu }; tdv_sdk.getCurCorrectOption = function () { return tdv_sdk.correctAnswer; }; tdv_sdk.getCorrectCount = function () { return tdv_sdk.answers; }; tdv_sdk.getCurImageUrl = function () { return tdv_sdk.curQuestion.url; }; tdv_sdk.nextQuestion = function () { tdv_sdk.currentIndex++; }; tdv_sdk.getCurIndex = function () { return tdv_sdk.currentIndex; }; // Alias cho getCurIndex (tương thích với các game khác) tdv_sdk.getCurrentLevel = function () { return tdv_sdk.currentIndex; }; tdv_sdk.getTotalQuestion = function () { return tdv_sdk.totalquestion; }; // Check xem còn câu hỏi không (trả về 1 nếu còn, 0 nếu hết) tdv_sdk.hasMoreQuestions = function () { return tdv_sdk.currentIndex < tdv_sdk.totalquestion ? 1 : 0; }; // Check xem đây có phải câu hỏi cuối cùng không (trả về 1 nếu đúng) tdv_sdk.isLastQuestion = function () { return tdv_sdk.currentIndex >= tdv_sdk.totalquestion - 1 ? 1 : 0; }; // Check xem game đã kết thúc chưa (trả về 1 nếu hết câu hỏi, 0 nếu còn) // Dùng trong Construct: If Browser.ExecJS("tdv_sdk.isGameOver()") = 1 → Game Over tdv_sdk.isGameOver = function () { return tdv_sdk.currentIndex >= tdv_sdk.totalquestion ? 1 : 0; }; // Lấy số câu hỏi còn lại tdv_sdk.getRemainingQuestions = function () { return Math.max(0, tdv_sdk.totalquestion - tdv_sdk.currentIndex); }; // Reset lại từ đầu (shuffle lại câu hỏi) tdv_sdk.reloadQuestions = function () { tdv_sdk.currentIndex = 0; tdv_sdk.listquestion = []; for (let i = 0; i < tdv_sdk.totalquestion; i++) { tdv_sdk.listquestion.push(tdv_sdk.list[i]); } console.log("🔄 Questions reloaded and shuffled!"); return 1; }; tdv_sdk.getId = function (index) { return tdv_sdk.list[index].id; }; tdv_sdk.getAnswers = function (index) { return tdv_sdk.answers[index]; }; // --- AUDIO: Hỗ trợ cả string đơn và mảng audio --- tdv_sdk.currentAudioQueue = []; tdv_sdk.currentAudioIndex = 0; tdv_sdk.playSound = function (name) { console.log(`Play sound: ${name}`); const audioSrc = `https://audio.senaai.vn/audio/en_female_1_${name.toLowerCase()}.mp3`; const audio = new Audio(audioSrc); audio.play(); }; // Phát audio câu hỏi (hỗ trợ cả string đơn và mảng) tdv_sdk.playSoundQuestion = function (rate) { // Dừng audio cũ nếu đang chạy if (window.audio && !window.audio.paused) { window.audio.pause(); window.audio.currentTime = 0; } tdv_sdk.currentAudioQueue = []; tdv_sdk.currentAudioIndex = 0; var audioSource = tdv_sdk.curQuestion.audio; var playbackRate = rate || 1; if (!audioSource) { console.log("Không có audio cho câu hỏi này."); return; } if (Array.isArray(audioSource)) { // Mảng audio (Hội thoại: context + question) tdv_sdk.currentAudioQueue = audioSource; tdv_sdk.playNextInQueue(playbackRate); } else { // Audio đơn tdv_sdk.playSingleAudio(audioSource, playbackRate); } }; tdv_sdk.playSingleAudio = function (src, rate) { var audio = new Audio(src); audio.playbackRate = rate; window.audio = audio; audio.play().catch(e => console.error("Lỗi phát audio:", e)); console.log(`Đang phát: ${src}`); }; tdv_sdk.playNextInQueue = function (rate) { if (tdv_sdk.currentAudioIndex >= tdv_sdk.currentAudioQueue.length) { console.log("Đã phát hết đoạn hội thoại."); return; } var src = tdv_sdk.currentAudioQueue[tdv_sdk.currentAudioIndex]; var audio = new Audio(src); audio.playbackRate = rate; window.audio = audio; audio.onended = function () { tdv_sdk.currentAudioIndex++; setTimeout(function () { tdv_sdk.playNextInQueue(rate); }, 300); }; audio.play().catch(e => console.error("Lỗi phát audio:", e)); console.log(`Đang phát đoạn ${tdv_sdk.currentAudioIndex + 1}: ${src}`); }; tdv_sdk.stopSound = function () { if (window.audio && !window.audio.paused) { window.audio.pause(); window.audio.currentTime = 0; } tdv_sdk.currentAudioQueue = []; tdv_sdk.currentAudioIndex = 0; }; // Tất cả 4 đáp án sẽ có cùng kích thước chữ tdv_sdk.getUniformScale = function () { if (!tdv_sdk.curQuestion) return 1; var options = tdv_sdk.curQuestion.options; var maxLen = 0; // Tìm độ dài của đáp án dài nhất for (var i = 0; i < options.length; i++) { var len = String(options[i] || "").length; if (len > maxLen) maxLen = len; } // Tính scale dựa trên đáp án dài nhất if (maxLen <= 8) return 1; if (maxLen <= 10) return 0.95; if (maxLen <= 12) return 0.9; if (maxLen <= 14) return 0.85; if (maxLen <= 18) return 0.8; if (maxLen <= 22) return 0.75; return 0.7; }; tdv_sdk.goHome = function () { window.location.href = "../"; }; // ==================== QUESTION TIMER (Mỗi câu hỏi 10 giây) ==================== var gameTimer = {}; gameTimer.questionTime = 10; // Thời gian mỗi câu hỏi (giây) gameTimer.currentTime = gameTimer.questionTime; gameTimer.isRunning = false; gameTimer.intervalId = null; // Bắt đầu đếm ngược cho câu hỏi hiện tại gameTimer.startTimer = function () { if (gameTimer.isRunning) { console.warn("Timer is already running."); return 0; } gameTimer.isRunning = true; gameTimer.intervalId = setInterval(function () { if (gameTimer.currentTime > 0) { gameTimer.currentTime--; } else { gameTimer.stopTimer(); console.log("⏰ Question time is up!"); } }, 1000); console.log("⏱️ Question timer started:", gameTimer.questionTime, "seconds."); return 1; }; gameTimer.stopTimer = function () { if (gameTimer.intervalId) { clearInterval(gameTimer.intervalId); gameTimer.intervalId = null; gameTimer.isRunning = false; console.log("Timer stopped."); } }; gameTimer.resetTimer = function () { gameTimer.stopTimer(); gameTimer.currentTime = gameTimer.questionTime; console.log("⏱️ Timer reset to:", gameTimer.questionTime, "seconds."); }; // Reset timer cho câu hỏi mới (gọi khi loadquestion) - CHỈ RESET, KHÔNG START gameTimer.prepareQuestionTimer = function () { gameTimer.stopTimer(); gameTimer.currentTime = gameTimer.questionTime; console.log("⏱️ Timer prepared:", gameTimer.questionTime, "seconds. Press Space to start."); return 1; }; // Reset VÀ start timer (gọi khi bấm Space) gameTimer.resetQuestionTimer = function () { gameTimer.stopTimer(); gameTimer.currentTime = gameTimer.questionTime; gameTimer.startTimer(); console.log("🔄 Timer started:", gameTimer.questionTime, "seconds."); return 1; }; // Set thời gian mỗi câu hỏi (mặc định 10 giây) gameTimer.setQuestionTime = function (seconds) { gameTimer.questionTime = seconds || 10; console.log("⚙️ Question time set to:", gameTimer.questionTime, "seconds."); return gameTimer.questionTime; }; gameTimer.getFormattedTime = function () { if (gameTimer.currentTime < 0) return "0:00"; const minutes = Math.floor(gameTimer.currentTime / 60); const seconds = gameTimer.currentTime % 60; const formattedSeconds = seconds < 10 ? '0' + seconds : seconds; return minutes + ':' + formattedSeconds; }; gameTimer.getCurrentTimeValue = function () { return gameTimer.currentTime; }; // Trả về thời gian hiển thị (luôn = 0 nếu đã hết giờ) gameTimer.getDisplayTime = function () { // Nếu đã hết giờ (state >= 3), luôn trả về 0 if (tdv_sdk.questionState >= 3) { return 0; } return Math.max(0, gameTimer.currentTime); }; gameTimer.pauseTimer = function () { if (gameTimer.isRunning) { clearInterval(gameTimer.intervalId); gameTimer.intervalId = null; gameTimer.isRunning = false; console.log("Timer paused at:", gameTimer.getFormattedTime()); return 1; } return 0; }; gameTimer.resumeTimer = function () { if (!gameTimer.isRunning && gameTimer.currentTime > 0) { gameTimer.isRunning = true; gameTimer.intervalId = setInterval(function () { if (gameTimer.currentTime > 0) { gameTimer.currentTime--; } else { gameTimer.stopTimer(); console.log("Time is up!"); } }, 1000); console.log("Timer resumed from:", gameTimer.getFormattedTime()); return 1; } return 0; }; // ==================== GAME SCORE ==================== var gameScore = {}; gameScore.currentScore = 0; gameScore.addScore = function (points) { const pts = parseInt(points) || 0; if (pts > 0) { gameScore.currentScore += pts; console.log(`Score added: ${pts}. New score: ${gameScore.currentScore}`); } return gameScore.currentScore; }; gameScore.resetScore = function () { gameScore.currentScore = 0; console.log("Score reset to 0."); return 0; }; gameScore.getScore = function () { return gameScore.currentScore; }; gameScore.deductScore = function (points) { const pts = parseInt(points) || 0; if (gameScore.currentScore >= pts) { gameScore.currentScore -= pts; console.log(`Score deducted: ${pts}. New score: ${gameScore.currentScore}`); } else { gameScore.currentScore = 0; console.log(`Score deducted. New score is 0.`); } return gameScore.currentScore; }; // ==================== GAME LIVES ==================== var gameLives = {}; gameLives.maxLives = 3; gameLives.currentLives = gameLives.maxLives; gameLives.resetLives = function () { gameLives.currentLives = gameLives.maxLives; console.log("Lives reset to:", gameLives.maxLives); return gameLives.currentLives; }; gameLives.loseLife = function () { if (gameLives.currentLives > 0) { gameLives.currentLives--; console.log("Lost 1 life. Remaining:", gameLives.currentLives); } else { console.log("No lives left. Game Over condition."); } return gameLives.currentLives; }; gameLives.getLives = function () { return gameLives.currentLives; }; // ==================== INSTRUCTIONS ==================== tdv_sdk.getQuizInstructions = function () { const instructions = " 🌟 HƯỚNG DẪN GAME: HÀNH TRÌNH CỦA THỎ 🌟\n\n" + "🎯 MỤC TIÊU:\n" + " Giúp chú thỏ đi hết hành trình và đến đích! Trả lời đúng các câu hỏi để ghi thật nhiều điểm trên đường đi.\n\n" + "🌀 CÁCH CHƠI:\n" + " 1. Lắc xúc xắc: Chạm vào xúc xắc để quay.\n" + " 2. Di chuyển: Chú thỏ sẽ đi theo số chấm xuất hiện trên xúc xắc.\n" + " 3. Trả lời câu hỏi: Khi chú thỏ dừng lại, chọn đáp án đúng hiển thị trên màn hình.\n" + " 4. Tiếp tục hành trình: Sau khi trả lời, bạn có thể quay lại xúc xắc ngay để đi tiếp.\n\n" + "💡 ĐIỂM SỐ VÀ THỬ THÁCH:\n" + " ✅ Đúng: +100 điểm.\n" + " ❌ Sai: Không bị trừ điểm hay phạt.\n" + " 🐺 Nguy hiểm: Nếu dừng ở ô **'SÓI'** (Wolf), bạn sẽ bị trừ 100 điểm ngay lập tức.\n\n" + "🍀 Cùng chú thỏ phiêu lưu, trả lời câu hỏi và ghi thật nhiều điểm trên hành trình nhé!"; return instructions; }; tdv_sdk.hasAudio = function () { if (!tdv_sdk.curQuestion) return 0; var audio = tdv_sdk.curQuestion.audio; // Check nếu là mảng và có item if (Array.isArray(audio) && audio.length > 0) return 1; // Check nếu là string và không rỗng if (typeof audio === 'string' && audio.trim() !== '') return 1; return 0; };