MikeDoes commited on
Commit
07b11dd
·
verified ·
1 Parent(s): c973283

Upload standalone.html

Browse files
Files changed (1) hide show
  1. standalone.html +306 -0
standalone.html ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Current Game</title>
6
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
7
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
8
+ </head>
9
+ <body class="bg-gradient-to-br from-gray-50 to-gray-100 min-h-screen">
10
+ <div class="container mx-auto py-8 px-4 sm:px-6 lg:px-8 max-w-4xl">
11
+ <!-- Header Section -->
12
+ <div class="bg-white rounded-2xl shadow-lg p-6 mb-8">
13
+ <div class="flex justify-between items-center">
14
+ <div>
15
+ <h1 class="text-3xl font-bold text-gray-800 mb-2">Word Game</h1>
16
+ <p class="text-sm text-gray-600 font-medium">Welcome, <span id="player-name" class="text-indigo-600"></span>!</p>
17
+ </div>
18
+ <div id="timer" class="text-2xl font-bold text-indigo-600 bg-indigo-50 px-6 py-3 rounded-xl shadow-sm"></div>
19
+ </div>
20
+ </div>
21
+
22
+ <!-- Game Status -->
23
+ <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>
24
+
25
+ <!-- Feedback Section -->
26
+ <div id="feedback-section" class="bg-white rounded-2xl shadow-lg p-6 mb-8 hidden">
27
+ <div class="flex items-center justify-between">
28
+ <div class="flex-1">
29
+ <h3 class="text-lg font-semibold text-gray-800 mb-2">Latest Guess Results</h3>
30
+ <div class="flex items-center space-x-4">
31
+ <div class="bg-gray-50 rounded-lg px-4 py-2">
32
+ <span class="text-gray-500 text-sm">Word:</span>
33
+ <span id="guessed-word" class="font-medium text-gray-800 ml-2"></span>
34
+ </div>
35
+ <div class="bg-indigo-50 rounded-lg px-4 py-2">
36
+ <span class="text-indigo-500 text-sm">Score:</span>
37
+ <span id="guess-score" class="font-medium text-indigo-600 ml-2"></span>
38
+ </div>
39
+ </div>
40
+ <p id="feedback-text" class="mt-3 text-gray-700"></p>
41
+ </div>
42
+ <div id="score-indicator" class="w-24 h-24 rounded-full border-8 flex items-center justify-center">
43
+ <span class="text-2xl font-bold"></span>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <!-- Game Info Card -->
49
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
50
+ <!-- Game Details -->
51
+ <div class="bg-white rounded-2xl shadow-lg p-6">
52
+ <div id="game-info" class="space-y-4">
53
+ <!-- Will be populated by JS -->
54
+ </div>
55
+ </div>
56
+
57
+ <!-- Advice Section -->
58
+ <div class="bg-white rounded-2xl shadow-lg p-6">
59
+ <h3 class="text-lg font-semibold text-gray-800 mb-4">Give Advice</h3>
60
+ <div class="space-y-4">
61
+ <!-- Personality Selector -->
62
+ <div class="mb-4">
63
+ <label for="personality-select" class="block text-sm font-medium text-gray-700 mb-2">Choose Personality</label>
64
+ <select
65
+ id="personality-select"
66
+ 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"
67
+ >
68
+ <option value="helpful">Helpful</option>
69
+ <option value="funny">Funny</option>
70
+ <option value="strict">Strict</option>
71
+ </select>
72
+ </div>
73
+ <input
74
+ id="guess-input"
75
+ type="text"
76
+ placeholder="Enter your advice..."
77
+ 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"
78
+ required
79
+ />
80
+ <button
81
+ id="submit-guess-btn"
82
+ 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">
83
+ Submit Advice
84
+ </button>
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ <!-- Previous Guesses -->
90
+ <div class="bg-white rounded-2xl shadow-lg p-6">
91
+ <h3 class="text-lg font-semibold text-gray-800 mb-4">Previous Turn Guesses</h3>
92
+ <div class="bg-gray-50 rounded-xl p-4">
93
+ <ul id="previous-guess-list" class="space-y-2"></ul>
94
+ </div>
95
+ </div>
96
+
97
+ <script>
98
+ const statusEl = document.getElementById('status');
99
+ const timerEl = document.getElementById('timer');
100
+ const gameInfoEl = document.getElementById('game-info');
101
+ const guessInput = document.getElementById('guess-input');
102
+ const submitGuessBtn = document.getElementById('submit-guess-btn');
103
+ const previousGuessList = document.getElementById('previous-guess-list');
104
+ const feedbackSection = document.getElementById('feedback-section');
105
+ const guessedWordEl = document.getElementById('guessed-word');
106
+ const guessScoreEl = document.getElementById('guess-score');
107
+ const feedbackTextEl = document.getElementById('feedback-text');
108
+ const scoreIndicatorEl = document.getElementById('score-indicator');
109
+
110
+ let countdownInterval;
111
+ const playerName = 'Player1'; // You can change this or make it dynamic
112
+ document.getElementById('player-name').textContent = playerName;
113
+
114
+ function startCountdown(endTimestamp) {
115
+ if (countdownInterval) {
116
+ clearInterval(countdownInterval);
117
+ }
118
+
119
+ function updateTimer() {
120
+ const now = new Date().getTime();
121
+ const timeLeft = endTimestamp - now;
122
+
123
+ if (timeLeft <= 0) {
124
+ clearInterval(countdownInterval);
125
+ timerEl.innerHTML = '<i class="fas fa-hourglass-end mr-2"></i>Time\'s up!';
126
+ timerEl.classList.remove('text-indigo-600', 'bg-indigo-50');
127
+ timerEl.classList.add('text-red-600', 'bg-red-50');
128
+ fetchGameState();
129
+ return;
130
+ }
131
+
132
+ const seconds = Math.floor(timeLeft / 1000);
133
+ timerEl.innerHTML = `<i class="fas fa-hourglass-half mr-2"></i>${seconds}s`;
134
+ }
135
+
136
+ updateTimer();
137
+ countdownInterval = setInterval(updateTimer, 1000);
138
+ }
139
+
140
+ async function submitGuess(guessText) {
141
+ if (!guessText) return;
142
+
143
+ submitGuessBtn.disabled = true;
144
+ submitGuessBtn.classList.add('opacity-75');
145
+
146
+ try {
147
+ const formData = new FormData();
148
+ formData.append('guess_text', guessText);
149
+ formData.append('player_name', playerName);
150
+ formData.append('personality', document.getElementById('personality-select').value);
151
+
152
+ const response = await fetch('https://lemot.online/player/play/submit_guess/', {
153
+ method: 'POST',
154
+ body: formData
155
+ });
156
+
157
+ const data = await response.json();
158
+
159
+ if (data.error) {
160
+ statusEl.textContent = data.message || "Error submitting guess.";
161
+ statusEl.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700');
162
+ statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700');
163
+ } else {
164
+ feedbackSection.classList.remove('hidden');
165
+ guessedWordEl.textContent = data.guessed_word;
166
+ guessScoreEl.textContent = `${data.score}%`;
167
+ feedbackTextEl.textContent = data.feedback;
168
+
169
+ scoreIndicatorEl.className = 'w-24 h-24 rounded-full border-8 flex items-center justify-center';
170
+ if (data.score >= 90) {
171
+ scoreIndicatorEl.classList.add('border-green-500', 'text-green-500');
172
+ } else if (data.score >= 70) {
173
+ scoreIndicatorEl.classList.add('border-yellow-500', 'text-yellow-500');
174
+ } else if (data.score >= 50) {
175
+ scoreIndicatorEl.classList.add('border-orange-500', 'text-orange-500');
176
+ } else {
177
+ scoreIndicatorEl.classList.add('border-red-500', 'text-red-500');
178
+ }
179
+ scoreIndicatorEl.querySelector('span').textContent = `${Math.round(data.score)}%`;
180
+
181
+ guessInput.value = '';
182
+ fetchGameState();
183
+ }
184
+ } catch (err) {
185
+ console.error(err);
186
+ statusEl.textContent = "Error submitting guess.";
187
+ statusEl.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700');
188
+ statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700');
189
+ } finally {
190
+ submitGuessBtn.disabled = false;
191
+ submitGuessBtn.classList.remove('opacity-75');
192
+ }
193
+ }
194
+
195
+ function fetchGameState() {
196
+ const formData = new FormData();
197
+ formData.append('player_name', playerName);
198
+
199
+ fetch('https://lemot.online/player/play/', {
200
+ method: 'POST',
201
+ body: formData
202
+ })
203
+ .then(res => res.json())
204
+ .then(data => {
205
+ if (data.error) {
206
+ statusEl.textContent = data.message;
207
+ statusEl.classList.remove('bg-blue-50', 'border-blue-500', 'text-blue-700');
208
+ statusEl.classList.add('bg-red-50', 'border-red-500', 'text-red-700');
209
+ } else {
210
+ statusEl.classList.remove('bg-red-50', 'border-red-500', 'text-red-700');
211
+ statusEl.classList.add('bg-blue-50', 'border-blue-500', 'text-blue-700');
212
+ updateGameState(data);
213
+ }
214
+ })
215
+ .catch(err => {
216
+ console.error(err);
217
+ statusEl.textContent = "Error fetching game state.";
218
+ });
219
+ }
220
+
221
+ function updateGameState(data) {
222
+ gameInfoEl.innerHTML = '';
223
+ previousGuessList.innerHTML = '';
224
+ statusEl.textContent = data.message || '';
225
+
226
+ if (data.session_id) {
227
+ const infoHtml = `
228
+ <div class="space-y-4">
229
+ <div class="flex items-center space-x-2">
230
+ <span class="text-gray-500">Session:</span>
231
+ <span class="font-medium text-gray-800">${data.session_id || ''}</span>
232
+ </div>
233
+ <div class="flex items-center space-x-2">
234
+ <span class="text-gray-500">Turn:</span>
235
+ <span class="font-medium text-gray-800">${data.turn_number || ''}</span>
236
+ </div>
237
+ <div class="flex items-center space-x-2">
238
+ <span class="text-gray-500">Word:</span>
239
+ <span class="font-medium text-gray-800">${data.word || ''}</span>
240
+ </div>
241
+ <div class="border-t border-gray-100 pt-4">
242
+ <h4 class="font-semibold text-gray-800 mb-2">Hints:</h4>
243
+ <ul class="space-y-2">
244
+ <li class="flex items-center space-x-2">
245
+ <i class="fas fa-lightbulb text-yellow-400"></i>
246
+ <span>${data.hint0 || ''}</span>
247
+ </li>
248
+ <li class="flex items-center space-x-2">
249
+ <i class="fas fa-lightbulb text-yellow-400"></i>
250
+ <span>${data.hint1 || ''}</span>
251
+ </li>
252
+ <li class="flex items-center space-x-2">
253
+ <i class="fas fa-lightbulb text-yellow-400"></i>
254
+ <span>${data.hint2 || ''}</span>
255
+ </li>
256
+ <li class="flex items-center space-x-2">
257
+ <i class="fas fa-lightbulb text-yellow-400"></i>
258
+ <span>${data.hint3 || ''}</span>
259
+ </li>
260
+ </ul>
261
+ </div>
262
+ </div>
263
+ `;
264
+ gameInfoEl.innerHTML = infoHtml;
265
+
266
+ if (data.end_timestamp) {
267
+ startCountdown(data.end_timestamp);
268
+ }
269
+ }
270
+
271
+ if (Array.isArray(data.previous_turn_guesses) && data.previous_turn_guesses.length > 0) {
272
+ data.previous_turn_guesses.forEach(g => {
273
+ const li = document.createElement('li');
274
+ li.className = 'flex items-center space-x-3 text-gray-700';
275
+ li.innerHTML = `
276
+ <i class="fas fa-user-circle text-gray-400"></i>
277
+ <span class="font-medium text-indigo-600">${g.player_name}</span>
278
+ <span class="text-gray-400">:</span>
279
+ <span>${g.guess_text}</span>
280
+ `;
281
+ previousGuessList.appendChild(li);
282
+ });
283
+ } else {
284
+ previousGuessList.innerHTML = '<p class="text-gray-500 italic">No guesses from previous turn</p>';
285
+ }
286
+ }
287
+
288
+ // Event Listeners
289
+ submitGuessBtn.addEventListener('click', () => {
290
+ const guessText = guessInput.value.trim();
291
+ submitGuess(guessText);
292
+ });
293
+
294
+ guessInput.addEventListener('keypress', (e) => {
295
+ if (e.key === 'Enter') {
296
+ const guessText = guessInput.value.trim();
297
+ submitGuess(guessText);
298
+ }
299
+ });
300
+
301
+ // Initial fetch
302
+ window.addEventListener('load', fetchGameState);
303
+ </script>
304
+ </div>
305
+ </body>
306
+ </html>