资讯动态

WLED TetrisAI_v2 Usermod 实战:在 ESP32 LED 矩阵上运行自玩俄罗斯方块 AI 效果

发布时间:2026/9/13 10:03:25 来源:尧图企业网站定制
WLED TetrisAI_v2 Usermod 实战在 ESP32 LED 矩阵上运行自玩俄罗斯方块 AI 效果【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED本文基于 WLED 官方 usermod 库中的 TetrisAI_v2 模块readme.md撰写讲解如何将自玩俄罗斯方块作为一个 2D 灯光效果编译进 WLED 固件、在 ESP32 WS2812B 矩阵上启用并逐项解读其滑块/复选框参数背后的源码实现从 7-bag 随机出块、位掩码棋盘到启发式 AI 评估函数的完整链路。读完后你可以独立完成该 usermod 的编译安装、按效果元数据正确配置参数并理解智能度滑块实际上是如何扰动 AI 权重的。一、TetrisAI_v2 是什么TetrisAI_v2 是一个以 WLED usermod 形式提供的效果effect它内置一个完整的俄罗斯方块游戏引擎和一个启发式 AIAI 自动落子、清线把整个游戏过程实时渲染到 LED 矩阵上。效果在 WebUI 中以名称Tetris AI出现属于 2D 效果因此需要 WLED0.14 及以上版本依赖 matrix/2D 段支持非矩阵1D 灯带环境下效果会直接用前景色填充段后返回不产生游戏画面作者声明的测试环境是ESP32 4MB WS2812B 16x16 矩阵。一个需要特别注意的安全提示原文档原文强调光敏性癫痫警告——默认情况下消行时会有一行以 200ms 周期在灰/黑之间闪烁的动画。该效果可以在 WLED 的 usermod 设置页中通过noFlashOnClear配置项关闭见第五节。二、安装把 tetrisai_v2 加进编译2.1 最小安装步骤按照 readme.md 的说明只需在platformio_override.ini中加入一行custom_usermods tetrisai_v2编译后Tetris AI 效果即出现在效果列表中。如果与默认 usermod 共存可以按 platformio_override.sample.ini 中推荐的写法保留默认集合并追加custom_usermods ${env:esp32dev.custom_usermods} tetrisai_v22.2 名字从哪里来custom_usermods里的条目名不是随意的。构建脚本 load_usermods.py 会解析该变量并在usermods/目录下按原名、原名_v2、usermod_v2_原名等规则查找对应目录find_usermodpio-scripts/load_usermods.py#L13-L28。本模块目录是usermods/TetrisAI_v2/其 library.json 声明name: TetrisAI_v2且build: { libArchive: false }因此tetrisai_v2不区分大小写匹配能正确命中。模块的入口在 TetrisAI_v2.cppTetrisAIUsermod::setup()调用strip.addEffect(255, mode_2DTetrisAI, _data_FX_MODE_2DTETRISAI)注册效果ID 255 表示动态分配usermod 自身 ID 为USERMOD_ID_TETRISAI 47定义于 wled00/const.h#L243。2.3 Flash 空间不足时切换分区表该模块会引入一个完整的游戏引擎 AI含递归搜索可能挤占代码分区。readme 给出的解决方案是换用代码分区更大、文件系统分区更小的布局例如tools/WLED_ESP32_4MB_256KB_FS.csv该分区文件实际存在于 tools/WLED_ESP32_4MB_256KB_FS.csv在platformio_override.ini中追加board_build.partitions tools/WLED_ESP32_4MB_256KB_FS.csvtools/目录下还有同系列的其他分区表可按需选择如 512KB、700KB FS 变体见 tools/ 目录下的WLED_ESP32_4MB_*.csv文件。注意该分区只适用于 4MB flash 的 ESP32如果你的 flash 容量不同请选择对应的WLED_ESP32_*MB*.csv。三、推荐的颜色与调色板配置readme 给出的观感最佳组合对应效果元数据中的前景/背景/边框三色颜色槽建议值作用源码依据背景色background黑色未落子格子的填充色TetrisAI_v2.cpp#L52-L54 中gridPixel 0时取SEGCOLOR(1)边框色border浅灰划分下一块预览区与棋盘的 1 像素竖线取SEGCOLOR(2)前景色foreground即 Game Over 色深灰游戏结束动画中逐格熄灭的填充色gridPixel 254时取SEGCOLOR(0)调色板paletteRainbow各落子方块颜色从调色板按 1/32 分段取色方块颜色的映射在 TetrisAI_v2.cpp#L64-L68每个块的colorIndex乘以 32 后加上动态colorOffset再ColorFromPalette(SEGPALETTE, ...)取色因此把 7 种块均匀铺满整个调色板——换用 Rainbow 调色板时七块呈现彩虹分布这是Rainbow 推荐的直接原因。四、参数详解滑块与复选框如何映射到源码效果元数据字符串完整定义在 TetrisAI_v2.cpp#L255Tetris AI!,Look ahead,Intelligence,Rotate color,Mistake free,Show next,Border,Mistakes;Game Over,!,Border;!;2;sx127,ix64,c1255,c20,c331,o11,o21,o30,pal11按 WLED 效果元数据约定解析效果名 Tetris AI滑块依次为Look ahead强度槽 intensity、Intelligencecustom1、Rotate colorcustom2、Mistake freecustom3颜色名依次为前景 Game Over、背景默认、边框 Border复选框依次为Show nextcheck1、Bordercheck2、Mistakescheck3末尾的2声明这是 2D 效果分号后为默认值speed127、intensity64、c1255、c20、c331、check11、check21、check30、pal11Rainbow。4.1 滑块Sliders滑块源码映射作用与取值speed效果速度槽msDelayMove 1024 - (4 * SEGMENT.speed)TetrisAI_v2.cpp#L129游戏速度。速度 0 → 每步 1024ms255 → 约 4ms即AI 每一步落一格或换一个决策周期的刷新间隔Look aheadintensitynLookAhead intensity ? (intensity 7) 2 : 1TetrisAI_v2.cpp#L133AI 允许预知多少块0intensity0只看当前块1~127 预知 1 块128~255 预知 2 块。与 readme0 - 2一致Intelligencecustom1扰动四个启发式权重TetrisAI_v2.cpp#L191-L200AI 有多会玩。255 时不扰动满智能调低后权重被偏移决策变差。机制见第五节Rotate colorcustom2colorInc SEGMENT.custom2 4TetrisAI_v2.cpp#L135让方块颜色每隔几步偏移旋转调色板位置取值 0~16数值越大色相漂移越快Mistake freecustom3失误间隔倒计时mistaceCountdown SEGMENT.custom3TetrisAI_v2.cpp#L235-L249仅在 Mistakes 复选框打开时生效每 N 步好棋AI 故意走一次最坏决策模仿人类失误4.2 复选框Checkboxes复选框作用源码依据Show next打开后在右侧留出 5 像素宽的下一块预览区每块占 5 行高否则整段宽度都用于棋盘布局计算见 TetrisAI_v2.cpp#L157-L177绘制见 TetrisAI_v2.cpp#L76-L109Show border打开后额外占用 1 像素列在棋盘与预览区之间画一条边框线同上effectWidth 1绘制循环用SEGCOLOR(2)Mistakes打开后按mistake free间隔周期性执行最差决策SEGMENT.check3分支TetrisAI_v2.cpp#L237值得注意的默认值出厂默认o11, o21Show next 与 Border 均开启、o30Mistakes 关闭。若段宽不足以容纳棋盘 5(预览) 1(边框)布局代码会自动把棋盘减宽gridWidth - ...TetrisAI_v2.cpp#L160-L17416x16 矩阵下正好是 10 列棋盘 5 预览 1 边框。4.3 游戏状态机整个游戏循环由TetrisAIGame::poll()驱动的状态机推进tetrisaigame.h#L63、L99-L143INIT → TEST_GAME_OVER → GET_NEXT_PIECE → FIND_BEST_MOVE → ANIMATE_MOVE → (循环) └──────────────────► ANIMATE_GAME_OVER → INITmode_2DTetrisAI()每个刷新周期按状态调用poll()动画类状态ANIMATE_MOVE / ANIMATE_GAME_OVER受msDelayMove节流而 GET_NEXT_PIECE / FIND_BEST_MOVE 等逻辑状态不受速度限制地立即推进——即AI 思考不占时间只有动画受 speed 控制。游戏结束判定为顶部 4 行隐藏区任一格被占tetrisaigame.h#L93-L97棋盘实际高度是height 4渲染从第 4 行开始ANIMATE_GAME_OVER 状态会逐格把棋盘像素置为特殊值 254用前景色重绘随后自动开新局。五、AI 与棋盘源码级实现剖析5.1 出块标准 7-bag 随机器tetrisbag.h 实现经典 7-bagbag数组预填0,1,2,...,6耗尽一次后shuffleBag()用 Fisher–Yates 洗牌queuePiece()维护一个长度等于nLookAhead的piecesQueue。队列头是当前落子块队列其余部分既是下一块预览区的数据源piecesQueue[nextPieceIdx]TetrisAI_v2.cpp#L91-L107也是 AI 前瞻搜索的输入——AI 预知的块与玩家看到的块完全一致。7 种块I/O/Z/S/L/J/T的形状以紧凑位图存储每个旋转用uint16_t rows4 行 × 4 位表示pieces.h#L39-L108colorIndex决定其在调色板中的分段位置。5.2 棋盘32 位行掩码的双棋盘设计棋盘由两套并行的数据结构组成GridBWgridbw.h每行一个uint32_t位掩码std::vectoruint32_t pixels因此宽度上限 32构造时超过 32 会被钳制gridbw.h#L41-L44。放置/擦除块用|/~整行位运算碰撞检测noCollision()只需按行一次isLineFull()比较行掩码是否全 1——这是 AI 能做深搜索的速度基础。GridColorgridcolor.h每格一个uint8_t颜色索引仅用于渲染消行/坍塌时与 GridBW 同步偏移。消行带一个闪烁缓冲cleanupFullLines()先只在clearingRows[]上标记满行而不删除效果层等750ms后才置clearedLinesReadyForRemoval true并真正移除TetrisAI_v2.cpp#L203-L215。闪烁期间满行像素按strip.now % 200 150在灰/黑间交替TetrisAI_v2.cpp#L42-L50——这就是光敏性癫痫警告的来源。用户mod 配置项noFlashOnClear true可让满行保持静态灰色配置通过addToConfig/readFromConfig持久化到 WLED 的 JSON 设置中TetrisAI_v2.cpp#L269-L281即 readme 提到的从 usermod 设置页关闭闪烁。5.3 启发式评分函数AI 的评估逻辑在 tetrisai.h。updateRating()tetrisai.h#L42-L108同样以列方向累积位掩码单次遍历同时算出各列高度含 aggregate 高度、最高列、最低列、满行数、空洞数当前行掩码与列累积掩码的 XOR 中 1 的个数countOnes是经典 popcount 位技巧、凹凸度相邻列高度差的绝对值之和tetrisai.h#L101-L105。最终打分tetrisai.h#L107score aHeight × aggregatedHeight fullLines × fullLines holes × holes bumpiness × bumpiness默认权重tetrisai.h#L110权重默认值含义aHeight-0.510066堆积总高度越高越差fullLines0.760666即将/已满的行越多越好holes-0.35663空洞越多越差bumpiness-0.184483表面越不平越差Rating结构体定义于 rating.h初值score -FLT_MAX以便更优者胜的比较语义。5.4 搜索与智能度/失误的实现findBestMove()tetrisai.h#L138-L204对候选块做递归枚举对piecesQueue中每一块穷举每种旋转 × 每一列落点落点由findLandingPosition()沿列下探求出放置→评分或递归搜索下一块→擦除。递归深度即 lookahead因此 16 列 × 预知 2 块时的候选规模大致是 O(落点数^3)位掩码棋盘保证了这在 ESP32 上可行。Intelligence 滑块通过均匀扰动四个权重来实现TetrisAI_v2.cpp#L194-L199float dui 0.2f - (0.2f * (intelligence / 255.0f)); ai.aHeight -0.510066f dui; ai.fullLines 0.760666f - dui; ai.holes -0.35663f dui; ai.bumpiness -0.184483f dui;intelligence 255 时dui 0权重保持最优组合调低滑块后正负项相互抵消的幅度增大评分的区分度下降AI 决策质量随之降低。Mistakes 复选框 Mistake free 滑块则直接反转比较方向倒计时归零的那一步把ai.findWorstMove true此时搜索保留得分最低的落法tetrisai.h#L178-L192随即还原并重置倒计时为custom3——从而呈现大多数时候很强、偶尔犯一个低级错误的人类感。5.5 布局与居中段重建速度、尺寸、复选框变化时触发时效果会重算占用区域棋盘宽min(cols, 32)、高min(rows, 255)Show next 追加 5 列、Show border 追加 1 列然后segOffsetX/Y (cols/rows - effectW/H) / 2实现整块居中TetrisAI_v2.cpp#L144-L189。六、限制与最佳观赏效果硬限制与 readme.md Limits 一节一致并得到源码印证棋盘最大宽度 32受GridBW每行uint32_t位掩码限制gridbw.h#L27棋盘最大高度 255受行索引uint8_t限制TetrisAI_v2.cpp#L150-L151;段尺寸超过上限时整个效果画布会在段内居中显示而不是拉伸。最佳观赏建议原文档 Best results把速度调到略快于人类高手的实际操作速度Intelligence 拉满、Mistakes 关闭或 mistake free 设得很大——AI 以超人的稳定水平连续清行观感最炸场。反过来把 Intelligence 调低并启用 Mistakes可以看到 AI 堆积、出现空洞乃至 Game Over 熄灭动画的全过程适合演示AI 也会输。七、相关文件索引文件说明usermods/TetrisAI_v2/readme.md模块说明本文依据的原始文档usermods/TetrisAI_v2/TetrisAI_v2.cppWLED 效果入口、渲染、参数映射、usermod 配置usermods/TetrisAI_v2/tetrisaigame.h游戏主循环状态机、game over 判定usermods/TetrisAI_v2/tetrisai.h启发式评分与最优/最差走法搜索usermods/TetrisAI_v2/gridbw.h位掩码棋盘碰撞、落点、消行闪烁缓冲usermods/TetrisAI_v2/gridcolor.h8 位色索引渲染棋盘usermods/TetrisAI_v2/tetrisbag.h7-bag 随机出块与下一块队列usermods/TetrisAI_v2/pieces.h7 种块形状位图与旋转数据usermods/TetrisAI_v2/rating.h评分结构体usermods/TetrisAI_v2/library.json库名与 libArchive 设置tools/WLED_ESP32_4MB_256KB_FS.csvFlash 不足时推荐的大代码区分区表pio-scripts/load_usermods.pycustom_usermods 的解析与目录匹配逻辑适用前提再强调一次需要 0.14 版本、具备 2D 段matrix的硬件布局如 16x16 矩阵以及编译侧在platformio_override.ini中登记tetrisai_v2。该模块属于 WLED 社区 usermod作者 muebau随主仓库分发但由上游用户自行维护升级 WLED 大版本后建议核对效果元数据与 usermod API 的兼容性。【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价