游戏链接: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、猜中的单词轮数略多,平均要四-五轮,我看网上有人能做到三轮,我感觉深深的惭愧,这道题就是极大似然概率知识点的典型应用,话说用上算法得多花半天时间,我是没有折腾的劲了,有缘人看到可以尝试下。思路就是每个单词之间是有一定相关概率,每次猜词时可以根据反馈的情况,选择词库中单词中出现概率最高的即可。