Initial commit: Add MathHomeworkHelper project with web and Android components
Some checks reported errors
continuous-integration/drone Build encountered an error
Some checks reported errors
continuous-integration/drone Build encountered an error
This commit is contained in:
commit
f9558008e1
37 changed files with 5318 additions and 0 deletions
651
script.js
Normal file
651
script.js
Normal file
|
|
@ -0,0 +1,651 @@
|
|||
// Game State
|
||||
let gameState = {
|
||||
difficulty: 1,
|
||||
currentProblem: null,
|
||||
points: 0,
|
||||
totalAnswers: 0
|
||||
};
|
||||
|
||||
// Difficulty configurations (will be updated with translations)
|
||||
let difficultyConfig = {
|
||||
1: {
|
||||
num1Min: 1, num1Max: 9,
|
||||
num2Min: 1, num2Max: 9,
|
||||
descriptionKey: 'difficulty1'
|
||||
},
|
||||
2: {
|
||||
num1Min: 10, num1Max: 99,
|
||||
num2Min: 1, num2Max: 9,
|
||||
descriptionKey: 'difficulty2'
|
||||
},
|
||||
3: {
|
||||
num1Min: 10, num1Max: 99,
|
||||
num2Min: 10, num2Max: 99,
|
||||
descriptionKey: 'difficulty3'
|
||||
},
|
||||
4: {
|
||||
num1Min: 100, num1Max: 999,
|
||||
num2Min: 10, num2Max: 99,
|
||||
descriptionKey: 'difficulty4'
|
||||
},
|
||||
5: {
|
||||
num1Min: 10000, num1Max: 99999,
|
||||
num2Min: 100, num2Max: 999,
|
||||
descriptionKey: 'difficulty5'
|
||||
}
|
||||
};
|
||||
|
||||
// DOM Elements
|
||||
const difficultySlider = document.getElementById('difficulty-slider');
|
||||
const difficultyDisplay = document.getElementById('difficulty-display');
|
||||
const difficultyDescription = document.getElementById('difficulty-description');
|
||||
const problemDisplay = document.getElementById('problem-display');
|
||||
const submitBtn = document.getElementById('submit-btn');
|
||||
const feedbackDiv = document.getElementById('feedback');
|
||||
const pointsScoreDisplay = document.getElementById('points-score');
|
||||
const newProblemBtn = document.getElementById('new-problem-btn');
|
||||
const victoryModal = document.getElementById('victory-modal');
|
||||
const playAgainBtn = document.getElementById('play-again-btn');
|
||||
|
||||
// Event Listeners
|
||||
difficultySlider.addEventListener('change', handleDifficultyChange);
|
||||
submitBtn.addEventListener('click', handleSubmitAnswer);
|
||||
newProblemBtn.addEventListener('click', generateNewProblem);
|
||||
playAgainBtn.addEventListener('click', resetGame);
|
||||
|
||||
// Initialize
|
||||
window.addEventListener('load', async () => {
|
||||
await i18n.initialize();
|
||||
initializeLanguageSelector();
|
||||
updateUIText();
|
||||
generateNewProblem();
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle difficulty slider change
|
||||
*/
|
||||
function handleDifficultyChange() {
|
||||
gameState.difficulty = parseInt(difficultySlider.value);
|
||||
difficultyDisplay.textContent = gameState.difficulty;
|
||||
difficultyDescription.textContent = difficultyConfig[gameState.difficulty].description;
|
||||
generateNewProblem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random number between min and max (inclusive)
|
||||
*/
|
||||
function getRandomNumber(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new multiplication problem
|
||||
*/
|
||||
function generateNewProblem() {
|
||||
const config = difficultyConfig[gameState.difficulty];
|
||||
const num1 = getRandomNumber(config.num1Min, config.num1Max);
|
||||
const num2 = getRandomNumber(config.num2Min, config.num2Max);
|
||||
const answer = num1 * num2;
|
||||
|
||||
gameState.currentProblem = {
|
||||
num1,
|
||||
num2,
|
||||
answer
|
||||
};
|
||||
|
||||
displayProblem();
|
||||
clearFeedback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate intermediate steps for vertical multiplication
|
||||
*/
|
||||
function calculateIntermediateSteps(num1, num2) {
|
||||
const num2Str = num2.toString();
|
||||
const steps = [];
|
||||
|
||||
// Calculate partial products for each digit of num2
|
||||
for (let i = num2Str.length - 1; i >= 0; i--) {
|
||||
const digit = parseInt(num2Str[i]);
|
||||
const partialProduct = num1 * digit;
|
||||
const shiftAmount = num2Str.length - 1 - i;
|
||||
steps.push({
|
||||
digit,
|
||||
product: partialProduct,
|
||||
shift: shiftAmount
|
||||
});
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the multiplication problem
|
||||
*/
|
||||
function displayProblem() {
|
||||
const { num1, num2 } = gameState.currentProblem;
|
||||
const difficulty = gameState.difficulty;
|
||||
|
||||
if (difficulty === 1) {
|
||||
// Horizontal layout for 1x1 with result
|
||||
const answer = gameState.currentProblem.answer.toString();
|
||||
let resultHTML = '<div class="line" style="justify-content: flex-end; gap: 2px;">';
|
||||
for (let i = 0; i < answer.length; i++) {
|
||||
resultHTML += `<input type="text" class="digit-input result-input" maxlength="1" data-pos="${i}" />`;
|
||||
}
|
||||
resultHTML += '</div>';
|
||||
|
||||
problemDisplay.innerHTML = `
|
||||
<div class="multiplication-horizontal">
|
||||
<span class="number">${num1}</span>
|
||||
<span class="operator">×</span>
|
||||
<span class="number">${num2}</span>
|
||||
<span class="operator">=</span>
|
||||
${resultHTML}
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add event listeners to result digit inputs
|
||||
setTimeout(() => {
|
||||
addResultDigitInputListeners();
|
||||
}, 0);
|
||||
} else {
|
||||
// Vertical layout for 2+ digits
|
||||
const num1Str = num1.toString();
|
||||
const num2Str = num2.toString();
|
||||
|
||||
// Calculate intermediate steps for reference
|
||||
const steps = calculateIntermediateSteps(num1, num2);
|
||||
gameState.currentProblem.steps = steps;
|
||||
|
||||
// Create input fields for intermediate steps only if num2 has more than 1 digit
|
||||
let intermediateHTML = '';
|
||||
if (num2 > 9) {
|
||||
// Calculate the maximum width needed for intermediate steps
|
||||
const maxResultWidth = gameState.currentProblem.answer.toString().length;
|
||||
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const stepProduct = steps[i].product.toString();
|
||||
const totalWidth = stepProduct.length + steps[i].shift;
|
||||
intermediateHTML += '<div class="line" style="justify-content: flex-start; gap: 5px;">';
|
||||
|
||||
// Each row is offset one position to the left
|
||||
// Add offset spaces at the beginning (left side)
|
||||
for (let offset = 0; offset < i; offset++) {
|
||||
intermediateHTML += '<span style="width: 90px;"></span>';
|
||||
}
|
||||
|
||||
// Add empty spaces for shift
|
||||
for (let s = 0; s < steps[i].shift; s++) {
|
||||
intermediateHTML += '<span style="width: 90px;"></span>';
|
||||
}
|
||||
|
||||
// Add input fields for each digit
|
||||
for (let j = 0; j < stepProduct.length; j++) {
|
||||
intermediateHTML += `<input type="text" class="digit-input intermediate-input" maxlength="1" data-step="${i}" data-pos="${j}" />`;
|
||||
}
|
||||
|
||||
// Add trailing empty spaces on the right
|
||||
const trailingSpaces = maxResultWidth - totalWidth - i;
|
||||
for (let e = 0; e < trailingSpaces; e++) {
|
||||
intermediateHTML += '<span style="width: 90px;"></span>';
|
||||
}
|
||||
|
||||
intermediateHTML += '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Create input fields for final result
|
||||
const answer = gameState.currentProblem.answer.toString();
|
||||
let resultHTML = '<div class="line" style="justify-content: flex-end; gap: 2px;">';
|
||||
for (let i = 0; i < answer.length; i++) {
|
||||
resultHTML += `<input type="text" class="digit-input result-input" maxlength="1" data-pos="${i}" />`;
|
||||
}
|
||||
resultHTML += '</div>';
|
||||
|
||||
let html = `
|
||||
<div class="multiplication-vertical">
|
||||
<div class="line">
|
||||
<span>${num1Str}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
<span class="operator">×</span>
|
||||
<span>${num2Str}</span>
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
`;
|
||||
|
||||
if (num2 > 9) {
|
||||
html += `
|
||||
<div id="intermediate-steps">
|
||||
${intermediateHTML}
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<div id="result-steps">
|
||||
${resultHTML}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
problemDisplay.innerHTML = html;
|
||||
|
||||
// Add event listeners to digit inputs
|
||||
setTimeout(() => {
|
||||
addDigitInputListeners();
|
||||
addResultDigitInputListeners();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listeners to digit input fields
|
||||
*/
|
||||
function addDigitInputListeners() {
|
||||
const digitInputs = document.querySelectorAll('.digit-input:not(.result-input)');
|
||||
|
||||
digitInputs.forEach((input, index) => {
|
||||
input.addEventListener('input', (e) => {
|
||||
// Only allow digits
|
||||
if (!/^\d?$/.test(e.target.value)) {
|
||||
e.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Move to next input if digit entered
|
||||
if (e.target.value && index < digitInputs.length - 1) {
|
||||
digitInputs[index + 1].focus();
|
||||
}
|
||||
});
|
||||
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Backspace' && !e.target.value && index > 0) {
|
||||
digitInputs[index - 1].focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listeners to result digit input fields
|
||||
* Navigation: left after filling, wrap to rightmost of next line
|
||||
*/
|
||||
function addResultDigitInputListeners() {
|
||||
const resultInputs = document.querySelectorAll('.result-input');
|
||||
|
||||
resultInputs.forEach((input, index) => {
|
||||
input.addEventListener('input', (e) => {
|
||||
// Only allow digits
|
||||
if (!/^\d?$/.test(e.target.value)) {
|
||||
e.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Move to LEFT if digit entered
|
||||
if (e.target.value) {
|
||||
if (index > 0) {
|
||||
// Move to previous input (left)
|
||||
resultInputs[index - 1].focus();
|
||||
} else if (index === 0) {
|
||||
// At the leftmost position, wrap to rightmost of previous line
|
||||
const allLines = document.querySelectorAll('#result-steps .line, #intermediate-steps .line');
|
||||
if (allLines.length > 1) {
|
||||
const prevLineInputs = allLines[allLines.length - 2].querySelectorAll('input');
|
||||
if (prevLineInputs.length > 0) {
|
||||
prevLineInputs[prevLineInputs.length - 1].focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
input.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Backspace' && !e.target.value && index < resultInputs.length - 1) {
|
||||
resultInputs[index + 1].focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find which digits are incorrect in the answer
|
||||
*/
|
||||
function findIncorrectDigits(userAnswer, correctAnswer) {
|
||||
const userStr = userAnswer.toString();
|
||||
const correctStr = correctAnswer.toString();
|
||||
const incorrectPositions = [];
|
||||
|
||||
// Pad the shorter string with leading zeros for comparison
|
||||
const maxLen = Math.max(userStr.length, correctStr.length);
|
||||
const userPadded = userStr.padStart(maxLen, '0');
|
||||
const correctPadded = correctStr.padStart(maxLen, '0');
|
||||
|
||||
for (let i = 0; i < maxLen; i++) {
|
||||
if (userPadded[i] !== correctPadded[i]) {
|
||||
incorrectPositions.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return incorrectPositions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display answer with highlighted incorrect digits
|
||||
*/
|
||||
function displayAnswerWithErrors(userAnswer, correctAnswer) {
|
||||
const incorrectPositions = findIncorrectDigits(userAnswer, correctAnswer);
|
||||
const userStr = userAnswer.toString();
|
||||
const correctStr = correctAnswer.toString();
|
||||
const maxLen = Math.max(userStr.length, correctStr.length);
|
||||
const userPadded = userStr.padStart(maxLen, '0');
|
||||
|
||||
let html = '<div style="font-size: 1.5em; margin-top: 15px;"><strong>Your answer:</strong> ';
|
||||
|
||||
for (let i = 0; i < maxLen; i++) {
|
||||
const digit = userPadded[i];
|
||||
if (incorrectPositions.includes(i)) {
|
||||
html += `<span style="border: 3px solid #dc2626; padding: 5px 8px; margin: 0 2px; display: inline-block; background-color: #fee2e2;">${digit}</span>`;
|
||||
} else {
|
||||
html += digit;
|
||||
}
|
||||
}
|
||||
|
||||
html += `<br><strong>Correct answer:</strong> ${correctStr}</div>`;
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user answer from input boxes
|
||||
*/
|
||||
function getUserAnswer() {
|
||||
const resultInputs = document.querySelectorAll('.result-input');
|
||||
let answer = '';
|
||||
resultInputs.forEach(input => {
|
||||
answer += input.value;
|
||||
});
|
||||
return answer === '' ? null : parseInt(answer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user intermediate steps from input boxes
|
||||
*/
|
||||
function getUserIntermediateSteps() {
|
||||
const steps = [];
|
||||
const intermediateLines = document.querySelectorAll('#intermediate-steps .line');
|
||||
|
||||
intermediateLines.forEach((line, lineIndex) => {
|
||||
const inputs = line.querySelectorAll('input');
|
||||
let stepValue = '';
|
||||
inputs.forEach(input => {
|
||||
stepValue += input.value;
|
||||
});
|
||||
if (stepValue) {
|
||||
steps.push(parseInt(stepValue));
|
||||
}
|
||||
});
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle answer submission
|
||||
*/
|
||||
function handleSubmitAnswer() {
|
||||
const userAnswer = getUserAnswer();
|
||||
const correctAnswer = gameState.currentProblem.answer;
|
||||
|
||||
if (userAnswer === null) {
|
||||
showFeedback('Please enter an answer!', 'incorrect');
|
||||
return;
|
||||
}
|
||||
|
||||
gameState.totalAnswers++;
|
||||
|
||||
// Check intermediate steps if they exist
|
||||
const intermediateStepsDiv = document.getElementById('intermediate-steps');
|
||||
let intermediateStepsCorrect = true;
|
||||
let intermediateErrorMessage = '';
|
||||
|
||||
if (intermediateStepsDiv) {
|
||||
const steps = gameState.currentProblem.steps;
|
||||
const intermediateLines = document.querySelectorAll('#intermediate-steps .line');
|
||||
|
||||
intermediateLines.forEach((line, lineIndex) => {
|
||||
const inputs = line.querySelectorAll('input');
|
||||
let userStepValue = '';
|
||||
inputs.forEach(input => {
|
||||
userStepValue += input.value;
|
||||
});
|
||||
|
||||
if (userStepValue) {
|
||||
const userStepNum = parseInt(userStepValue);
|
||||
const correctStepNum = steps[lineIndex].product;
|
||||
|
||||
if (userStepNum !== correctStepNum) {
|
||||
intermediateStepsCorrect = false;
|
||||
intermediateErrorMessage += `<br>Step ${lineIndex + 1}: You wrote ${userStepNum}, correct is ${correctStepNum}`;
|
||||
|
||||
// Highlight incorrect digits in this step
|
||||
const correctStr = correctStepNum.toString();
|
||||
const userStr = userStepValue;
|
||||
inputs.forEach((input, digitIndex) => {
|
||||
if (digitIndex < userStr.length && userStr[digitIndex] !== correctStr[correctStr.length - userStr.length + digitIndex]) {
|
||||
input.classList.add('error');
|
||||
} else if (digitIndex < userStr.length) {
|
||||
input.classList.add('correct');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (userAnswer === correctAnswer && intermediateStepsCorrect) {
|
||||
gameState.points += 1;
|
||||
showFeedback('🎉 Correct! +1 point', 'correct');
|
||||
updateScore();
|
||||
|
||||
// Check if reached 20 points
|
||||
if (gameState.points >= 20) {
|
||||
showVictoryModal();
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
generateNewProblem();
|
||||
}, 1500);
|
||||
} else {
|
||||
gameState.points = Math.max(0, gameState.points - 2);
|
||||
|
||||
// Mark incorrect result boxes with red color
|
||||
if (userAnswer !== correctAnswer) {
|
||||
const resultInputs = document.querySelectorAll('.result-input');
|
||||
const userStr = userAnswer.toString();
|
||||
const correctStr = correctAnswer.toString();
|
||||
const maxLen = Math.max(userStr.length, correctStr.length);
|
||||
const userPadded = userStr.padStart(maxLen, '0');
|
||||
const correctPadded = correctStr.padStart(maxLen, '0');
|
||||
|
||||
resultInputs.forEach((input, index) => {
|
||||
if (userPadded[index] !== correctPadded[index]) {
|
||||
input.classList.add('error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
feedbackDiv.textContent = '❌ Your answer is wrong, check the red boxes';
|
||||
feedbackDiv.className = 'feedback incorrect';
|
||||
updateScore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show feedback message
|
||||
*/
|
||||
function showFeedback(message, type) {
|
||||
feedbackDiv.textContent = message;
|
||||
feedbackDiv.className = `feedback ${type}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear feedback message
|
||||
*/
|
||||
function clearFeedback() {
|
||||
feedbackDiv.textContent = '';
|
||||
feedbackDiv.className = 'feedback empty';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update score display
|
||||
*/
|
||||
function updateScore() {
|
||||
pointsScoreDisplay.textContent = `${gameState.points}/20`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show victory modal and create confetti
|
||||
*/
|
||||
function showVictoryModal() {
|
||||
victoryModal.classList.add('show');
|
||||
createConfetti();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create confetti animation
|
||||
*/
|
||||
function createConfetti() {
|
||||
const colors = ['#2563eb', '#7c3aed', '#dc2626', '#16a34a', '#ea580c', '#f59e0b'];
|
||||
const confettiCount = 50;
|
||||
|
||||
for (let i = 0; i < confettiCount; i++) {
|
||||
const confetti = document.createElement('div');
|
||||
confetti.className = 'confetti';
|
||||
confetti.style.left = Math.random() * 100 + '%';
|
||||
confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
|
||||
confetti.style.delay = Math.random() * 0.5 + 's';
|
||||
confetti.style.animationDuration = (Math.random() * 2 + 2.5) + 's';
|
||||
document.body.appendChild(confetti);
|
||||
|
||||
// Remove confetti element after animation
|
||||
setTimeout(() => {
|
||||
confetti.remove();
|
||||
}, 3500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset game for new round
|
||||
*/
|
||||
function resetGame() {
|
||||
gameState.points = 0;
|
||||
gameState.totalAnswers = 0;
|
||||
victoryModal.classList.remove('show');
|
||||
updateScore();
|
||||
generateNewProblem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize language selector
|
||||
*/
|
||||
function initializeLanguageSelector() {
|
||||
const languageFlagsContainer = document.getElementById('language-flags');
|
||||
const languages = i18n.getSupportedLanguages();
|
||||
|
||||
languageFlagsContainer.innerHTML = '';
|
||||
|
||||
Object.entries(languages).forEach(([langCode, langInfo]) => {
|
||||
const flagButton = document.createElement('button');
|
||||
flagButton.className = 'language-flag';
|
||||
flagButton.textContent = langInfo.flag;
|
||||
flagButton.title = langInfo.name;
|
||||
flagButton.setAttribute('data-tooltip', langInfo.name);
|
||||
|
||||
if (langCode === i18n.getCurrentLanguage()) {
|
||||
flagButton.classList.add('active');
|
||||
}
|
||||
|
||||
flagButton.addEventListener('click', () => {
|
||||
changeLanguage(langCode);
|
||||
});
|
||||
|
||||
languageFlagsContainer.appendChild(flagButton);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Change language and update UI
|
||||
*/
|
||||
function changeLanguage(langCode) {
|
||||
i18n.setLanguage(langCode);
|
||||
|
||||
// Update active flag
|
||||
document.querySelectorAll('.language-flag').forEach(flag => {
|
||||
flag.classList.remove('active');
|
||||
});
|
||||
const languages = i18n.getSupportedLanguages();
|
||||
const flagButtons = document.querySelectorAll('.language-flag');
|
||||
const langCodes = Object.keys(languages);
|
||||
flagButtons.forEach((btn, index) => {
|
||||
if (langCodes[index] === langCode) {
|
||||
btn.classList.add('active');
|
||||
}
|
||||
});
|
||||
|
||||
updateUIText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all UI text based on current language
|
||||
*/
|
||||
function updateUIText() {
|
||||
// Update header
|
||||
document.getElementById('title').textContent = '🎓 ' + i18n.t('title');
|
||||
document.getElementById('subtitle').textContent = i18n.t('subtitle');
|
||||
|
||||
// Update difficulty label
|
||||
const difficultyLabel = document.querySelector('.difficulty-label');
|
||||
if (difficultyLabel) {
|
||||
difficultyLabel.innerHTML = i18n.t('difficultyLevel') + ' <span id="difficulty-display">' + gameState.difficulty + '</span>';
|
||||
}
|
||||
|
||||
// Update difficulty text labels
|
||||
const difficultyTexts = document.querySelectorAll('.difficulty-text');
|
||||
if (difficultyTexts.length >= 2) {
|
||||
difficultyTexts[0].textContent = i18n.t('easy');
|
||||
difficultyTexts[1].textContent = i18n.t('hard');
|
||||
}
|
||||
|
||||
// Update difficulty description
|
||||
const config = difficultyConfig[gameState.difficulty];
|
||||
if (config && config.descriptionKey) {
|
||||
document.getElementById('difficulty-description').textContent = i18n.t(config.descriptionKey);
|
||||
}
|
||||
|
||||
// Update buttons
|
||||
document.getElementById('submit-btn').textContent = i18n.t('checkAnswer');
|
||||
document.getElementById('new-problem-btn').textContent = i18n.t('newProblem');
|
||||
|
||||
// Update score label
|
||||
const scoreLabel = document.querySelector('.score-label');
|
||||
if (scoreLabel) {
|
||||
scoreLabel.textContent = i18n.t('points');
|
||||
}
|
||||
|
||||
// Update modal
|
||||
const modalTitle = document.querySelector('.modal-content h2');
|
||||
const modalText = document.querySelector('.modal-content p');
|
||||
const playAgainButton = document.getElementById('play-again-btn');
|
||||
|
||||
if (modalTitle) {
|
||||
modalTitle.textContent = i18n.t('congratulations');
|
||||
}
|
||||
if (modalText) {
|
||||
modalText.textContent = i18n.t('youReached20Points');
|
||||
}
|
||||
if (playAgainButton) {
|
||||
playAgainButton.textContent = i18n.t('playAgain');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue