Python算法- 为游戏“鬼”智能查找所有“获胜”字母排列的方法

1 投票
2 回答
1797 浏览
提问于 2025-04-16 10:45

我正在写一个电脑程序来玩单词游戏“鬼魂”。

现在这个程序的工作方式是这样的:

--用户选择一个字母(目前只有用户先出手时才能使用)

--电脑有一个包含所有可能的奇数单词的字典列表(这样用户必须完成每个单词,否则就会输)。在用户每次选择字母后,电脑会通过一个循环来缩减它的单词列表:

 wordList = [w for w in wordList if w.startswith(currentWord)]

这样它的“wordList”中只保留符合当前正在拼写的单词。

--然后,电脑从当前的单词列表中随机选择一个单词,并返回这个单词的相应字母。接着,它会通过以下代码更新自己的列表:

 randomnumber = random.randint(0, len(wordList)-1)
 currentWord+=wordList[randomnumber][len(currentWord)]
 wordList = [w for w in wordList if w.startswith(currentWord)]

--这个过程会持续进行,直到用户拼出一个单词,这会通过checkLoss函数来检测,或者电脑无法继续拼单词而触发checkBluff函数。checkBluff函数要求用户写出他在想的单词,以确保他不是在编造。

--*问题在这里:* 显然,因为电脑是随机选择字母,所以有些单词会导致输。例如,如果第一个玩家选择字母“d”,那么电脑很可能会选择“e”,因为有很多单词以“de”开头。然而,如果用户在第三轮选择字母“e”,使得当前拼写为“dee”,那么电脑的列表中就没有符合的单词(英语中只有一个符合这个形式的单词:'deed',而且是偶数,因此会输),所以触发了bluff函数,电脑就输了,因为用户揭示他想到的确实是一个真实的单词“deed”。

所以,我想要一个算法,让电脑提前思考,这样它就不会选择一个让第一个玩家强制输的后续字母。 例如,如果选择了“d”,电脑就不应该选择“e”,因为这样会导致后面再选一个“e”就会输。同样,如果用户选择了“h”,电脑就不应该跟着选“o”,因为用户可以再说“c”,这样就会拼出“hock”。

我想不出办法来实现这个。

如果需要,这里是完整的程序:

import os, random, sys, math, string

def checkBluff(currentWord, choice, fullList):
    if choice.startswith(currentWord):
        #print "this is accurate"
        for line in fullList:
            if line == choice:
                return 1
    return 0

def checkLoss(currentWord, fullList):
    for line in fullList:
       if currentWord == line:
           return 1
    return 0 

def instantiateWordList(dictionary, wordList):
    for line in dictionary:
        wordList.append(line.strip())
    return wordList



def main():

    fullDict = open("wordlist.txt", "r") #fullDict contains all possible words
    winFirst = open("firstwin.txt", "r") #winFirst contains all odd-numbered words
    winSecond = open("secondwin.txt", "r")#winSecond contains all even-numbered words
    turn = "Human"
    currentWord = ""
    wordList = []
    fullList= []
    bluff = ""

#Instantiates a list with every word for use in evaluating win/loss
for line in fullDict:
    fullList.append(line.strip())

#Decide who goes first
choice = raw_input("1. I will go first \n2. I will go second\n>>")[0]

if choice == "1":
    wordList = instantiateWordList(winSecond, wordList)
    turn == "Human"
else:  
    wordList = instantiateWordList(winFirst, wordList)
    turn == "Computer"

while True:
    if turn == "Human":  
        choice = raw_input("Choose a letter: ")[0]
        currentWord+=choice


        if checkLoss(currentWord, fullList) == 1:
            print "You have lost by spelling the word "+ currentWord
            break 


        print "**Current Word**"+ currentWord
        wordList = [w for w in wordList if w.startswith(currentWord)]
        turn = "Computer"

    if turn == "Computer":
        try: 
            randomnumber = random.randint(0, len(wordList)-1)
            currentWord+=wordList[randomnumber][len(currentWord)]
            print "I am thinking of the word: "+ str(wordList[randomnumber])
            wordList = [w for w in wordList if w.startswith(currentWord)]

            print "**Current word**: "+ currentWord
            print "length: "+ str(len(wordList))
            turn = "Human"
        except StandardError:
            bluff = raw_input("I call bluff.  What word were you thinking of?\n>>")
            if checkBluff(currentWord, bluff, fullList) == 1:
                print "You actually won!"
                break
            else:
                print "You lost.  You lying son of a bitch."
                break 


if __name__ == "__main__":
    main()

2 个回答

0

为了让程序不输,它还需要保留一个偶数位置单词的列表(哦,它确实有,只是我一开始没注意到

在决定下一个字母时,程序应该先查看它的偶数位置(失去的)单词列表。如果有 n+2 个字符长的单词(当 n=1 时是4个字符,n=3 时是6个字符等等,n 是当前字母的位置),那么它就不应该使用那些单词中 n 位置的字母。

举个“deed”的例子:

  1. 用户输入“d”
  2. 程序发现有一个以“d”开头且长度为4个字符的单词:“deed”。
  3. 它把“deed”中第1个字母(也就是“e”)加到“限制”字母的列表里。
  4. 它扫描“获胜”单词的列表,忽略那些以“de”开头的单词,然后得到一个“可用”字母的列表。
  5. 它从这个列表中随机选择一个字母并显示给用户。
1

你想让电脑提前预测,但又要随机选择?:-)

这个游戏其实很简单,也很容易让电脑总是赢,如果你愿意的话。实际上,你可以提前生成一些策略树,这样就能确保电脑获胜。这些策略树其实也不复杂,如果你想的话,可以把它们记住。

如果你不想这样做,那就只需要考虑下一轮的情况。在你提到的例子中,提前一轮就能看到对手可以在下一轮强迫获胜,所以电脑会避免“de”。但这样做并不能避免对手在两轮后让电脑输的情况。

不过,要做到这一点,你需要考虑所有可能的情况。然后你可以在剩下的选择中随机挑选。

撰写回答