用Python实现Wordle AI猜词:三种策略对比与胜率分析
最近在整理算法小项目时想到了一个特别适合练手的主题把 Wordle 猜词游戏用 Python 实现一遍再让不同的“AI 选手”自动玩这个游戏看谁的胜率更高、平均猜中轮数更少。这个项目看起来简单但拆开后涉及反馈判定、候选词过滤、信息熵计算、批量模拟评估正好可以把枚举、贪心、信息论这几个基础话题串起来。如果你刚开始学算法或者想找一个不需要大模型也能讲清楚“AI 思路”的项目这篇教程应该很适合你。市面上很多“AI 猜词”项目直接接大模型 API让模型根据历史反馈猜下一个词。但这一篇会先绕开大模型用经典算法实现三种策略随机猜词、词频优先、信息熵最大化。这样能直观看到不同策略对胜率的影响也能自己动手改策略、加优化。等基础版本跑通后再考虑把大模型作为竞速选手接入对比也是顺理成章的事。1. 项目背景Wordle 与 AI 猜词挑战1.1 Wordle 游戏规则Wordle 是一款猜单词的小游戏。系统会随机选择一个五字母英文单词作为答案玩家在六次机会内不断猜测。每次猜测后游戏会给出三色反馈绿色字母正确且位置也正确。黄色字母在答案中存在但位置不对。灰色字母不在答案中或者超出了答案中该字母的数量。举个例子假设答案是apple猜测是apply那么反馈为答案猜测反馈解释appleapply绿 绿 绿 绿 灰前四个字母位置正确y 不在答案中再看一个重复字母的例子。假设答案是eerie猜测是eject答案猜测反馈解释eerieeject绿 灰 黄 灰 灰第一个 e 位置正确第三个猜测位置的 e 存在但位置不对这个规则看起来简单但重复字母的处理很容易出错。后面实现make_feedback时会专门说明。1.2 为什么叫“小型 AI 挑战”这里的“AI 挑战”并不是指用神经网络训练一个模型而是指让程序自主决策根据之前的反馈从候选词集合中筛选答案并决定下一步猜什么。这个问题的本质是“主动学习”或“最优实验设计”每一步选择一个猜测目标是尽快缩小答案范围。经典的信息熵贪心策略是其中的代表方法它不依赖任何外部模型也能在真实游戏中达到很高的胜率。1.3 本文最终完成的功能整个项目会包含四个文件wordle.py游戏核心负责计算三色反馈和单局流程。words.py演示词表内置 100 个五字母英文单词。player.py三种 AI 猜词策略。main.py命令行入口支持批量模拟和人机对战。最终你可以用一条命令让 AI 自动玩几百局并统计胜率和平均猜中轮数也可以自己扮演玩家在终端里玩一局原汁原味的 Wordle。2. 环境准备与项目结构2.1 环境说明本项目使用 Python 标准库实现不依赖任何第三方包。理论上 Python 3.8 及以上版本都能直接运行。我会用到argparse、random、collections.Counter、math这些模块都属于标准库。如果你的机器上有多个 Python 版本创建虚拟环境再运行更稳妥python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate当然本项目零第三方依赖不创建虚拟环境也可以直接运行。2.2 项目目录结构建议新建一个wordle-ai-challenge目录所有代码都放在里面wordle-ai-challenge/ ├── main.py # 命令行入口 ├── player.py # AI 猜词策略 ├── wordle.py # Wordle 游戏核心 └── words.py # 演示词表每个文件的职责非常清晰words.py只负责提供词表。wordle.py只负责规则判定。player.py实现不同的决策算法。main.py负责把前面的模块串起来提供用户交互入口。这样拆分的好处是之后如果想把player.py里的策略换成大模型 API只需要保证guess()和update()两个接口不变即可游戏核心完全不用改动。3. 游戏规则与反馈判定3.1 反馈判定的核心难点实现 Wordle 反馈判定最大的坑是重复字母。例如答案apple猜测amplea在 0 位正确绿色。m不在答案中灰色。p在 2 位答案 2 位也是p绿色。l在 3 位绿色。e在 4 位绿色。但如果猜测是peachanswer是apple情况就会复杂一些。guess中出现了p、e、a这些字母都存在于答案中但不能无限给黄色因为答案里的每个字母只能匹配一次。正确的处理方式分两步先扫描一次把所有“字母和位置都正确”的位置标记为绿色。再扫描一次对非绿色位置检查该字母是否还“剩余可用”如果可用就标记为黄色并从剩余集合中移除否则标记为灰色。这样可以避免把同一个答案字母重复匹配到多个猜测字母上。3.2 实现游戏核心创建wordle.py Wordle 游戏核心逻辑反馈判定与单局游戏流程。 from typing import List, Tuple, Optional GREEN green YELLOW yellow GRAY gray MAX_GUESSES 6 Feedback Tuple[str, ...] def make_feedback(secret: str, guess: str) - Feedback: 计算一次猜测的反馈。 - green字母正确且位置正确 - yellow字母存在于答案中但位置不对 - gray字母不在答案中或超出答案中该字母的剩余数量 先标记所有 green再为 yellow 分配剩余字母确保重复字母处理正确。 if len(secret) ! len(guess): raise ValueError(secret 和 guess 长度不一致) result: List[str] [GRAY] * len(secret) unmatched: List[str] [] # 第一遍标记 green并收集非 green 位置的答案字母 for idx, (s, g) in enumerate(zip(secret, guess)): if s g: result[idx] GREEN else: unmatched.append(s) # 第二遍为剩余位置分配 yellow / gray for idx, (s, g) in enumerate(zip(secret, guess)): if result[idx] GREEN: continue if g in unmatched: result[idx] YELLOW unmatched.remove(g) else: result[idx] GRAY return tuple(result) def is_valid_guess(guess: str, word_list) - bool: return len(guess) 5 and guess in word_list def play_once(secret: str, player, word_list, max_guesses: int MAX_GUESSES) - Optional[int]: 使用指定 player 完成一局游戏。 返回猜中所

相关新闻