利用Python破解猜字游戏Wordle

游戏链接:https://www.powerlanguage.co.uk/wordle/

年前同学给我安利了一款猜字游戏,该游戏每天会指定5位字母单词谜底,玩家有6次机会猜中这个单词。如果字母在谜底中出现且位置对了就显示绿色,字母出现了但位置不对就显示黄色,字母在答案的单词中没出现就显示灰色。


image.png

我属于人菜瘾大,单词量本就薄弱,被这些生僻单词折磨的死去活来,我是怒了,反正玩不起就耍流氓,天下武功唯穷举不破,用代码暴力破解吧。

一、代码思路

1、找到一份英文单词词库,我把词库分享到网盘。
链接:https://pan.baidu.com/s/1lvHw28i9NMxtXuEJkFP3YQ
提取码:6666
2、对词库进行预处理,删除有标点符号的单词、统一单词的大小写。
3、依次猜词:每次猜词时尽量保证选择的单词的字母是不重复的,这样能保证最大化试错概率;每次猜词根据反馈的颜色缩小单词词库,然后每次从词库中随机选择单词,选择的原则还是从重复单词数少的单词组中选择一个。此外,尽可能选择有元音的单词,这样命中率会高些。

代码如下:

## 后面根据猜中情况筛选:orange、black、green    
def apd_col(color_lst,char,location=0):
    color_lst.append([char,location-1])
    return color_lst
        
def select_word_lst(word_lst,org_lst,blk_lst,grn_lst):
    next_word_lst = []
    for word in word_lst:
        org_mark,blk_mark,grn_mark=1,0,1
        ## 黑名单筛选
        for blk_word in blk_lst:
            if word.find(blk_word[0])>=0:
                blk_mark=1
        #绿名单圈选        
        for grn_word in grn_lst:
            if word[grn_word[1]]!=grn_word[0]:
                grn_mark=0
        #黄名单圈选        
        for org_word in org_lst:
            if word[org_word[1]]==org_word[0] or word.find(org_word[0])==-1:
                org_mark=0        
                
        if blk_mark==0 and grn_mark==1 and org_mark==1:
            next_word_lst.append(word)
    return next_word_lst 

if __name__=="__main__":
    import os 
    import random
    os.chdir(r"C:\Users\bingo\Desktop\wordle")
    
    # 读取单词库
    word_lst=[]
    for line in open("data/dic.txt",encoding="utf-8"):
        word=line.split("\uf8f5")[0]
        if len(word.strip())==5 and word.find("-")<0:
            word = word.lower()
            word_lst.append(word)
            
    ## 第一轮 初始化英文字母:包含元音aeiou、尽可能出现所有字母
    init_lst=[]
    for word in word_lst:
        word=word.lower()
        if (word.find("a")>=0 or word.find("e")>=0 or word.find("i")>=0 or word.find("o")>=0 or word.find("u")>=0) and len(set(word))==5 and word.find("-")<0:
            init_lst.append(word)

    init_word = init_lst[random.randrange(len(init_lst))]
    print(init_word)
    
    #第二轮
    org_lst,blk_lst,grn_lst=[],[],[] #初始化
    
    
    
    blk_lst=apd_col(blk_lst,"p",-1)
    blk_lst=apd_col(blk_lst,"a",-1)
    blk_lst=apd_col(blk_lst,"s",-1)
    blk_lst=apd_col(blk_lst,"t",-1)
    blk_lst=apd_col(blk_lst,"e",-1)
    
    grn_lst=apd_col(grn_lst,"e",2)
    word_lst_2 = select_word_lst(word_lst,org_lst,blk_lst,grn_lst)
    #初始两轮尽可能多的选出词汇

    #第三轮
    org_lst=apd_col(org_lst,"o",1)
    org_lst=apd_col(org_lst,"c",3)
    
    blk_lst=apd_col(blk_lst,"r",1)
    blk_lst=apd_col(blk_lst,"i",4)
    blk_lst=apd_col(blk_lst,"n",5)
    word_lst_3 = select_word_lst(word_lst_2,org_lst,blk_lst,grn_lst)

二、改进空间

1、交互做的很垃圾,每次都是在手机里猜单词,然后在电脑上根据反馈结果输入到单词组中,不过我是不想改了,代码能用就行。
2、猜中的单词轮数略多,平均要四-五轮,我看网上有人能做到三轮,我感觉深深的惭愧,这道题就是极大似然概率知识点的典型应用,话说用上算法得多花半天时间,我是没有折腾的劲了,有缘人看到可以尝试下。思路就是每个单词之间是有一定相关概率,每次猜词时可以根据反馈的情况,选择词库中单词中出现概率最高的即可。

你可能感兴趣的:(利用Python破解猜字游戏Wordle)