I am trying to create my own implementation of wordle from scratch in angular and am stuck trying to resolve one of the edge cases. Assume the word to guess for all the following cases is "CLOSE".
CASE 1 - Both duplicate letters are in the wrong position.
If my guess is "CHEER", both of the 'E's are in the wrong position, but "CLOSE" only has one 'E' and hence only one should get a yellow highlight. My code IS dealing with this as desired
CASE 2 - The letter with the correct position comes first followed by the same letter in the incorrect position
If my guess is "COCKS", the first 'C' is in the correct position and should get a yellow highlight whereas 'C' should get a gray highlight since "CLOSE" only has one 'C'. My code IS dealing with this as desired as well
CASE 3 - The letter with the incorrect position comes first followed by the same letter in the correct position
If my guess is "LEAVE", the first 'E' is in the incorrect position, but because the second 'E' is in the correct position, and "CLOSE" only has one 'E', it should get a gray highlight and the second 'E' should get a green highlight. This is the edge case that I want to fix
The outcome of my implementation:
The desired outcome of this case:
The logic that I am using at the moment:
let remainingLettersInWord: string = this.chosenWord;
for (let i = 0; i < 5; i ) {
if (this.currentGuess[i] === this.chosenWord[i]) {
remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
this.setAttributeStyle(i, COLOR.Green);
} else if (remainingLettersInWord.includes(this.currentGuess[i])) {
remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
this.setAttributeStyle(i, COLOR.Yellow);
} else {
this.setAttributeStyle(i, COLOR.Gray);
}
}
Here, chosenWord = "CLOSE", currentGuess = "CHEER" for case 1, "COCKS" for case 2 and "LEAVE" for case 3
CodePudding user response:
I ended up fixing the problem with the help of one of my senior devs and the comment from @Chris G
Here is the solution I used:
let remainingLettersInWord: string = this.chosenWord;
for (let i = 0; i < 5; i ) {
if (this.currentGuess[i] === this.chosenWord[i]) {
remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
this.setAttributeStyle(i, COLOR.Green);
} else {
this.setAttributeStyle(i, COLOR.Gray);
}
}
for (let i = 0; i < 5; i ) {
if (remainingLettersInWord.includes(this.currentGuess[i]) && this.currentGuess[i] !== this.chosenWord[i]) {
remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
this.setAttributeStyle(i, COLOR.Yellow);
}
}
I split the logic for the yellow check into a separate loop and I am removing the green words from the list before checking the yellow list. That adheres to all my edge cases now
CodePudding user response:
A different approach by counting the letters of the wanted word.
const
getColors = ([...word], [...input]) => {
const
count = {},
result = Array(5).fill('-'); // only to show the result.
for (let i = 0; i < input.length; i ) {
if (word[i] === input[i]) result[i] = 'green';
else count[word[i]] = (count[word[i]] || 0) 1;
}
for (let i = 0; i < input.length; i ) {
if (word[i] === input[i] || !count[input[i]]) continue;
count[input[i]]--;
result[i] = 'yellow';
}
return result;
};
console.log(...getColors("CLOSE", "CHEER"));
console.log(...getColors("CLOSE", "COCKS"));
console.log(...getColors("CLOSE", "LEAVE"));