category = categorySelect.value;
difficulty = difficultySelect.value;
// Reset state
score = 0;
level = 1;
// Snake starts in center
const center = Math.floor(GRID_SIZE / 2);
snake = [{ x: center, y: center }];
direction = { x: 1, y: 0 };
nextDirection = { x: 1, y: 0 };
updateGameSpeed();
resizeCanvas();
// Update HUD
scoreDisplay.textContent = score;
lengthDisplay.textContent = snake.length;
levelDisplay.textContent = level;
// Hide menus
startMenu.style.display = 'none';
gameOverMenu.style.display = 'none';
pauseMenu.style.display = 'none';
// Begin with a question
gameRunning = true;
gamePaused = true;
showQuestion();
}
function updateGameSpeed() {
// Adjust speed based on difficulty
switch(difficulty) {
case 'easy':
gameSpeed = 350;
break;
case 'medium':
gameSpeed = 250;
break;
case 'hard':
gameSpeed = 180;
break;
}
}
function showQuestion() {
isQuestionPhase = true;
// Stop movement
if (gameLoop) {
clearInterval(gameLoop);
gameLoop = null;
}
// Get data based on selected category
let dataSource;
switch(category) {
case 'greetings': dataSource = greetingsData; break;
case 'nouns': dataSource = nounsData; break;
case 'verbs': dataSource = verbsData; break;
case 'adjectives': dataSource = adjectivesData; break;
case 'sentences': dataSource = sentencesData; break;
case 'numbers': dataSource = numbersData; break;
case 'timeExpressions': dataSource = timeExpressionsData; break;
case 'culturalPhrases': dataSource = culturalPhrasesData; break;
case 'questionWords': dataSource = questionWordsData; break;
case 'daysOfWeek': dataSource = daysOfWeekData; break;
case 'nounClasses': dataSource = nounClassesData; break;
case 'speechSounds': dataSource = speechSoundsData; break;
case 'negation': dataSource = negationData; break;
case 'pastTense': dataSource = pastTenseData; break;
case 'negativePast': dataSource = negativePastData; break;
case 'futureTense': dataSource = futureTenseData; break;
case 'negativeFuture': dataSource = negativeFutureData; break;
case 'haveAndDo': dataSource = haveData; break;
case 'mixed':
// Select a random category for mixed
const categories = [
greetingsData, nounsData, verbsData, adjectivesData, sentencesData,
numbersData, timeExpressionsData, culturalPhrasesData, questionWordsData,
daysOfWeekData, nounClassesData, speechSoundsData, negationData,
pastTenseData, negativePastData, futureTenseData, negativeFutureData, haveData
];
dataSource = categories[Math.floor(Math.random() * categories.length)];
break;
}
// Pick a random item from the data
const itemIndex = Math.floor(Math.random() * dataSource.length);
const item = dataSource[itemIndex];
// Decide question direction (English to Sesotho or Sesotho to English)
let isEnglishToSesotho = Math.random() > 0.5;
// Create the question
let questionPrompt, correctAnswer;
// Special handling for noun classes
if (category === 'nounClasses') {
const questionType = Math.floor(Math.random() * 3); // 0, 1, or 2
if (questionType === 0) {
questionPrompt = `What is the subject concord for noun class ${item.class}?`;
correctAnswer = item.concord;
} else if (questionType === 1) {
questionPrompt = `What is the prefix for noun class ${item.class}?`;
correctAnswer = item.prefix;
} else {
questionPrompt = `What class does the example "${item.example}" belong to?`;
correctAnswer = `Class ${item.class}`;
}
}
// Special handling for speech sounds
else if (category === 'speechSounds') {
if (isEnglishToSesotho) {
questionPrompt = `What is a Sesotho example of the sound "${item.en}"?`;
correctAnswer = item.st;
} else {
questionPrompt = `What English sound corresponds to "${item.st}"?`;
correctAnswer = item.en;
}
}
// Special handling for nouns with class information
else if (category === 'nouns' && item.class) {
const questionType = Math.floor(Math.random() * 3); // 0, 1, or 2
if (questionType === 0) {
// Regular translation
if (isEnglishToSesotho) {
questionPrompt = `What is the Sesotho for "${item.en}"?`;
correctAnswer = item.st;
} else {
questionPrompt = `What does "${item.st}" mean in English?`;
correctAnswer = item.en;
}
} else if (questionType === 1) {
// Ask for noun class
questionPrompt = `What noun class does "${item.st}" belong to?`;
correctAnswer = `Class ${item.class}`;
} else {
// Ask for the subject concord
questionPrompt = `What is the subject concord for "${item.st}"?`;
correctAnswer = item.concord;
}
}
// Regular translation for other categories
else {
if (isEnglishToSesotho) {
questionPrompt = `What is the Sesotho for "${item.en}"?`;
correctAnswer = item.st;
} else {
questionPrompt = `What does "${item.st}" mean in English?`;
correctAnswer = item.en;
}
}
currentQuestion = {
text: questionPrompt,
correctAnswer: correctAnswer,
allAnswers: []
};
// Set the question text
questionText.textContent = currentQuestion.text;
// Generate answer choices
let allPossibleAnswers;
// For noun classes, create appropriate answers
if (category === 'nounClasses') {
if (questionPrompt.includes("subject concord")) {
allPossibleAnswers = nounClassesData.map(item => item.concord);
} else if (questionPrompt.includes("prefix")) {
allPossibleAnswers = nounClassesData.map(item => item.prefix);
} else {
allPossibleAnswers = nounClassesData.map(item => `Class ${item.class}`);
}
}
// For regular categories
else {
allPossibleAnswers = dataSource.map(item => isEnglishToSesotho ? item.st : item.en);
}
// Remove correct answer from the array so we don't duplicate it
const correctAnswerIndex = allPossibleAnswers.indexOf(correctAnswer);
if (correctAnswerIndex !== -1) {
allPossibleAnswers.splice(correctAnswerIndex, 1);
}
// Shuffle the remaining answers
shuffleArray(allPossibleAnswers);
// Take the first 3 wrong answers
const wrongAnswers = allPossibleAnswers.slice(0, 3);
// Combine with correct answer and shuffle again
const answerChoices = [...wrongAnswers, correctAnswer];
shuffleArray(answerChoices);
// Clear previous answers
answersContainer.innerHTML = '';
answers = [];
// Create display items for each answer
answerChoices.forEach((ans, idx) => {
// Create display item in question overlay
const item = document.createElement('div');
item.className = 'answer-item';
const emojiSpan = document.createElement('span');
emojiSpan.className = 'answer-emoji';
emojiSpan.textContent = emojis[idx];
const textSpan = document.createElement('span');
textSpan.textContent = ans;
item.appendChild(emojiSpan);
item.appendChild(textSpan);
answersContainer.appendChild(item);
// Generate random position on the grid for the game
const pos = getRandomPosition();
answers.push({
x: pos.x,
y: pos.y,
text: ans,
correct: ans === correctAnswer,
emoji: emojis[idx]
});
});
questionPhase.style.display = 'flex';
}
Sesotho Snake Game - Learn South African Sesotho
Sesotho Snake: Learn South African Sesotho
Score: 0
Length: 1
Level: 1
Loading question...
Sesotho Snake Game
Learn South African Sesotho while playing snake!
First read the language question, then collect the correct answer with your snake.
Game Over!
Your score: 0
Final snake length: 1
Level reached: 1