🎮ArcadeLab

🎙️ Interpreter's Showdown - Hot Word Challenge

by RocketGecko40
724 lines26.1 KB
▶ Play
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>🎙️ Interpreter's Showdown - Hot Word Challenge</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Poppins', 'Segoe UI', system-ui, -apple-system, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }

        /* Game Container */
        .game-container {
            max-width: 900px;
            width: 100%;
            background: rgba(255,255,255,0.1);
            backdrop-filter: blur(10px);
            border-radius: 48px;
            padding: 20px;
            box-shadow: 0 25px 50px -12px rgba(0,0,0,0.5);
            border: 1px solid rgba(255,255,255,0.2);
        }

        /* Header */
        .game-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 30px;
            flex-wrap: wrap;
            gap: 15px;
        }

        .score-board {
            background: #f9a826;
            padding: 12px 24px;
            border-radius: 60px;
            font-weight: bold;
            font-size: 1.5rem;
            color: #1a1a2e;
            box-shadow: 0 4px 15px rgba(249,168,38,0.3);
        }

        .question-counter {
            background: rgba(255,255,255,0.2);
            padding: 12px 24px;
            border-radius: 60px;
            font-weight: bold;
            font-size: 1.1rem;
            color: white;
        }

        .player-name-input {
            display: flex;
            gap: 10px;
            align-items: center;
        }

        .player-name-input input {
            padding: 10px 16px;
            border-radius: 60px;
            border: none;
            font-size: 1rem;
            background: white;
        }

        .player-name-input button {
            background: #4ecdc4;
            border: none;
            padding: 10px 20px;
            border-radius: 60px;
            font-weight: bold;
            cursor: pointer;
            transition: transform 0.2s;
        }

        .player-name-input button:hover {
            transform: scale(1.05);
        }

        /* Main Game Card */
        .game-card {
            background: white;
            border-radius: 32px;
            padding: 40px;
            margin-bottom: 20px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            min-height: 400px;
            display: flex;
            flex-direction: column;
        }

        /* Timer Bar */
        .timer-bar {
            height: 6px;
            background: #e0e0e0;
            border-radius: 3px;
            margin-bottom: 30px;
            overflow: hidden;
        }

        .timer-progress {
            height: 100%;
            width: 100%;
            background: linear-gradient(90deg, #f9a826, #e74c3c);
            border-radius: 3px;
            transition: width 0.1s linear;
        }

        /* Question Text */
        .question-text {
            font-size: 1.6rem;
            line-height: 1.4;
            margin-bottom: 30px;
            color: #1a1a2e;
            font-weight: 500;
        }

        .question-text.en {
            border-left: 5px solid #f9a826;
            padding-left: 20px;
            background: #fef9e6;
            border-radius: 16px;
            padding: 20px;
        }

        .question-text.zh {
            border-left: 5px solid #4ecdc4;
            padding-left: 20px;
            background: #e8f8f6;
            border-radius: 16px;
            padding: 20px;
        }

        /* Options Area */
        .options-area {
            flex-grow: 1;
        }

        .option-btn {
            width: 100%;
            padding: 16px 20px;
            margin-bottom: 12px;
            background: #f5f5f5;
            border: 2px solid #e0e0e0;
            border-radius: 60px;
            font-size: 1rem;
            text-align: left;
            cursor: pointer;
            transition: all 0.2s;
            font-family: inherit;
        }

        .option-btn:hover:not(:disabled) {
            background: #e8e8e8;
            transform: translateX(5px);
            border-color: #f9a826;
        }

        .option-btn.correct {
            background: #2ecc71;
            color: white;
            border-color: #27ae60;
        }

        .option-btn.wrong {
            background: #e74c3c;
            color: white;
            border-color: #c0392b;
        }

        .option-btn:disabled {
            cursor: not-allowed;
            opacity: 0.7;
        }

        /* Input Area for Interpreting */
        .interpreting-area {
            margin-top: 20px;
        }

        .interpreting-input {
            width: 100%;
            padding: 16px;
            border: 2px solid #e0e0e0;
            border-radius: 16px;
            font-size: 1rem;
            font-family: inherit;
            resize: vertical;
            min-height: 100px;
        }

        .submit-btn {
            margin-top: 15px;
            background: #f9a826;
            color: #1a1a2e;
            border: none;
            padding: 14px 28px;
            border-radius: 60px;
            font-weight: bold;
            font-size: 1rem;
            cursor: pointer;
            transition: all 0.2s;
        }

        .submit-btn:hover {
            background: #e67e22;
            transform: scale(1.02);
        }

        /* Feedback */
        .feedback {
            margin-top: 20px;
            padding: 16px;
            border-radius: 16px;
            font-weight: 500;
            animation: fadeIn 0.3s;
        }

        .feedback.correct-feedback {
            background: #d5f5e3;
            color: #27ae60;
            border-left: 5px solid #2ecc71;
        }

        .feedback.wrong-feedback {
            background: #fadbd8;
            color: #c0392b;
            border-left: 5px solid #e74c3c;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        /* Next Button */
        .next-btn {
            background: #4ecdc4;
            color: #1a1a2e;
            border: none;
            padding: 14px 28px;
            border-radius: 60px;
            font-weight: bold;
            font-size: 1.1rem;
            cursor: pointer;
            margin-top: 20px;
            transition: all 0.2s;
        }

        .next-btn:hover {
            background: #44b3aa;
            transform: scale(1.02);
        }

        /* Leaderboard */
        .leaderboard {
            background: rgba(255,255,255,0.95);
            border-radius: 24px;
            padding: 20px;
            margin-top: 20px;
        }

        .leaderboard h3 {
            color: #1a1a2e;
            margin-bottom: 15px;
            font-size: 1.3rem;
        }

        .leaderboard-list {
            list-style: none;
        }

        .leaderboard-list li {
            padding: 10px 15px;
            background: #f0f0f0;
            margin-bottom: 8px;
            border-radius: 12px;
            display: flex;
            justify-content: space-between;
            font-weight: 500;
        }

        .restart-btn {
            background: #e74c3c;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 60px;
            font-weight: bold;
            cursor: pointer;
            margin-top: 15px;
            width: 100%;
        }

        /* Utility */
        .hidden {
            display: none;
        }

        .game-complete {
            text-align: center;
        }

        .game-complete h2 {
            color: #f9a826;
            font-size: 2rem;
            margin-bottom: 20px;
        }

        @media (max-width: 600px) {
            .game-card {
                padding: 20px;
            }
            .question-text {
                font-size: 1.2rem;
            }
        }
    </style>
</head>
<body>
<div class="game-container" id="gameContainer">
    <div class="game-header">
        <div class="score-board">⭐ Score: <span id="score">0</span></div>
        <div class="question-counter">📋 Question <span id="currentQ">1</span>/<span id="totalQ">12</span></div>
        <div class="player-name-input">
            <input type="text" id="playerName" placeholder="Your name" value="Student">
            <button onclick="resetGame()">🔄 New Game</button>
        </div>
    </div>

    <div class="game-card" id="gameCard">
        <div class="timer-bar">
            <div class="timer-progress" id="timerProgress" style="width: 100%"></div>
        </div>
        <div id="dynamicContent"></div>
    </div>

    <div class="leaderboard" id="leaderboard">
        <h3>🏆 Leaderboard</h3>
        <ul class="leaderboard-list" id="leaderboardList">
            <li>👑 No players yet</li>
        </ul>
        <button class="restart-btn" onclick="resetGame()">🔄 Reset All Scores</button>
    </div>
</div>

<script>
    // ========== QUESTIONS DATABASE ==========
    const questions = [
        // --- TOPIC 1: World Data Organization ---
        {
            id: 1,
            topic: "🌍 World Data Organization",
            type: "vocab",
            question: "In the WDO news, what does 'inaugural' mean?",
            options: ["A. Final / 最终的", "B. First / 首次的, 成立的", "C. Secret / 秘密的", "D. Annual / 每年的"],
            correct: "B",
            explanation: "✅ 'Inaugural' means marking the beginning of something — '成立的', '首届的'. The 'inaugural assembly' was WDO's first meeting!",
            points: 10
        },
        {
            id: 2,
            topic: "🌍 World Data Organization",
            type: "knowledge",
            question: "What did WDO members do at their first general meeting? (Choose the ONE that is NOT correct)",
            options: ["A. Reviewed and adopted the charter", "B. Elected council members and board of supervisors", "C. Elected the organization's first president", "D. Approved key systems and regulations"],
            correct: "C",
            explanation: "⚠️ The text says they elected 'leadership' but not specifically 'president'. Trick question! Stay faithful to the source text.",
            points: 10
        },
        {
            id: 3,
            topic: "🌍 World Data Organization",
            type: "interpreting",
            question: "Interpret this sentence into Chinese (spoken or typed): 'The newly elected council held its inaugural meeting, electing the organization's leadership and approving key systems and regulations.'",
            isInterpreting: true,
            correctAnswer: "新当选的首届理事会召开第一次会议,选举产生组织负责人,审议通过组织重要制度和规定。",
            keywords: ["新当选", "首届理事会", "第一次会议", "选举", "组织负责人", "审议通过", "重要制度", "规定"],
            points: 20
        },
        // --- TOPIC 2: ZXMOTO ---
        {
            id: 4,
            topic: "🏍️ ZXMOTO (Zhang Xue Motorcycle)",
            type: "vocab",
            question: "What does 'consecutive' mean in 'won two consecutive SSP class titles'?",
            options: ["A. One after another without break / 连续不断的", "B. Total / 总共的", "C. Impressive / 令人印象深刻的", "D. Difficult / 困难的"],
            correct: "A",
            explanation: "✅ 'Consecutive' = back-to-back wins. ZXMOTO won Saturday AND Sunday — that's consecutive!",
            points: 10
        },
        {
            id: 5,
            topic: "🏍️ ZXMOTO (Zhang Xue Motorcycle)",
            type: "knowledge",
            question: "What historical achievement did ZXMOTO accomplish at WSBK in Portugal?",
            options: ["A. First Chinese team to participate", "B. First Chinese manufacturer to win consecutively, breaking欧美日 monopoly", "C. First electric motorcycle to win", "D. First time using a Chinese mechanic"],
            correct: "B",
            explanation: "✅ 'Breaking the decades-long monopoly of European, American and Japanese brands' — a historic moment for Chinese manufacturing!",
            points: 10
        },
        {
            id: 6,
            topic: "🏍️ ZXMOTO (Zhang Xue Motorcycle)",
            type: "interpreting",
            question: "Interpret this sentence into Chinese: 'Founded in 2024 by Zhang Xue, who started as a mechanic at the age of 14, the brand made history in just two years.'",
            isInterpreting: true,
            correctAnswer: "张雪14岁开始当修车学徒。这个2024年成立的品牌,仅用两年时间便登上世界舞台。",
            keywords: ["张雪", "14岁", "修车学徒/机械师", "2024年", "成立", "两年", "世界舞台/历史"],
            points: 20
        },
        // --- TOPIC 3: Fuel Surcharge ---
        {
            id: 7,
            topic: "✈️ Fuel Surcharge Increase",
            type: "vocab",
            question: "The word 'surcharge' means:",
            options: ["A. A discount / 折扣", "B. An extra fee / 附加费", "C. A refund / 退款", "D. A tax refund / 退税"],
            correct: "B",
            explanation: "✅ 'Surcharge' = '附加费' — an additional charge on top of the base price. Your plane ticket just got more expensive!",
            points: 10
        },
        {
            id: 8,
            topic: "✈️ Fuel Surcharge Increase",
            type: "knowledge",
            question: "How much will the fuel surcharge be for a 900km domestic flight after April 5?",
            options: ["A. 10 yuan", "B. 20 yuan", "C. 60 yuan", "D. 120 yuan"],
            correct: "D",
            explanation: "✅ Routes exceeding 800km → 120 yuan surcharge. Plus the 50 yuan airport fee = 170 yuan total extra!",
            points: 10
        },
        {
            id: 9,
            topic: "✈️ Fuel Surcharge Increase",
            type: "interpreting",
            question: "Interpret into Chinese: 'Following a broad increase in international flight fuel surcharges, domestic routes in China will see a fivefold rise in the fuel surcharge starting April 5.'",
            isInterpreting: true,
            correctAnswer: "继国际航线燃油附加费全面上调后,4月5日国内航线燃油附加费将上涨5倍。",
            keywords: ["国际航线", "燃油附加费", "全面上调", "国内航线", "4月5日", "5倍/五倍"],
            points: 20
        },
        // --- TOPIC 4: Henry Lee ---
        {
            id: 10,
            topic: "🔬 Dr. Henry Lee",
            type: "vocab",
            question: "What does 'forensic' refer to in 'forensic scientist'?",
            options: ["A. Related to forests / 森林的", "B. Related to legal/court evidence / 法医的, 法庭的", "C. Related to foreign countries / 外国的", "D. Related to future predictions / 预测的"],
            correct: "B",
            explanation: "✅ 'Forensic' comes from Latin 'forensis' meaning 'of the forum/court'. Dr. Lee was the world's most famous forensic scientist!",
            points: 10
        },
        {
            id: 11,
            topic: "🔬 Dr. Henry Lee",
            type: "knowledge",
            question: "Which statement about Dr. Henry Lee is TRUE?",
            options: ["A. He was born in the United States", "B. He worked on the O.J. Simpson case", "C. He founded the FBI", "D. He only worked in China"],
            correct: "B",
            explanation: "✅ Dr. Lee was born in Rugao, China (1938), worked on the famous O.J. Simpson case, and worked on 8,000+ cases in 46 countries!",
            points: 10
        },
        {
            id: 12,
            topic: "🔬 Dr. Henry Lee",
            type: "interpreting",
            question: "Interpret into Chinese: 'His contributions to forensic science and law enforcement are extraordinary and unmatched. His legacy lives on in the generations of students he impacted.'",
            isInterpreting: true,
            correctAnswer: "他对法医学和执法工作的贡献是非凡且无与伦比的。他的精神遗产在他影响的一代又一代学生中得以延续。",
            keywords: ["法医学", "执法", "非凡", "无与伦比", "遗产/精神", "一代又一代", "学生"],
            points: 20
        }
    ];

    // Game state
    let currentIndex = 0;
    let totalScore = 0;
    let timerInterval = null;
    let timeLeft = 20;
    let answerLocked = false;
    let currentPlayer = "Student";
    let leaderboard = [];

    // Load leaderboard from localStorage
    function loadLeaderboard() {
        const stored = localStorage.getItem("interpreterLeaderboard");
        if (stored) {
            leaderboard = JSON.parse(stored);
        } else {
            leaderboard = [];
        }
        renderLeaderboard();
    }

    function saveLeaderboard() {
        localStorage.setItem("interpreterLeaderboard", JSON.stringify(leaderboard));
    }

    function renderLeaderboard() {
        const listEl = document.getElementById("leaderboardList");
        if (!listEl) return;
        if (leaderboard.length === 0) {
            listEl.innerHTML = "<li>👑 No scores yet. Play a game!</li>";
            return;
        }
        const sorted = [...leaderboard].sort((a,b) => b.score - a.score).slice(0,8);
        listEl.innerHTML = sorted.map((entry, idx) => 
            `<li><span>${idx+1}. ${entry.name}</span><span>⭐ ${entry.score} pts</span></li>`
        ).join("");
    }

    function addScoreToLeaderboard(name, score) {
        leaderboard.push({ name: name, score: score, date: new Date().toLocaleDateString() });
        leaderboard = leaderboard.sort((a,b) => b.score - a.score).slice(0, 10);
        saveLeaderboard();
        renderLeaderboard();
    }

    function updateUI() {
        document.getElementById("score").innerText = totalScore;
        document.getElementById("currentQ").innerText = currentIndex + 1;
        document.getElementById("totalQ").innerText = questions.length;
    }

    function stopTimer() {
        if (timerInterval) {
            clearInterval(timerInterval);
            timerInterval = null;
        }
    }

    function startTimer() {
        stopTimer();
        timeLeft = 20;
        const progressBar = document.getElementById("timerProgress");
        timerInterval = setInterval(() => {
            if (!answerLocked) {
                timeLeft -= 0.1;
                const percent = Math.max(0, (timeLeft / 20) * 100);
                if (progressBar) progressBar.style.width = percent + "%";
                if (timeLeft <= 0) {
                    stopTimer();
                    if (!answerLocked) {
                        answerLocked = true;
                        showTimeoutFeedback();
                    }
                }
            }
        }, 100);
    }

    function showTimeoutFeedback() {
        const contentDiv = document.getElementById("dynamicContent");
        const feedbackDiv = document.createElement("div");
        feedbackDiv.className = "feedback wrong-feedback";
        feedbackDiv.innerHTML = `⏰ TIME'S UP! The correct answer was: ${questions[currentIndex].correctAnswer.substring(0, 100)}...`;
        contentDiv.appendChild(feedbackDiv);
        disableOptions();
        showNextButton();
    }

    function disableOptions() {
        const btns = document.querySelectorAll(".option-btn");
        btns.forEach(btn => btn.disabled = true);
        const submitBtn = document.querySelector(".submit-btn");
        if (submitBtn) submitBtn.disabled = true;
    }

    function showNextButton() {
        const container = document.getElementById("dynamicContent");
        const existingNext = document.querySelector(".next-btn");
        if (!existingNext) {
            const nextBtn = document.createElement("button");
            nextBtn.innerText = "➡️ NEXT QUESTION";
            nextBtn.className = "next-btn";
            nextBtn.onclick = () => {
                currentIndex++;
                if (currentIndex < questions.length) {
                    renderQuestion();
                } else {
                    endGame();
                }
            };
            container.appendChild(nextBtn);
        }
    }

    function endGame() {
        stopTimer();
        const container = document.getElementById("dynamicContent");
        const playerName = document.getElementById("playerName").value || "Student";
        addScoreToLeaderboard(playerName, totalScore);
        container.innerHTML = `
            <div class="game-complete">
                <h2>🎉 GAME COMPLETE! 🎉</h2>
                <p style="font-size: 2rem; margin: 20px 0;">⭐ ${totalScore} / 240 ⭐</p>
                <p>🏆 ${playerName}, you've completed the Interpreter's Showdown!</p>
                <p>💡 Remember: In real interpreting, accuracy + speed = success!</p>
                <button class="restart-btn" onclick="resetGame()">🔄 PLAY AGAIN</button>
            </div>
        `;
    }

    function checkInterpreting() {
        if (answerLocked) return;
        const input = document.querySelector(".interpreting-input");
        const userAnswer = input.value.trim().toLowerCase();
        const q = questions[currentIndex];
        const keywordMatch = q.keywords.some(kw => userAnswer.includes(kw.toLowerCase()));
        
        stopTimer();
        answerLocked = true;
        
        const contentDiv = document.getElementById("dynamicContent");
        const feedbackDiv = document.createElement("div");
        
        if (keywordMatch) {
            totalScore += q.points;
            updateUI();
            feedbackDiv.className = "feedback correct-feedback";
            feedbackDiv.innerHTML = `✅ GREAT INTERPRETATION! +${q.points} points!<br>📖 Reference: ${q.correctAnswer}`;
        } else {
            feedbackDiv.className = "feedback wrong-feedback";
            feedbackDiv.innerHTML = `❌ Needs improvement! +0 points.<br>📖 Correct answer: ${q.correctAnswer}<br>💡 Key words to include: ${q.keywords.join(", ")}`;
        }
        contentDiv.appendChild(feedbackDiv);
        disableOptions();
        showNextButton();
    }

    function handleAnswer(selected, correctLetter, points) {
        if (answerLocked) return;
        stopTimer();
        answerLocked = true;
        
        const isCorrect = (selected === correctLetter);
        if (isCorrect) {
            totalScore += points;
            updateUI();
        }
        
        const btns = document.querySelectorAll(".option-btn");
        btns.forEach(btn => {
            btn.disabled = true;
            if (btn.innerText.startsWith(correctLetter)) {
                btn.classList.add("correct");
            }
            if (!isCorrect && btn.innerText.startsWith(selected)) {
                btn.classList.add("wrong");
            }
        });
        
        const contentDiv = document.getElementById("dynamicContent");
        const feedbackDiv = document.createElement("div");
        feedbackDiv.className = isCorrect ? "feedback correct-feedback" : "feedback wrong-feedback";
        feedbackDiv.innerHTML = isCorrect ? 
            `✅ CORRECT! +${points} points!<br>📖 ${questions[currentIndex].explanation}` : 
            `❌ WRONG! The correct answer is ${correctLetter}.<br>📖 ${questions[currentIndex].explanation}`;
        contentDiv.appendChild(feedbackDiv);
        showNextButton();
    }

    function renderQuestion() {
        answerLocked = false;
        const q = questions[currentIndex];
        const container = document.getElementById("dynamicContent");
        
        let topicColor = "";
        if (q.topic.includes("Data")) topicColor = "🌍";
        else if (q.topic.includes("ZXMOTO")) topicColor = "🏍️";
        else if (q.topic.includes("Fuel")) topicColor = "✈️";
        else topicColor = "🔬";
        
        let html = `<div style="margin-bottom: 15px;"><span style="background: #f0f0f0; padding: 5px 12px; border-radius: 20px; font-size: 0.9rem;">${topicColor} ${q.topic}</span></div>`;
        html += `<div class="question-text ${q.type === 'interpreting' ? (q.question.includes('Chinese') ? 'zh' : 'en') : ''}">${q.question}</div>`;
        
        if (q.isInterpreting) {
            html += `<div class="interpreting-area">
                        <textarea class="interpreting-input" placeholder="Type or speak your interpretation here... (English to Chinese / Chinese to English as required)" rows="4"></textarea>
                        <button class="submit-btn" onclick="checkInterpreting()">🎤 SUBMIT INTERPRETATION</button>
                    </div>`;
        } else {
            html += `<div class="options-area">`;
            q.options.forEach(opt => {
                const letter = opt.charAt(0);
                html += `<button class="option-btn" onclick="handleAnswer('${letter}', '${q.correct}', ${q.points})">${opt}</button>`;
            });
            html += `</div>`;
        }
        
        container.innerHTML = html;
        startTimer();
        updateUI();
    }

    function resetGame() {
        stopTimer();
        currentIndex = 0;
        totalScore = 0;
        currentPlayer = document.getElementById("playerName").value || "Student";
        updateUI();
        renderQuestion();
    }

    // Initialize
    loadLeaderboard();
    resetGame();
</script>
</body>
</html>

Game Source: 🎙️ Interpreter's Showdown - Hot Word Challenge

Creator: RocketGecko40

Libraries: none

Complexity: complex (724 lines, 26.1 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: interpreter-s-showdown-hot-word-challeng-rocketgecko40" to link back to the original. Then publish at arcadelab.ai/publish.