Spaces:
Running
Running
// Core game elements | |
const statusEl = document.getElementById('status'); | |
const timerEl = document.getElementById('timer'); | |
const gameInfoEl = document.getElementById('game-info'); | |
const guessInput = document.getElementById('guess-input'); | |
const submitGuessBtn = document.getElementById('submit-guess-btn'); | |
const feedbackSection = document.getElementById('feedback-section'); | |
const guessedWordEl = document.getElementById('guessed-word'); | |
const guessScoreEl = document.getElementById('guess-score'); | |
const feedbackTextEl = document.getElementById('feedback-text'); | |
const chatContent = document.getElementById('chat-content'); | |
const gridContainer = document.getElementById('grid-container'); | |
// Game state variables | |
let countdownInterval; | |
const playerName = 'Player1'; | |
let squareCount = 0; | |
let chatCount = 1; | |
// Grid management functions | |
const updateGrid = () => { | |
const cols = Math.ceil(Math.sqrt(squareCount)); | |
const rows = Math.ceil(squareCount / cols); | |
gridContainer.style.gridTemplateColumns = `repeat(${cols}, minmax(0, 1fr))`; | |
}; | |
const addSquare = () => { | |
squareCount++; | |
updateGrid(); | |
const colors = ["cerulean", "light-sea-green", "sunset", "floral-white", "light-red"]; | |
const square = document.createElement("div"); | |
square.className = `${colors[(squareCount - 1) % colors.length]} w-16 h-16 rounded-md shadow-md flex flex-col items-center justify-center text-black font-bold pop-in`; | |
square.innerHTML = ` | |
<span class="iconify" data-icon="mdi:account" data-width="24" data-height="24"></span> | |
Student ${squareCount} | |
`; | |
gridContainer.appendChild(square); | |
}; | |
const removeSquare = () => { | |
if (squareCount > 0) { | |
const squareToRemove = gridContainer.lastElementChild; | |
squareToRemove.classList.add("pop-out"); | |
setTimeout(() => { | |
squareToRemove.remove(); | |
squareCount--; | |
updateGrid(); | |
}, 300); | |
} | |
}; | |
// Chat functionality | |
const addStreamMessage = (message, type = 'user') => { | |
if (!message.trim()) return; | |
const chatLine = document.createElement("div"); | |
chatLine.className = "text-gray-700 flex items-center gap-2"; | |
if (type === 'system') { | |
chatLine.innerHTML = `<span class="font-bold text-blue-600">${message}</span>`; | |
} else { | |
chatLine.innerHTML = `<span class="font-bold">${chatCount}.</span> <span>${message}</span>`; | |
chatCount++; | |
} | |
chatContent.appendChild(chatLine); | |
chatContent.scrollTop = chatContent.scrollHeight; | |
}; | |
// Timer functionality | |
function startCountdown(endTimestamp) { | |
if (countdownInterval) { | |
clearInterval(countdownInterval); | |
} | |
function updateTimer() { | |
const now = new Date().getTime(); | |
const timeLeft = endTimestamp - now; | |
if (timeLeft <= 0) { | |
clearInterval(countdownInterval); | |
timerEl.textContent = 'Time\'s up!'; | |
timerEl.classList.add('text-red-600'); | |
//addStreamMessage('Time\'s up! Starting new round...', 'system'); | |
fetchGameState(); | |
return; | |
} | |
const seconds = Math.floor(timeLeft / 1000); | |
timerEl.textContent = `${seconds}s`; | |
} | |
updateTimer(); | |
countdownInterval = setInterval(updateTimer, 1000); | |
} | |
// Game state management | |
function updateGameState(data) { | |
gameInfoEl.innerHTML = ''; | |
statusEl.textContent = data.message || ''; | |
if (data.session_id) { | |
const infoHtml = ` | |
<div> | |
Session: ${data.session_id || ''}<br> | |
Turn: ${data.turn_number || ''}<br> | |
Word: ${data.word || ''} | |
</div> | |
`; | |
gameInfoEl.innerHTML = infoHtml; | |
// Display hints based on turn number | |
const turnNumber = parseInt(data.turn_number) || 0; | |
// Hint 0 on turn 1 | |
if (turnNumber === 1 && data.hint0) { | |
addStreamMessage('New hint available:', 'system'); | |
addStreamMessage(data.hint0, 'system'); | |
} | |
// Hint 1 on turn 3 | |
else if (turnNumber === 3 && data.hint1) { | |
addStreamMessage('New hint available:', 'system'); | |
addStreamMessage(data.hint1, 'system'); | |
} | |
// Hint 2 on turn 5 | |
else if (turnNumber === 5 && data.hint2) { | |
addStreamMessage('New hint available:', 'system'); | |
addStreamMessage(data.hint2, 'system'); | |
} | |
// Hint 3 on turn 7 | |
else if (turnNumber === 7 && data.hint3) { | |
addStreamMessage('New hint available:', 'system'); | |
addStreamMessage(data.hint3, 'system'); | |
} | |
if (data.end_timestamp) { | |
startCountdown(data.end_timestamp); | |
} | |
} | |
} | |
// API interactions | |
async function submitAdvice(adviceText) { | |
if (!guessText) return; | |
submitGuessBtn.disabled = true; | |
submitGuessBtn.classList.add('opacity-75'); | |
try { | |
const formData = new FormData(); | |
formData.append('guess_text', guessText); | |
formData.append('player_name', playerName); | |
formData.append('personality', document.getElementById('personality-select').value); | |
const response = await fetch('https://lemot.online/player/submit_guess/', { | |
method: 'POST', | |
body: formData | |
}); | |
const data = await response.json(); | |
if (data.error) { | |
statusEl.textContent = data.message || "Error submitting guess."; | |
statusEl.classList.add('text-red-600'); | |
addStreamMessage('Error submitting guess', 'system'); | |
} else { | |
feedbackSection.classList.remove('hidden'); | |
guessedWordEl.textContent = data.guessed_word; | |
guessScoreEl.textContent = `${data.score} / 10`; | |
feedbackTextEl.textContent = data.feedback; | |
addStreamMessage(`${data.guessed_word} - Score: ${data.score} / 10`); | |
guessInput.value = ''; | |
fetchGameState(); | |
} | |
} catch (err) { | |
console.error(err); | |
statusEl.textContent = "Error submitting guess."; | |
statusEl.classList.add('text-red-600'); | |
} finally { | |
submitGuessBtn.disabled = false; | |
submitGuessBtn.classList.remove('opacity-75'); | |
} | |
} | |
function fetchGameState() { | |
const formData = new FormData(); | |
formData.append('player_name', playerName); | |
fetch('https://lemot.online/player/play/', { | |
method: 'POST', | |
body: formData | |
}) | |
.then(res => res.json()) | |
.then(data => { | |
if (data.error) { | |
statusEl.textContent = data.message; | |
statusEl.classList.add('text-red-600'); | |
addStreamMessage(data.message, 'system'); | |
} else { | |
statusEl.classList.remove('text-red-600'); | |
updateGameState(data); | |
} | |
}) | |
.catch(err => { | |
console.error(err); | |
statusEl.textContent = "Error fetching game state."; | |
addStreamMessage("Error fetching game state", 'system'); | |
}); | |
} | |
// Event listeners | |
submitGuessBtn.addEventListener('click', () => { | |
const guessText = guessInput.value.trim(); | |
submitGuessb(guessText); | |
}); | |
guessInput.addEventListener('keypress', (e) => { | |
if (e.key === 'Enter') { | |
const guessText = guessInput.value.trim(); | |
submitGuessb(guessText); | |
} | |
}); | |
// Add square button listeners if they exist | |
const addSquareBtn = document.getElementById('add-square'); | |
const removeSquareBtn = document.getElementById('remove-square'); | |
if (addSquareBtn) { | |
addSquareBtn.addEventListener('click', addSquare); | |
} | |
if (removeSquareBtn) { | |
removeSquareBtn.addEventListener('click', removeSquare); | |
} | |
// Initialize game | |
window.addEventListener('load', fetchGameState); |