milwright commited on
Commit
eeb2654
Β·
1 Parent(s): 9e70845

Fix level progression and word validation issues

Browse files

- Add validation to prevent selecting all-caps words that appear in passages
- Implement proper 2-round requirement before level advancement
- Update UI to show progress feedback (e.g., "1/2 rounds completed")
- Fix bug where words like "VOLUME" were selected when visible in text

Files changed (3) hide show
  1. src/aiService.js +9 -3
  2. src/app.js +11 -3
  3. src/clozeGameEngine.js +16 -3
src/aiService.js CHANGED
@@ -428,7 +428,7 @@ Return as JSON: {"passage1": {...}, "passage2": {...}}`
428
  parsed.passage2.words = parsed.passage2.words.filter(word => word && word.trim() !== '');
429
 
430
  // Filter problematic words and validate word lengths based on level
431
- const validateWords = (words) => {
432
  const problematicWords = ['negro', 'retard', 'retarded', 'nigger', 'chinaman', 'jap', 'gypsy', 'savage', 'primitive', 'heathen'];
433
  return words.filter(word => {
434
  const cleanWord = word.replace(/[^a-zA-Z]/g, '');
@@ -437,6 +437,12 @@ Return as JSON: {"passage1": {...}, "passage2": {...}}`
437
  // Skip problematic words
438
  if (problematicWords.includes(lowerWord)) return false;
439
 
 
 
 
 
 
 
440
  // Check length constraints
441
  if (level <= 2) {
442
  return cleanWord.length >= 4 && cleanWord.length <= 7;
@@ -451,8 +457,8 @@ Return as JSON: {"passage1": {...}, "passage2": {...}}`
451
  const originalP1Count = parsed.passage1.words.length;
452
  const originalP2Count = parsed.passage2.words.length;
453
 
454
- parsed.passage1.words = validateWords(parsed.passage1.words);
455
- parsed.passage2.words = validateWords(parsed.passage2.words);
456
 
457
  console.log(`βœ… Level ${level} batch validation: P1 ${parsed.passage1.words.length}/${originalP1Count}, P2 ${parsed.passage2.words.length}/${originalP2Count} words passed`);
458
 
 
428
  parsed.passage2.words = parsed.passage2.words.filter(word => word && word.trim() !== '');
429
 
430
  // Filter problematic words and validate word lengths based on level
431
+ const validateWords = (words, passageText) => {
432
  const problematicWords = ['negro', 'retard', 'retarded', 'nigger', 'chinaman', 'jap', 'gypsy', 'savage', 'primitive', 'heathen'];
433
  return words.filter(word => {
434
  const cleanWord = word.replace(/[^a-zA-Z]/g, '');
 
437
  // Skip problematic words
438
  if (problematicWords.includes(lowerWord)) return false;
439
 
440
+ // Check if word appears in all caps in the passage (like "VOLUME")
441
+ if (passageText.includes(word.toUpperCase()) && word === word.toUpperCase()) {
442
+ console.log(`Skipping all-caps word: ${word}`);
443
+ return false;
444
+ }
445
+
446
  // Check length constraints
447
  if (level <= 2) {
448
  return cleanWord.length >= 4 && cleanWord.length <= 7;
 
457
  const originalP1Count = parsed.passage1.words.length;
458
  const originalP2Count = parsed.passage2.words.length;
459
 
460
+ parsed.passage1.words = validateWords(parsed.passage1.words, passage1);
461
+ parsed.passage2.words = validateWords(parsed.passage2.words, passage2);
462
 
463
  console.log(`βœ… Level ${level} batch validation: P1 ${parsed.passage1.words.length}/${originalP1Count}, P2 ${parsed.passage2.words.length}/${originalP2Count} words passed`);
464
 
src/app.js CHANGED
@@ -69,9 +69,11 @@ class App {
69
  <strong>${roundData.title}</strong> by ${roundData.author}
70
  `;
71
 
72
- // Show level information without passage number
73
  const blanksCount = roundData.blanks.length;
74
- this.elements.roundInfo.innerHTML = `Level ${this.game.currentLevel} β€’ ${blanksCount} blank${blanksCount > 1 ? 's' : ''}`;
 
 
75
 
76
  // Show contextualization from AI agent
77
  this.elements.contextualization.innerHTML = `
@@ -160,7 +162,13 @@ class App {
160
  }
161
 
162
  if (results.passed) {
163
- message += ` - Excellent! Advancing to Level ${this.game.currentLevel + 1}! πŸŽ‰`;
 
 
 
 
 
 
164
  this.elements.result.className = 'mt-4 text-center font-semibold text-green-600';
165
  } else {
166
  if (this.game.currentLevel >= 3) {
 
69
  <strong>${roundData.title}</strong> by ${roundData.author}
70
  `;
71
 
72
+ // Show level information
73
  const blanksCount = roundData.blanks.length;
74
+ const levelInfo = `Level ${this.game.currentLevel} β€’ ${blanksCount} blank${blanksCount > 1 ? 's' : ''}`;
75
+
76
+ this.elements.roundInfo.innerHTML = levelInfo;
77
 
78
  // Show contextualization from AI agent
79
  this.elements.contextualization.innerHTML = `
 
162
  }
163
 
164
  if (results.passed) {
165
+ // Check if this completes the requirements for level advancement
166
+ const roundsCompleted = this.game.roundsPassedAtCurrentLevel + 1; // +1 for this round
167
+ if (roundsCompleted >= 2) {
168
+ message += ` - Excellent! Advancing to Level ${this.game.currentLevel + 1}! πŸŽ‰`;
169
+ } else {
170
+ message += ` - Great job! ${roundsCompleted}/2 rounds completed for Level ${this.game.currentLevel + 1}`;
171
+ }
172
  this.elements.result.className = 'mt-4 text-center font-semibold text-green-600';
173
  } else {
174
  if (this.game.currentLevel >= 3) {
src/clozeGameEngine.js CHANGED
@@ -25,6 +25,9 @@ class ClozeGame {
25
  this.currentBooks = []; // Array of two books per round
26
  this.passages = []; // Array of two passages per round
27
  this.currentPassageIndex = 0; // 0 for first passage, 1 for second
 
 
 
28
  }
29
 
30
  async initialize() {
@@ -749,11 +752,21 @@ class ClozeGame {
749
  // Always increment round counter
750
  this.currentRound++;
751
 
752
- // Only advance level if user passed the round
753
  if (roundPassed) {
754
- this.currentLevel++;
 
 
 
 
 
 
 
 
 
 
 
755
  }
756
- // If failed, stay at same level
757
 
758
  // Clear chat conversations for new round
759
  this.chatService.clearConversations();
 
25
  this.currentBooks = []; // Array of two books per round
26
  this.passages = []; // Array of two passages per round
27
  this.currentPassageIndex = 0; // 0 for first passage, 1 for second
28
+
29
+ // Level progression tracking
30
+ this.roundsPassedAtCurrentLevel = 0; // Track successful rounds at current level
31
  }
32
 
33
  async initialize() {
 
752
  // Always increment round counter
753
  this.currentRound++;
754
 
755
+ // Track successful rounds and advance level after 2 successful rounds
756
  if (roundPassed) {
757
+ this.roundsPassedAtCurrentLevel++;
758
+ console.log(`Round passed! Total rounds passed at level ${this.currentLevel}: ${this.roundsPassedAtCurrentLevel}`);
759
+
760
+ // Advance level after 2 successful rounds
761
+ if (this.roundsPassedAtCurrentLevel >= 2) {
762
+ this.currentLevel++;
763
+ this.roundsPassedAtCurrentLevel = 0; // Reset counter for new level
764
+ console.log(`Advancing to level ${this.currentLevel} after 2 successful rounds`);
765
+ }
766
+ } else {
767
+ // Failed round - do not reset the counter, user must accumulate 2 passes
768
+ console.log(`Round failed. Still need ${2 - this.roundsPassedAtCurrentLevel} more passed round(s) to advance from level ${this.currentLevel}`);
769
  }
 
770
 
771
  // Clear chat conversations for new round
772
  this.chatService.clearConversations();