Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions stores/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import { defineStore } from 'pinia';
import { useLanguageStore } from '~/stores/language';
import { useSettingsStore } from '~/stores/settings';
import { useStatsStore } from '~/stores/stats';
import { buildNormalizedWordMap, normalizeWord } from '~/utils/diacritics';
import {
buildNormalizedWordMap,
charsMatch,
normalizeChar,
normalizeWord,
} from '~/utils/diacritics';
import { toFinalForm, toRegularForm } from '~/utils/positional';
import { splitWord } from '~/utils/graphemes';
import { calculateCommunityPercentile } from '~/utils/stats';
Expand Down Expand Up @@ -967,6 +972,9 @@ export const useGameStore = defineStore('game', () => {
* Returns an error message if invalid, or null if valid.
*/
function checkHardMode(guess: string): string | null {
const lang = useLanguageStore();
const nMap = lang.normalizeMap;

for (let r = 0; r < activeRow.value; r++) {
const row = tiles.value[r];
const colors = tileColors.value[r];
Expand All @@ -978,11 +986,15 @@ export const useGameStore = defineStore('game', () => {
if (!letter) continue;

if (color === 'correct') {
if (guess[c]?.toLowerCase() !== letter.toLowerCase()) {
if (!charsMatch(guess[c] || '', letter, nMap)) {
return `Hard mode: ${letter.toUpperCase()} must be in position ${c + 1}`;
}
} else if (color === 'semicorrect') {
if (!guess.toLowerCase().includes(letter.toLowerCase())) {
const normalizedLetter = normalizeChar(letter, nMap).toLowerCase();
const guessHasLetter = [...guess].some(
(g) => normalizeChar(g, nMap).toLowerCase() === normalizedLetter
);
if (!guessHasLetter) {
return `Hard mode: guess must contain ${letter.toUpperCase()}`;
}
Comment on lines 988 to 999
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check which languages define both positional variants and hard mode
# Look for languages with final_form_map (positional) that might also use hard mode

echo "=== Languages with final_form_map (positional variants) ==="
rg -l 'final_form' --type=json --type=yaml

echo ""
echo "=== Check if these configs also have diacritic_map ==="
fd -e json -e yaml . | xargs rg -l 'final_form' | head -5 | while read f; do
  echo "--- $f ---"
  rg -A2 -B2 'final_form|diacritic_map' "$f" | head -20
done

Repository: Hugo0/wordle

Length of output: 631


🏁 Script executed:

# Find and examine the key functions mentioned in the review
grep -n "function charsMatch\|const charsMatch\|function normalizeChar\|const normalizeChar\|function fullCharsMatch\|const fullCharsMatch" stores/game.ts

Repository: Hugo0/wordle

Length of output: 122


🏁 Script executed:

# Also get context around these functions to understand their implementations
sed -n '1,50p' stores/game.ts | head -30

Repository: Hugo0/wordle

Length of output: 1298


🏁 Script executed:

# Check if hard mode is a configuration option in language configs
rg -A5 -B5 'hard.?mode|hardMode' data/languages/*/language_config.json

Repository: Hugo0/wordle

Length of output: 38


🏁 Script executed:

# Get fullCharsMatch implementation
sed -n '204,230p' stores/game.ts

Repository: Hugo0/wordle

Length of output: 890


🏁 Script executed:

# Get charsMatch and normalizeChar from diacritics utils
cat -n utils/diacritics.ts | head -100

Repository: Hugo0/wordle

Length of output: 3320


🏁 Script executed:

# Search for hard mode configuration/usage
rg -n 'hard.?mode|hardMode' stores/game.ts | head -20

Repository: Hugo0/wordle

Length of output: 665


🏁 Script executed:

# Find fullNormalize function
rg -n "function fullNormalize|const fullNormalize" stores/game.ts

Repository: Hugo0/wordle

Length of output: 110


🏁 Script executed:

# Get checkHardMode function implementation
sed -n '971,1050p' stores/game.ts

Repository: Hugo0/wordle

Length of output: 3077


🏁 Script executed:

# Also look for where fullNormalize is defined or what it does
rg -B5 -A10 "fullNormalize" stores/game.ts | head -50

Repository: Hugo0/wordle

Length of output: 2056


🏁 Script executed:

# Get fullNormalize and understand what toRegularForm does
cat -n utils/positional.ts | head -60

Repository: Hugo0/wordle

Length of output: 2592


🏁 Script executed:

# Check if Hebrew or Greek enable hard mode in their configs
cat -n data/languages/he/language_config.json

Repository: Hugo0/wordle

Length of output: 3367


🏁 Script executed:

# Check Greek config too
cat -n data/languages/el/language_config.json

Repository: Hugo0/wordle

Length of output: 2809


🏁 Script executed:

# Search for any references to finalFormReverseMap in game.ts to understand usage
rg -n "finalFormReverseMap" stores/game.ts

Repository: Hugo0/wordle

Length of output: 137


Positional variant handling IS required for hard mode.

The color algorithm uses fullCharsMatch() which normalizes both positional variants (via finalFormReverseMap) and diacritics. The hard mode validation uses charsMatch() and normalizeChar() which only handle diacritics.

This creates an inconsistency for languages with both positional variants and diacritics. Greek is affected: it defines both final_form_map (σ → ς) and diacritic_map. When hard mode is enabled (a global setting, not per-language), the color algorithm would consider σ and ς as equivalent, but hard mode validation would reject a guess if the positional form differs.

Update checkHardMode() to use fullCharsMatch() instead of charsMatch() for the 'correct' color validation, or apply the same full normalization using finalFormReverseMap before comparing characters.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@stores/game.ts` around lines 988 - 999, The hard-mode validation in
checkHardMode is using charsMatch/normalizeChar (which only handle diacritics)
causing mismatch with the color algorithm that uses fullCharsMatch (which also
applies finalFormReverseMap positional normalization); update the 'correct'
branch to call fullCharsMatch(guess[c] || '', letter, nMap) instead of
charsMatch, and ensure the 'semicorrect' check also compares using the same full
normalization (use fullChar normalization via finalFormReverseMap before the
.toLowerCase() comparison) so positional variants like σ/ς are treated
consistently with the color algorithm.

}
Expand Down
Loading