0

我正在尝试构建一个 wordle 求解器作为一个自我项目,但是我陷入了我的一小部分代码中。检查选择词和猜测工作中的每个字母以及它们的颜色代码的方法工作正常,除非有一个带有重复字母的单词(例如:单词 SHARE 可以正常工作,但是单词 GUESS 只会对 GUES 进行颜色代码)。我尝试使用计数器,但我将如何准确地在列表中的正确位置输入字母?

def wordcolor(self, choice, guess):
    guesscolor = dict()
    choiceword = []
    guesslist = []
    guessdict = dict()
    choicedict = dict()
    for a in choice:
        choiceword.append(a)
    for b in guess:
        guesslist.append(b)

    for idx, value in enumerate(choiceword):
        choicedict[idx] = value

    for idx, value in enumerate(guesslist):
        guessdict[idx] = value

    guesscolor[0] = guesslist[0]
    guesscolor[1] = guesslist[1]
    guesscolor[2] = guesslist[2]
    guesscolor[3] = guesslist[3]
    guesscolor[4] = guesslist[4]

    counter = 0

    lengthofword = len(guesslist)

    totalsame = 0

    sameword = 0

    countsguess = Counter(guessh)
    duplicatesguess = [c for c in countsguess if countsguess[c] > 1]
    countschoice = Counter(choice)
    duplicateschoices = [c for c in countschoice if countschoice[c] > 1]

    for a in duplicateschoices:
        if a == None:
            duplicateschoices.append("None")
    for a in duplicatesguess:
        if a == None:
            duplicatesguess.append("None")

    while (counter < lengthofword):
        if guessdict[counter] in choicedict.values():

            totalsame += 1

            if choiceword[counter] == guesslist[counter]:
                print(f"The word at index {counter} is present in both strings in same place")
                sameword += 1
                a = guessdict[counter]
                guesscolor[a] = "green"



            else:
                a = guessdict[counter]
                guesscolor[a] = "orange"
            counter += 1


        else:
            a = guessdict[counter]
            guesscolor[a] = "red"
            counter += 1

    print(guesscolor)

    print("There are " + str(totalsame) + " duplicate characters." + str(sameword) + " of them are in the same place")


Game(0).wordcolor(choice, guessh)

示例输出:

Computer choice word: eject 
Human Guess: ejjet (I haven't made the code to check guesses against dictionary) 
The word at index 0 is present in both strings in same place
The word at index 1 is present in both strings in same place
The word at index 4 is present in both strings in same place
{0: 'e', 1: 'j', 2: 'j', 3: 'e', 4: 't', 'e': 'orange', 'j': 'orange', 't': 'green'} (Ignores duplicate letters) 
There are 5 duplicate characters. 3 of them are in the same place
Incorrect Guess

如果猜测没有重复的字母,则代码有效

Computer choice word: rotas 
Human Guess: share  
0: 's', 1: 'h', 2: 'a', 3: 'r', 4: 'e', 's': 'orange', 'h': 'red', 'a': 'orange', 'r': 'orange', 'e': 'red'}
There are 3 duplicate characters.0 of them are in the same place
Incorrect Guess
4

3 回答 3

0

您当前的代码可能适用于无重复字母的情况,但从代码简单性的角度来看,它并不适用。你做的工作太复杂了。

通常情况下,更智能的数据会导致更简单的代码。要将这个算法重新构建为一个数据问题,请注意有两个逻辑测试:(1)猜测的字母是否与单词的对应字母完全匹配,以及(2)是单词中的猜测字母。以下是可能的结果:

LETTER_COLORS = {
    (True, True): 'green',
    (False, True): 'orange',
    (False, False): 'red',
}

以及使用该数据的代码:

def get_letter_colors(word, guess):
    return {
        g : LETTER_COLORS[g == word[i], g in word]
        for i, g in enumerate(guess)
    }
于 2022-02-23T06:43:02.507 回答
0

如果我正确理解您的问题,您正在寻找一种方法来区分“guess”中的多余字母(应标记为不正确和红色)与“guess”中与“choice”中的字母相对应的字母(应该是绿色还是橙色,具体取决于它们是否在正确的位置)。所谓“多余”,意思是:“guess”中的字母也出现在“choice”中,但“guess”中出现的次数多于“choice”中的次数。

这是您可能解决此特殊情况的一种方法示例,其中包含注释。我在您的“eject”与“ejjet”示例案例中对其进行了测试,它正确地将第一个“j”标记为绿色,第二个标记为红色。

def compareTwoFiveLetterWords(actual, guess):
    # There are three possible conditions for every letter in the guess word:
    # Correct letter, correct position (green)
    # Correct letter, incorrect position (orange)
    # Incorrect letter (red)
    letterColors = []
    
    actualLetterCounts = {}
    for letter in actual:
        if letter not in actualLetterCounts:
            actualLetterCounts[letter] = 1
        else:
            actualLetterCounts[letter] += 1

    guessLetterCounts = {}        
    for letter in guess:
        if letter not in guessLetterCounts:
            guessLetterCounts[letter] = 1
        else:
            guessLetterCounts[letter] += 1

    for letterIndex in range(0, 5):
        if guess[letterIndex] == actual[letterIndex]:
            letterColors.append((guess[letterIndex], 'green'))
        # Only this one condition can lead to the duplicate problem.
        # So, instead of just checking whether the letter is in the word,
        # we have to check how many of it are in the guess versus how many
        # of it are in the actual word.  If it's in the wrong place and the
        # count is higher in guess than actual, it is a wrong letter:
        # color it red.  Otherwise, it's correct but misplaced:  color it orange.
        elif guess[letterIndex] in actual:
            if guessLetterCounts[guess[letterIndex]] > actualLetterCounts[guess[letterIndex]]:
                letterColors.append((guess[letterIndex], 'red'))
                # Decrement the count once the superfluous letter has been labeled incorrect
                guessLetterCounts[guess[letterIndex]] -= 1
            else:
                letterColors.append((guess[letterIndex], 'orange'))
        else:
            letterColors.append((guess[letterIndex], 'red'))

    return letterColors
于 2022-02-23T06:22:50.840 回答
0

每次您检查一个字母时,它都会被添加到guesscolor字典中。这样做的问题是,如果一个值已经存在,它将覆盖该值。因此,如果有重复的字母,则只会保存最后一个重复的字母。我建议改用以下代码:

 while counter < lengthofword:

    if guessdict[counter] in choicedict.values():

        totalsame += 1

        if choiceword[counter] == guesslist[counter]:
            print(f"The word at index {counter} is present in both strings in same place")
            sameword += 1

            guesscolor[counter]["color"] = "green"
        else:
            guesscolor[counter]["color"] = "orange"

        counter += 1
    else:
        guesscolor[counter]["color"] = "red"
        counter += 1

因此,与其添加以索引为键的字母并以字母为键,更好的方法是将字典作为值分配给已经存在的索引键。

这为您提供了以下输出:

{0: {'letter': 'e', 'color': 'green'}, 1: {'letter': 'j', 'color': 'green'}, 2: {'letter': 'j', 'color': 'orange'}, 3: {'letter': 'e', 'color': 'orange'}, 4: {'letter': 't', 'color': 'green'}}

同样在顶部,为了完成这项工作,您需要将其更改为:

for idx, value in enumerate(guesslist): 
     guessdict[idx] = value
    
guesscolor[0] = guesslist[0]
guesscolor[1] = guesslist[1]
guesscolor[2] = guesslist[2]
guesscolor[3] = guesslist[3]
guesscolor[4] = guesslist[4]

为此:

for idx, value in enumerate(guesslist):
     guessdict[idx] = value
     guesscolor[idx] = {"letter": guesslist[idx], "color": ""}

稍后,如果您想打印所有颜色值的列表,您可以执行这样的 for 循环:

for idx in guesscolor:
    print(guesscolor[idx]["color"])

最后一个建议:请将开头的所有字典默认分配从dict()to替换为{}. 使用括号是pythonic的正确方法。也可以更改变量guesslistguessword使代码更具可读性。

于 2022-02-23T06:47:29.660 回答