milwright commited on
Commit
04bba1d
Β·
1 Parent(s): 4ea90f7

add streak indicator and prevent concatenated word selection

Browse files
Files changed (3) hide show
  1. index.html +5 -2
  2. src/aiService.js +8 -2
  3. src/app.js +19 -0
index.html CHANGED
@@ -28,7 +28,10 @@
28
  <div class="paper-content">
29
  <div class="flex justify-between items-center mb-4">
30
  <div id="book-info" class="biblio-info"></div>
31
- <div id="round-info" class="round-badge px-3 py-1 rounded-full text-sm"></div>
 
 
 
32
  </div>
33
  <div id="contextualization" class="context-box mb-4 p-3 rounded-lg"></div>
34
  <div id="passage-content" class="prose max-w-none mb-6"></div>
@@ -59,7 +62,7 @@
59
  Show Hints
60
  </button>
61
  <div class="controls-divider"></div>
62
- <button id="leaderboard-btn" class="leaderboard-footer-btn" title="View leaderboard">
63
  πŸ…
64
  </button>
65
  </div>
 
28
  <div class="paper-content">
29
  <div class="flex justify-between items-center mb-4">
30
  <div id="book-info" class="biblio-info"></div>
31
+ <div class="flex gap-2 items-center">
32
+ <div id="streak-info" class="round-badge px-3 py-1 rounded-full text-sm hidden"></div>
33
+ <div id="round-info" class="round-badge px-3 py-1 rounded-full text-sm"></div>
34
+ </div>
35
  </div>
36
  <div id="contextualization" class="context-box mb-4 p-3 rounded-lg"></div>
37
  <div id="passage-content" class="prose max-w-none mb-6"></div>
 
62
  Show Hints
63
  </button>
64
  <div class="controls-divider"></div>
65
+ <button type="button" id="leaderboard-btn" class="leaderboard-footer-btn" title="View leaderboard">
66
  πŸ…
67
  </button>
68
  </div>
src/aiService.js CHANGED
@@ -242,7 +242,7 @@ class OpenRouterService {
242
  content: 'Select words for a cloze exercise. Return ONLY a JSON array of words, nothing else.'
243
  }, {
244
  role: 'user',
245
- content: `Select ${count} ${level <= 2 ? 'easy' : level <= 4 ? 'medium' : 'challenging'} words (${wordLengthConstraint}) from this passage. Choose meaningful nouns, verbs, or adjectives. Avoid capitalized words and proper nouns.
246
 
247
  Passage: "${passage}"`
248
  }],
@@ -382,6 +382,12 @@ Passage: "${passage}"`
382
  return false;
383
  }
384
 
 
 
 
 
 
 
385
  // Check if word exists as non-capitalized word after position 10 (matches game engine)
386
  if (!passageWordMap.has(cleanWord.toLowerCase())) {
387
  return false;
@@ -524,7 +530,7 @@ Passage: "${passage}"`
524
  content: 'Process passages for cloze exercises. Return ONLY a JSON object.'
525
  }, {
526
  role: 'user',
527
- content: `Select ${blanksPerPassage} ${level <= 2 ? 'easy' : level <= 4 ? 'medium' : 'challenging'} words (${wordLengthConstraint}) from each passage.
528
 
529
  Passage 1 ("${book1.title}" by ${book1.author}):
530
  ${passage1}
 
242
  content: 'Select words for a cloze exercise. Return ONLY a JSON array of words, nothing else.'
243
  }, {
244
  role: 'user',
245
+ content: `Select ${count} ${level <= 2 ? 'easy' : level <= 4 ? 'medium' : 'challenging'} words (${wordLengthConstraint}) from this passage. Choose meaningful nouns, verbs, or adjectives. Avoid capitalized words and proper nouns. NEVER select concatenated words like "fromthe", "tothe", "andthe", "hewas", "shewas" - these should be two separate words.
246
 
247
  Passage: "${passage}"`
248
  }],
 
382
  return false;
383
  }
384
 
385
+ // Reject obvious concatenated words like "fromthe", "tothe", etc.
386
+ if (/^(from|to|and)(the|a)$/i.test(cleanWord)) {
387
+ console.log(`🚫 Rejected concatenated word: "${word}"`);
388
+ return false;
389
+ }
390
+
391
  // Check if word exists as non-capitalized word after position 10 (matches game engine)
392
  if (!passageWordMap.has(cleanWord.toLowerCase())) {
393
  return false;
 
530
  content: 'Process passages for cloze exercises. Return ONLY a JSON object.'
531
  }, {
532
  role: 'user',
533
+ content: `Select ${blanksPerPassage} ${level <= 2 ? 'easy' : level <= 4 ? 'medium' : 'challenging'} words (${wordLengthConstraint}) from each passage. NEVER select concatenated words like "fromthe", "tothe", "andthe", "hewas", "shewas" - these should be two separate words.
534
 
535
  Passage 1 ("${book1.title}" by ${book1.author}):
536
  ${passage1}
src/app.js CHANGED
@@ -16,6 +16,7 @@ class App {
16
  stickyControls: document.getElementById('sticky-controls'),
17
  bookInfo: document.getElementById('book-info'),
18
  roundInfo: document.getElementById('round-info'),
 
19
  contextualization: document.getElementById('contextualization'),
20
  passageContent: document.getElementById('passage-content'),
21
  hintsSection: document.getElementById('hints-section'),
@@ -82,6 +83,9 @@ class App {
82
 
83
  this.elements.roundInfo.innerHTML = levelInfo;
84
 
 
 
 
85
  // Show contextualization from AI agent
86
  this.elements.contextualization.innerHTML = `
87
  <div class="flex items-start gap-2">
@@ -192,6 +196,21 @@ class App {
192
  // Show next button and hide submit button
193
  this.elements.submitBtn.style.display = 'none';
194
  this.elements.nextBtn.classList.remove('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
196
 
197
  highlightAnswers(results) {
 
16
  stickyControls: document.getElementById('sticky-controls'),
17
  bookInfo: document.getElementById('book-info'),
18
  roundInfo: document.getElementById('round-info'),
19
+ streakInfo: document.getElementById('streak-info'),
20
  contextualization: document.getElementById('contextualization'),
21
  passageContent: document.getElementById('passage-content'),
22
  hintsSection: document.getElementById('hints-section'),
 
83
 
84
  this.elements.roundInfo.innerHTML = levelInfo;
85
 
86
+ // Update streak display
87
+ this.updateStreakDisplay();
88
+
89
  // Show contextualization from AI agent
90
  this.elements.contextualization.innerHTML = `
91
  <div class="flex items-start gap-2">
 
196
  // Show next button and hide submit button
197
  this.elements.submitBtn.style.display = 'none';
198
  this.elements.nextBtn.classList.remove('hidden');
199
+
200
+ // Update streak display after processing results
201
+ this.updateStreakDisplay();
202
+ }
203
+
204
+ updateStreakDisplay() {
205
+ const stats = this.game.leaderboardService.getPlayerStats();
206
+ const currentStreak = stats.currentStreak;
207
+
208
+ if (currentStreak > 0) {
209
+ this.elements.streakInfo.innerHTML = `πŸ”₯ ${currentStreak} streak`;
210
+ this.elements.streakInfo.classList.remove('hidden');
211
+ } else {
212
+ this.elements.streakInfo.classList.add('hidden');
213
+ }
214
  }
215
 
216
  highlightAnswers(results) {