猜词游戏:尝试构建人工智能

Posted

技术标签:

【中文标题】猜词游戏:尝试构建人工智能【英文标题】:Word-guessing game: trying to build an AI 【发布时间】:2017-08-02 05:12:45 【问题描述】:

我正在尝试创建一个小游戏。

规则很简单:你给一个英文单词,计算机会一个字母一个字母地猜测这个单词。

问题是,我正试图让计算机以一种聪明的方式猜测字母。让我举一个简单的例子来说明我正在尝试构建的内容,以便您理解:

    你把“猫”这个词交给电脑去猜。

    我的 130K 单词列表被缩小到只有 3 个字符的单词,最多只有 805 个单词。从这个单词列表中,创建了一个字母表,只包含 25 个字母(不是全部 26 个),因为新的 805 个单词列表包含字母表中的所有字母,但“z”除外。所以我们现在有一个包含 25 个(不同)字母的列表。

-- 由于我无法在 SO 上上传任何内容,我们将在此示例中说庞大的 130K 单词列表是 10 个单词列表(变量名称“fullDice”)--

如果您尝试运行我的代码,请从此列表中选择一个词,否则 它不会工作

    计算机现在从这 25 个字母列表中猜测一个随机字母。

    如果字母不在单词中,他什么也不做,从列表中重新猜测一个字母。

    但如果字母在单词中,事情就会变得更加复杂。假设计算机猜测字母“c”。我希望计算机将可能的单词列表重新缩小到只有第一个字符中有“c”的单词。这样,805 个单词的列表现在变成了一个只有 36 个单词的列表。因为只有 36 个单词是 3 个字符并且以“c”开头,所以创建了一个新字母表。新的字母表现在只有 14 个字母,让计算机更容易猜出下一个字母并正确判断。以此类推,直到他找到所有的字母。

我被困在第 5 部分。如果您尝试在下面运行我的代码,您会发现字典列表永远不会缩小。那是我的问题。

import time
from random import randint

fullDice = ["panda", "tiger", "cat", "elephant", "whale", "leopard", "gorilla", "fish", "snake", "eagle"]

askForWord = input("Please enter an english word:   ")

while True:

    updatedDice = []

    for k in range (0, len(fullDice)):
        if len(askForWord) == len(fullDice[k]):
            updatedDice += [fullDice[k]]

    alphabet = []

    for i in range (0, len(updatedDice)):
        for n in range (0, len(updatedDice[i])):
            if updatedDice[i][n] not in alphabet:
                alphabet += [updatedDice[i][n]]

    guessRandomLetter = alphabet[randint(0, len(alphabet) - 1)]

    print("I guess the letter:   " + guessRandomLetter)
    print("From this dice: " + str(len(updatedDice)))
    print("From this amount of letters: " + str(len(alphabet)) + "\n")

    time.sleep(0.75)

    guessedWordUnderlined = "_" * len(askForWord)

    if guessRandomLetter in askForWord:

        for m in range(0, len(askForWord)):
            if askForWord[m] == guessRandomLetter:  # CHECKING IF THE GUESSED LETTER IS INSIDE THE WORD
                guessedWordUnderlined = list(guessedWordUnderlined)
                guessedWordUnderlined[m] = guessRandomLetter

        guessedWordUnderlined = ''.join(map(str, guessedWordUnderlined))

        if guessedWordUnderlined == askForWord:  # CHECK IF USER HAS WON

            print("YOU WON")
            break

【问题讨论】:

你尝试过什么调试? 没有。我在 Python 方面没有真正的经验,你能解释一下我的观点以及如何去做吗?顺便说一句,代码没有产生错误信息,那太简单了,错误是逻辑错误。 尝试将print 语句放在显示您怀疑安装错误的不同变量的值周围。这称为“打印调试”,对于快速调试小型简单程序很有用。 哦,是的,当然,我试过了,它并没有真正帮助.. :( 那你一定没找对地方。如果输出错误,那么对输出有贡献的值之一肯定是错误的。 【参考方案1】:

再次查看您的代码后,我相信问题出在声明 guessedWordUnderlined = "_" * len(askForWord) 中。这将创建一个长度等于askFOrWord 的下划线字符串。问题是在while True: 循环的每次迭代中,每个都是一个 new 字符串。这意味着在每次迭代中,字符串变成带有一个正确字母的下划线列表,但在下一次迭代中它会被覆盖。要解决此问题,您应该将行 guessedWordUnderlined = "_" * len(askForWord) 从其当前位置移动到 askForWord = input("Please enter an english word: ") 的正下方。这意味着它存在于全局范围而不是本地范围中,这意味着它不会被覆盖。如果我没记错的话,您还应该将global guessedWordUnderlined 行放在while 循环的开头。这可能需要您重新编写一些代码。希望这对你有用!

【讨论】:

我试过了,说实话并没有真正改变任何东西。最终目标是在每个循环中缩小 2 个主要列表(字母表和更新骰子)。 那么,也许您可​​以选择一个随机字母guessRandomLetter 并使用guessRandomLetter in askForWord 进行测试,以测试该字母是否出现在单词中并从那里开始,而不是现在进行的测试。如果你按照我建议的方式去做,你可能想看看string.index。除此之外,恐怕以目前的信息,我不确定我能做些什么。【参考方案2】:

我相信问题在于if guessedWordUnderlined in askForWord 永远不会是真的。 in 运算符测试第一个运算符是否在第二个参数中,第二个参数是一个容器,例如列表或字符串。 "_" * len(askForWord)guessedWordUnderlined 的值,是一串下划线,你正在测试它是否在askForWOrd 中。如果askForWord 的值是cat,那么askForWord 可以被认为是["c", "a", "t"],所以in 运算符将测试"___" == "c" or "___" == "a" or "___" == "t",没有一个是真的。这意味着它下面的代码永远不会执行,所以代码只会永远重复,随机猜测单词中的字母。我无法真正说出这个if 的功能是什么,因为您已经知道您可以选择的每个字母都在askForWord 中,尽管我确信我遗漏了一些明显的东西。

顺便说一句,您经常使用类似于for x in range(0, len(LIST): ... LIST[x] 的结构,它可以更简洁明了地写成for x in LIST: ... x。比如你的代码

for k in range (0, len(fullDice)):
    if len(askForWord) == len(fullDice[k]):
        updatedDice += [fullDice[k]]

alphabet = []

可以写成

for k in fullDice:
    if len(askForWord) == len(k):
        updatedDice += [k] # This should be updatedDice.append(k), but I
                           # have left it as-is for simplicity's sake.

alphabet = []

这应该有助于您的代码变得更具可读性。可以进行一些其他编辑以使您的代码更具 Python 风格,但除此之外,我看不出它在功能上存在任何问题。如果您分享此 if 应该提供的帮助,它可能会更容易在您的代码中找到任何其他错误。我希望这会有所帮助,祝你好运!

【讨论】:

感谢您的帮助!至于 if 语句,这是我的一个愚蠢错误,我在 SO 上发布它后不久就更改了它,但您之前可能正在查看代码。无论如何,我已将其更改为 if guessRandomLetter in askForWord: 因为我想在运行以下代码之前知道字母是否在单词内。也感谢你的“pythonic way to python”小课=) @Michael 你可能不需要那个if,因为你的代码从单词中随机选择一个字母(假设alphabet 包含askForWord 中唯一字符的列表),所以它总是会评估为True,但它应该可以正常工作。 不,字母表包含整个单词列表中的唯一字符列表。 @Michael 我的错误,对不起;我一直在 cat 上尝试,但这是有道理的。【参考方案3】:

您刚刚问了一个包含该代码的 qs。 我试图使其仅适用于您提供为“python”的词典中的可用单词。

    from random import randint
    import random
    import time
    import datetime
    random.seed(datetime.datetime.now())

    wordOfTheUser = input("ENTER ENGLISH WORD HERE:  ")
    if wordOfTheUser in ("abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"):
            pass
    else:
            print("your word is not on the list, still devlopping.")
            raise

    diceList1 = ["abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"]

    diceList2 = []

    for k in range (0, len(diceList1) - 1):
        if len(diceList1[k]) == len(wordOfTheUser):
            diceList2 += [diceList1[k]]

    makeAlphabet = []

    for b in range (0, len(diceList2)):
        for x in range (0, len(diceList2[b])):
            if diceList2[b][x] not in makeAlphabet:
                makeAlphabet += [diceList2[b][x]]

    computerWordSize = "_" * int(len(wordOfTheUser))
    a= len(makeAlphabet)

    while True:

        try:
            randomIndex = randint(0, a)
        except ValueError:

            randomIndex = randint(0, a)
            pass

        try:
            letterChosenRandomly = makeAlphabet[randomIndex]

        except IndexError as e:
            try:
                randomIndex = randint(0, int(len(makeAlphabet)))
                letterChosenRandomly = makeAlphabet[randomIndex]
            except:
                pass

        print("I guess the letter -> " + letterChosenRandomly)

        diceList3 = []

        if letterChosenRandomly in wordOfTheUser:

            print("\n=== WON ===> " + letterChosenRandomly)
            print("=== ALPHABET ===> " + str(len(makeAlphabet)))
            print("=== HDW1 ===> " + str(len(diceList1)))
            print("=== hdw2 ===> " + str(len(diceList2)))
            print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
            k=-1


            makeAlphabet = []


            for i in range (0, len(wordOfTheUser) ):
                if letterChosenRandomly == wordOfTheUser[i]:
                    computerWordSize = list(computerWordSize)
                    computerWordSize[i] = letterChosenRandomly

                    for l in range (0, len(diceList2)):
                        if computerWordSize[i] == diceList2[l][i]:
                            diceList3 += [diceList2[l]]

                    for d in range(0, len(diceList3)):
                        for h in range(0, len(diceList2[b])):
                            if diceList2[d][h] not in makeAlphabet:
                                makeAlphabet += [diceList2[d][h]]

            won = False

            computerWordSize = ''.join(map(str, computerWordSize))

            print(computerWordSize)

            if computerWordSize == wordOfTheUser:
                won = True

            if won is True:
                print("YOU WON")
                break

            time.sleep(1)

        else:

            print("\n=== LOOSE ===> " + letterChosenRandomly)
            print("=== ALPHABET ===> " + str(len(makeAlphabet)))
            print("=== HDW1 ===> " + str(len(diceList1)))
            print("== hdw2 ===> " + str(len(diceList2)))
            print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
            try:
                makeAlphabet.remove(letterChosenRandomly)
            except:
                print ("Letters not in list")
                break
            k=0

            diceList3 = []

            for q in range (0, len(wordOfTheUser) - 1):
                for l in range(0, len(diceList2)):
                    if computerWordSize[q] == diceList2[l][q]:
                        diceList3 += [diceList2[l]]

            for d in range(0, len(diceList3)):
                for h in range(0, len(diceList2[b])):
                    try:
                        if diceList2[d][h] not in makeAlphabet:
                            makeAlphabet += [diceList2[d][h]]
                    except:
                        try:
                            for s in range(0, len(diceList3)):
                                for f in range(0, len(diceList2)):
                                    if diceList2[s][f] not in makeAlphabet:
                                        makeAlphabet += [diceList2[s][f]]
                        except:
                            ("your word is too short")
            time.sleep(1)

【讨论】:

嘿,感谢您尝试帮助我,但此代码仍然无法按预期工作。每次计算机猜测一个字母时,字母表和单词列表都不会缩小。如果您仍然想帮忙,请尝试查看我上面的实际代码,谢谢 :)

以上是关于猜词游戏:尝试构建人工智能的主要内容,如果未能解决你的问题,请参考以下文章

想知道孩子学习成果?猜词小游戏,随时抽查让他随机背单词!

想知道孩子学习成果?猜词小游戏,随时抽查让他随机背单词!

模拟猜单词游戏

模拟猜单词游戏

用于人工智能中对手预测的神经网络 [关闭]

在AWS上使用Presto和Alluxio构建高性能平台以支持实时游戏服务