如果要在一块电路板上用最原始的电子元件实现一个完整的博弈程序, Tic-Tac-Toe(三连棋)是一个绝佳的起点。这个看似简单的 3×3 棋盘游戏,其状态空间足以考验硬件设计能力,却又足够小到可以用纯组合逻辑实现完美博弈。本文要分析的项目「Fets & Crosses」正是这样一个工程壮举:它使用 2458 个分立晶体管构建了完整的 Tic-Tac-Toe 系统,包含双人对战模式和单人挑战电脑模式。
系统架构与状态机设计
整个系统的核心是一组有限状态机(FSM),用于追踪棋盘上的每个格子的状态以及当前活跃的玩家。设计者采用了 19 个触发器(Flip-Flop)来存储系统状态:其中 18 个用于表示棋盘的 9 个格子(每个格子需要两个位来表示空、X、O 三种状态),另外 1 个用于追踪当前应该是哪一方落子。这个数字在工程上相当紧凑,因为理论上 9 个格子只需要 9 个二进制位就能表示所有可能的棋盘状态,但使用两个位可以更方便地实现游戏逻辑的编码与验证。
整个硬件被划分为两块 PCB:主电路板负责用户界面、电源管理、555 定时器时钟以及除了博弈引擎之外的所有逻辑;引擎板则专门实现与玩家对战的 AI 决策电路。两块电路板均采用双层 PCB 布线,遵循曼哈顿式布线风格(Manhattan wiring),即顶层用于垂直走线和晶体管封装布局,底层用于水平走线。这种布线方式虽然牺牲了一定的布线效率,但大大简化了手动布线的复杂度。
从 ROM 查找表到纯组合逻辑
项目的博弈引擎经历了两次重大迭代。最初的实现采用了并行输入输出的 ROM 作为大型查找表:当前棋盘状态被编码为 18 位地址输入,引擎的应手直接从存储器读取。这种方法虽然简单直接,但效率极低 —— 因为在 2^18(262144)个可能的输入中,只有不到 5% 对应实际有效的游戏状态。换句话说,超过 95% 的存储空间被浪费在无效的地址上。
设计者随后用纯组合逻辑门替换了 ROM 方案,实现了完全基于硬件的完美博弈引擎。这个新的实现不再需要任何存储器,而是通过硬编码的决策门(Decision Gate)来根据当前棋盘状态直接产生最优落子。这种方法的优点是响应速度快、无需等待存储器访问,但代价是需要精心设计大量的逻辑门电路。
决策门电路的层级设计
实现 Tic-Tac-Toe 完美博弈的核心在于如何将博弈策略转化为硬件逻辑。设计者采用了一种巧妙的「决策门级联」方案:64 个决策门按照固定的优先级顺序排列,每个决策门负责检测一种特定的棋盘局面,并在满足条件时产生对应的落子信号。当某个决策门激活时,它会输出一个阻塞信号(Block)传递给后续的决策门,从而确保只会产生唯一一个落子决策。
具体而言,这 64 个决策门按照以下优先级顺序排列:首先检测是否可以立即获胜(行、列、对角线共 24 种获胜方式);然后检测对手是否即将获胜并需要进行阻挡(同样 24 种方式);接着防止对手形成双路威胁(fork)—— 这是 Tic-Tac-Toe 中唯一能让对手有机可乘的情况,需要 3 个专门的决策门;之后按照策略优先级依次是:占据中心(1 个门)、占据对角角落(4 个门)、占据角落(4 个门)、占据边路(4 个门)。
值得注意的是,这 64 个决策门的具体实现使用了 CMOS 逻辑。设计者选择通过 NAND 和 NOR 门来构建更复杂的逻辑功能,因为在 CMOS 工艺中,构建反相逻辑所需的晶体管数量更少。每个决策门的输入信号都是经过取反的(低电平表示条件为真),这进一步减少了晶体管的使用量。最终,这 64 个决策门加上必要的状态取反和输出合并逻辑,总共使用了 1074 个晶体管,实现了完全组合逻辑的完美博弈引擎。
硬件实现的工程细节
从设计流程来看,这个项目的工作流程与真正的集成电路设计有几分相似之处。设计者首先在 KiCad 中创建了基本逻辑单元的原理图符号库,包括 NOT 门、NAND 门、NOR 门、AND 门、OR 门等。每个单元被放在独立的多层次原理图页面中,便于重复使用。构建更复杂的门电路时,直接调用这些基本单元进行组合 —— 例如,一个 2 输入的 AND 门实际上是由一个 NAND 门和一个 NOT 门级联而成。
布线阶段使用了 KiCad 的布局复制插件,将每个基本单元的布线应用到该类型的所有实例上。最终的手工组装经历了三个版本迭代才成功运行。设计者甚至专门制作了一个真空拾取放置笔(Vacuum Pick and Place Pen)来加速贴片过程,因为所有晶体管在电路板上共享相同的方向,这种半自动化工具大大提高了组装效率。
测试与验证
设计者实现了一个基于 STM32 的小型测试平台,将博弈引擎连接到 PC 端,并编写了一个 Python 脚本与引擎对弈所有可能的 Tic-Tac-Toe 局面。由于 Tic-Tac-Toe 的状态空间相对有限(只有 255168 种可能的游戏局面,其中大量是对称的),这种穷举式验证可以完全确认引擎在任何情况下都不会输棋。
工程参数与实践要点
如果读者希望尝试类似的全硬件博弈系统设计,以下参数和阈值值得关注:触发器数量应至少覆盖游戏状态编码与玩家轮换信息,该设计使用 19 个触发器;决策门数量取决于博弈复杂度,Tic-Tac-Toe 需要 64 个决策门实现完美博弈;晶体管预算方面,组合逻辑引擎占用约 1074 个 MOSFET,整个系统总计 2458 个;对于 CMOS 逻辑,优先使用 NAND/NOR 门而非 AND/OR 门可减少晶体管数量;布线策略上,双层 PCB 可采用曼哈顿式分层走线来简化布局;测试阶段建议编写自动化脚本穷举验证所有可能局面。
这个项目的真正价值在于它展示了如何将一个软件层面的博弈算法完整地转化为硬件电路:通过硬编码的决策门级联,实现了原本需要程序循环和条件判断才能完成的博弈逻辑。这种「用电路换代码」的思路,正是硬件加速的本质 —— 用空间(晶体管数量)换取时间(计算延迟),用并行硬件换取串行性能。
资料来源
- Fets & Crosses 项目主页:https://schilk.co/projects/fetsncrosses/
- GitHub 仓库:https://github.com/schilkp/Fets_and_Crosses