🎙️ Interpreter's Showdown - Hot Word Challenge
by RocketGecko40724 lines26.1 KB
<!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.