|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<title>Current Game</title> |
|
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet"> |
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> |
|
</head> |
|
<body class="bg-gradient-to-br from-gray-50 to-gray-100 min-h-screen"> |
|
<div class="container mx-auto py-8 px-4 sm:px-6 lg:px-8 max-w-4xl"> |
|
|
|
<div class="bg-white rounded-2xl shadow-lg p-6 mb-8"> |
|
<div class="flex justify-between items-center"> |
|
<div> |
|
<h1 class="text-3xl font-bold text-gray-800 mb-2">Word Game</h1> |
|
<p class="text-sm text-gray-600 font-medium">Welcome, <span id="player-name" class="text-indigo-600"></span>!</p> |
|
</div> |
|
<div id="timer" class="text-2xl font-bold text-indigo-600 bg-indigo-50 px-6 py-3 rounded-xl shadow-sm"></div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="status" class="bg-blue-50 border-l-4 border-blue-500 p-4 rounded-lg mb-8 text-blue-700 font-medium shadow-sm"></div> |
|
|
|
|
|
<div id="feedback-section" class="bg-white rounded-2xl shadow-lg p-6 mb-8 hidden"> |
|
<div class="flex items-center justify-between"> |
|
<div class="flex-1"> |
|
<h3 class="text-lg font-semibold text-gray-800 mb-2">Latest Guess Results</h3> |
|
<div class="flex items-center space-x-4"> |
|
<div class="bg-gray-50 rounded-lg px-4 py-2"> |
|
<span class="text-gray-500 text-sm">Word:</span> |
|
<span id="guessed-word" class="font-medium text-gray-800 ml-2"></span> |
|
</div> |
|
<div class="bg-indigo-50 rounded-lg px-4 py-2"> |
|
<span class="text-indigo-500 text-sm">Score:</span> |
|
<span id="guess-score" class="font-medium text-indigo-600 ml-2"></span> |
|
</div> |
|
</div> |
|
<p id="feedback-text" class="mt-3 text-gray-700"></p> |
|
</div> |
|
<div id="score-indicator" class="w-24 h-24 rounded-full border-8 flex items-center justify-center"> |
|
<span class="text-2xl font-bold"></span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8"> |
|
|
|
<div class="bg-white rounded-2xl shadow-lg p-6"> |
|
<div id="game-info" class="space-y-4"> |
|
|
|
</div> |
|
</div> |
|
|
|
|
|
<div class="bg-white rounded-2xl shadow-lg p-6"> |
|
<h3 class="text-lg font-semibold text-gray-800 mb-4">Give Advice</h3> |
|
<div class="space-y-4"> |
|
|
|
<div class="mb-4"> |
|
<label for="personality-select" class="block text-sm font-medium text-gray-700 mb-2">Choose Personality</label> |
|
<select |
|
id="personality-select" |
|
class="w-full px-4 py-3 rounded-xl border border-gray-200 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-200 shadow-sm" |
|
> |
|
<option value="helpful">Helpful</option> |
|
<option value="funny">Funny</option> |
|
<option value="strict">Strict</option> |
|
</select> |
|
</div> |
|
<input |
|
id="guess-input" |
|
type="text" |
|
placeholder="Enter your advice..." |
|
class="w-full px-4 py-3 rounded-xl border border-gray-200 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-200 shadow-sm" |
|
required |
|
/> |
|
<button |
|
id="submit-guess-btn" |
|
class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-6 rounded-xl transition-all duration-200 shadow-md hover:shadow-lg transform hover:-translate-y-0.5"> |
|
Submit Advice |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="bg-white rounded-2xl shadow-lg p-6"> |
|
<h3 class="text-lg font-semibold text-gray-800 mb-4">Previous Turn Guesses</h3> |
|
<div class="bg-gray-50 rounded-xl p-4"> |
|
<ul id="previous-guess-list" class="space-y-2"></ul> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
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 previousGuessList = document.getElementById('previous-guess-list'); |
|
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 scoreIndicatorEl = document.getElementById('score-indicator'); |
|
|
|
let countdownInterval; |
|
const playerName = 'Player1'; |
|
document.getElementById('player-name').textContent = playerName; |
|
|
|
function startCountdown(endTimestamp) { |
|
if (countdownInterval) { |
|
clearInterval(countdownInterval); |
|
} |
|
|
|
function updateTimer() { |
|
const now = new Date().getTime(); |
|
const timeLeft = endTimestamp - now; |
|
|
|
if (timeLeft <= 0) { |
|
clearInterval(countdownInterval); |
|
timerEl.innerHTML = '<i class="fas fa-hourglass-end mr-2"></i>Time\'s up!'; |
|
timerEl.classList.remove('text-indigo-600', 'bg-indigo-50'); |
|
timerEl.classList.add('text-red-600', 'bg-red-50'); |
|
fetchGameState(); |
|
return; |
|
} |
|
|
|
const seconds = Math.floor(timeLeft / 1000); |
|
timerEl.innerHTML = `<i class="fas fa-hourglass-half mr-2"></i>${seconds}s`; |
|
} |
|
|
|
updateTimer(); |
|
countdownInterval = setInterval(updateTimer, 1000); |
|
} |
|
|
|
async function submitGuess(guessText) { |
|
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/play/submit_guess/', { |
|
method: 'POST', |
|
body: formData |
|
}); |
|
|
|
const data = await response.json(); |
|
|
|
if (data.error) { |
|
statusEl.textContent = data.message || "Error submitting guess."; |
|
statusEl.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700'); |
|
statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700'); |
|
} else { |
|
feedbackSection.classList.remove('hidden'); |
|
guessedWordEl.textContent = data.guessed_word; |
|
guessScoreEl.textContent = `${data.score}%`; |
|
feedbackTextEl.textContent = data.feedback; |
|
|
|
scoreIndicatorEl.className = 'w-24 h-24 rounded-full border-8 flex items-center justify-center'; |
|
if (data.score >= 90) { |
|
scoreIndicatorEl.classList.add('border-green-500', 'text-green-500'); |
|
} else if (data.score >= 70) { |
|
scoreIndicatorEl.classList.add('border-yellow-500', 'text-yellow-500'); |
|
} else if (data.score >= 50) { |
|
scoreIndicatorEl.classList.add('border-orange-500', 'text-orange-500'); |
|
} else { |
|
scoreIndicatorEl.classList.add('border-red-500', 'text-red-500'); |
|
} |
|
scoreIndicatorEl.querySelector('span').textContent = `${Math.round(data.score)}%`; |
|
|
|
guessInput.value = ''; |
|
fetchGameState(); |
|
} |
|
} catch (err) { |
|
console.error(err); |
|
statusEl.textContent = "Error submitting guess."; |
|
statusEl.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700'); |
|
statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700'); |
|
} 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.remove('bg-blue-50', 'border-blue-500', 'text-blue-700'); |
|
statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700'); |
|
} else { |
|
statusEl.classList.remove('bg-red-50', 'border-red-500', 'text-red-700'); |
|
statusEl.classList.add('bg-blue-50', 'border-blue-500', 'text-blue-700'); |
|
updateGameState(data); |
|
} |
|
}) |
|
.catch(err => { |
|
console.error(err); |
|
statusEl.textContent = "Error fetching game state."; |
|
}); |
|
} |
|
|
|
function updateGameState(data) { |
|
gameInfoEl.innerHTML = ''; |
|
previousGuessList.innerHTML = ''; |
|
statusEl.textContent = data.message || ''; |
|
|
|
if (data.session_id) { |
|
const infoHtml = ` |
|
<div class="space-y-4"> |
|
<div class="flex items-center space-x-2"> |
|
<span class="text-gray-500">Session:</span> |
|
<span class="font-medium text-gray-800">${data.session_id || ''}</span> |
|
</div> |
|
<div class="flex items-center space-x-2"> |
|
<span class="text-gray-500">Turn:</span> |
|
<span class="font-medium text-gray-800">${data.turn_number || ''}</span> |
|
</div> |
|
<div class="flex items-center space-x-2"> |
|
<span class="text-gray-500">Word:</span> |
|
<span class="font-medium text-gray-800">${data.word || ''}</span> |
|
</div> |
|
<div class="border-t border-gray-100 pt-4"> |
|
<h4 class="font-semibold text-gray-800 mb-2">Hints:</h4> |
|
<ul class="space-y-2"> |
|
<li class="flex items-center space-x-2"> |
|
<i class="fas fa-lightbulb text-yellow-400"></i> |
|
<span>${data.hint0 || ''}</span> |
|
</li> |
|
<li class="flex items-center space-x-2"> |
|
<i class="fas fa-lightbulb text-yellow-400"></i> |
|
<span>${data.hint1 || ''}</span> |
|
</li> |
|
<li class="flex items-center space-x-2"> |
|
<i class="fas fa-lightbulb text-yellow-400"></i> |
|
<span>${data.hint2 || ''}</span> |
|
</li> |
|
<li class="flex items-center space-x-2"> |
|
<i class="fas fa-lightbulb text-yellow-400"></i> |
|
<span>${data.hint3 || ''}</span> |
|
</li> |
|
</ul> |
|
</div> |
|
</div> |
|
`; |
|
gameInfoEl.innerHTML = infoHtml; |
|
|
|
if (data.end_timestamp) { |
|
startCountdown(data.end_timestamp); |
|
} |
|
} |
|
|
|
if (Array.isArray(data.previous_turn_guesses) && data.previous_turn_guesses.length > 0) { |
|
data.previous_turn_guesses.forEach(g => { |
|
const li = document.createElement('li'); |
|
li.className = 'flex items-center space-x-3 text-gray-700'; |
|
li.innerHTML = ` |
|
<i class="fas fa-user-circle text-gray-400"></i> |
|
<span class="font-medium text-indigo-600">${g.player_name}</span> |
|
<span class="text-gray-400">:</span> |
|
<span>${g.guess_text}</span> |
|
`; |
|
previousGuessList.appendChild(li); |
|
}); |
|
} else { |
|
previousGuessList.innerHTML = '<p class="text-gray-500 italic">No guesses from previous turn</p>'; |
|
} |
|
} |
|
|
|
|
|
submitGuessBtn.addEventListener('click', () => { |
|
const guessText = guessInput.value.trim(); |
|
submitGuess(guessText); |
|
}); |
|
|
|
guessInput.addEventListener('keypress', (e) => { |
|
if (e.key === 'Enter') { |
|
const guessText = guessInput.value.trim(); |
|
submitGuess(guessText); |
|
} |
|
}); |
|
|
|
|
|
window.addEventListener('load', fetchGameState); |
|
</script> |
|
</div> |
|
</body> |
|
</html> |