Wordle 实现 - 处理重复字母(边缘情况)

Wordle implementation - dealing with duplicate letters (edge case)

我正在尝试在 angular 中从头开始创建我自己的 wordle 实现,并且一直在尝试解决其中一种边缘情况。假设对于以下所有情况,要猜测的单词是“CLOSE”。

案例 1 - 两个重复的字母都在错误的位置。

如果我的猜测是“CHEER”,那么 'E's are in the wrong position, but "CLOSE" only has one 'E' 因此只有一个应该得到黄色高亮。我的代码 IS 根据需要处理此问题

CASE 2 - 位置正确的字母在前,然后是位置不正确的相同字母

如果我的猜测是“COCKS”,第一个“C”在正确的位置并且应该得到黄色突出显示,而'C' 应该得到灰色突出显示,因为“CLOSE” 只有一个 'C'。我的代码 IS 也根据需要处理此问题

CASE 3 - 位置不正确的字母在前,然后是正确位置的相同字母

如果我的猜测是“LEAVE”,第一个'E'的位置不正确,但是因为第二个'E'位置正确,而“CLOSE”只有一个'E',应该获得灰色突出显示,第二个“E”应该获得绿色突出显示。这是我要修复的极端情况

我的执行结果:

本案例期望的结果:

我目前使用的逻辑:

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);
    }
  }

这里,chosenWord = "CLOSE",currentGuess = "CHEER" 用于案例 1,"COCKS" 用于案例 2,"LEAVE" 用于案例 3

我最终在我的一位高级开发人员的帮助和@Chris G

的评论的帮助下解决了这个问题

这是我使用的解决方案:

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);
    }
  }

我将黄色检查的逻辑拆分为一个单独的循环,并在检查黄色列表之前从列表中删除绿色单词。现在符合我所有的边缘情况

另一种方法是计算所需单词的字母。

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"));