低级别系统设计实战:Tic Tac Toe(井字棋)游戏的设计与多语言实现
示例工程【免费下载链接】awesome-low-level-designLearn Low Level Design (LLD) and prepare for interviews using free resources.项目地址https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design点击查看免费下载导读本篇技术指南以awesome-low-level-design仓库中 problems/tic-tac-toe.md 为问题定义主体系统讲解如何为经典的 3x3 井字棋游戏做面向面试的低级别系统设计LLD。文中完整继承需求文档中的 7 条功能需求与 4 个核心类Player、Board、Game、TicTacToe并深入仓库中 C、Java 等多语言实现源码剖析回合流转、落子校验、胜负判定、平局检测等关键逻辑以及用 Strategy / State / Observer 模式、Minimax 算法扩展单机 AI 的工程化写法。读完本文你将掌握从需求分析到类设计再到多语言落地的一整套 LLD 答题范式可直接迁移到停车场、电梯、象棋等其他常见面试题。一、需求分析把一句话需求拆成可验收的规格原文档 problems/tic-tac-toe.md 给出了 7 条需求它们是整个设计的验收标准任何实现都不能偏离游戏在 3x3 网格上进行两名玩家轮流在网格上放置自己的符号X 或 O率先在横向、纵向或对角线上连成三个己方符号的玩家获胜网格全部填满且无人获胜时游戏以平局结束游戏应提供用户界面来展示网格并允许玩家落子游戏应管理玩家回合并校验落子是否合法游戏应在结束时检测并宣布胜者或平局。其中值得在面试中强调的两点需求 3 与需求 4 是互斥的终止条件要么出现胜者要么棋盘填满二者必居其一这是游戏主循环跳出game over的判定依据需求 6 里的“合法”包含两层校验坐标必须落在 3x3 网格范围内且该格子必须为空。仓库中 Board.cpp 的makeMove正是同时执行这两层校验后才落子。Java 版的问题陈述 solutions/java/src/tictactoe/README.md 将棋盘抽象为 NxN、并补充了“可扩展性易于修改棋盘尺寸或新增功能”这条需求这提示我们面试答题时应把需求归纳为「双人轮流落子」「胜负/平局检测」「输入校验」「可扩展」四个维度去组织类设计。二、UML 类图从需求到类的映射原文档给出的 UML 类图位于 class-diagrams/tictactoe-class-diagram.png其核心实体可以归纳为 4 个类职责划分如下类职责关键方法Player表示一名玩家持有名字与符号X/OgetName()、getSymbol()Board表示 3x3 棋盘提供落子、胜负检测、满盘检测makeMove()、checkWin()、isFull()、display()Game管理游戏流程与玩家交互回合流转、校验、判定结果play()、makeMove()、switchPlayer()、displayResult()TicTacToe应用入口创建玩家与游戏实例并启动main()这个划分遵循典型的“数据Board 状态Game 实体Player 入口TicTacToe”分层Board 只管网格数据与棋盘规则不关心谁在下棋Game 负责编排流程入口类负责组装。面试时按“谁持有数据、谁驱动流程、谁组织启动”三步即可快速确定类边界。三、核心类的职责与接口设计3.1 Player最小化的玩家实体Player 只需三个字段name、symbolX 或 O、以及标识是否人类玩家的isHuman为 AI 扩展预留。仓库 C 实现 Player.hpp 与 Player.cpp 通过构造函数默认参数bool isHuman true提供了单机模式所需的扩展点——把isHuman设为false即得到一个由电脑控制的玩家。3.2 Board网格数据与棋盘规则Board 在 Board.hpp 中声明的接口完整覆盖了需求中“落子、校验、判胜、满盘”四大能力isValidPosition(row, col)判断坐标是否在[0, size)范围内isEmpty(row, col)判断格子是否为空空位用-字符表示makeMove(row, col, symbol)先校验再落子失败返回falseisFull()遍历全盘存在空格即返回falsecheckWin(symbol)委托给checkRows / checkColumns / checkDiagonals三个私有方法display()以 3 列对齐方式打印当前棋盘即需求 5 中的“用户界面”控制台版reset()重置网格便于复用棋盘实例。3.3 Game流程编排者Game 在 Game.hpp 中维护board、两个玩家指针、currentPlayer与gameOver标志。核心循环play()的逻辑为展示棋盘 → 若是人类玩家则读入 row/col 并调用makeMove若是电脑玩家则调用computerMove→ 循环直到gameOver→ 调用displayResult()宣布胜者或平局。四、胜负判定与平局检测checkWin 的实现细节Board 的胜负判定拆成三个方向分别检查见 Board.cpp行检查checkRows对每一行遍历所有列若整行都是某符号则胜列检查checkColumns对每一列遍历所有行逻辑同构于行检查对角线检查checkDiagonals主对角线grid[i][i]副对角线grid[i][size-1-i]。checkWin用checkRows(symbol) || checkColumns(symbol) || checkDiagonals(symbol)组合三者。值得注意的工程细节是仓库实现把循环写成通用size维度而非硬编码 3这直接呼应了 Java 版 README 中“支持任意 NxN 棋盘”的可扩展性需求。平局检测在 Game.cpp落子合法后先查board.checkWin(currentPlayer-getSymbol())若胜则gameOver true否则再查board.isFull()若满盘则将currentPlayer置空——这一技巧让displayResult()只需判断currentPlayer是否为nullptr即可区分“某人获胜”与“平局”两种终局void Game::displayResult() const { board.display(); if (currentPlayer) { std::cout currentPlayer-getName() wins! std::endl; } else { std::cout Its a draw! std::endl; } }这种用「状态语义复用」代替「额外布尔标志」的做法是 LLD 面试中的加分点。五、回合流转与落子校验Game 的 makeMove 主链路回合管理依赖currentPlayer指针的交替void Game::switchPlayer() { currentPlayer (currentPlayer player1) ? player2 : player1; }makeMove的主链路Game.cpp是理解全流程的关键board.isValidPosition(row, col)不通过 → 打印 Invalid position! 并直接返回不切换回合board.isEmpty(row, col)不通过 → 打印 Position already taken! 并返回不切换回合board.makeMove落子checkWin成立 → 结束isFull成立 → 结束平局否则switchPlayer()轮到下一位。注意第 1、2 步失败时都不切换玩家这保证了“非法落子不消耗回合”的规则正确性与需求 6 “校验落子确保合法”严格一致。六、从 3x3 到 NxN尺寸无关的通用化设计原需求只要求 3x3但仓库两种实现都做了通用化处理C 版Board构造函数带默认参数Board(int size 3)见 Board.hpp所有判定循环都以size为界Java 版Game.java 在构造时new Board(3)显式指定尺寸而 solutions/java/src/tictactoe/README.md 将“支持不同棋盘尺寸”列为扩展方向。这意味着若面试官追问“棋盘改为 4x4、5x5 怎么办”上述实现只需把落子判定从“三连”推广为“size连”即可类结构无需任何改动——这正是“把维度参数化”设计带来的扩展收益。七、工程化扩展设计模式与 AI 对弈原文档只给出 4 个基础类仓库实现则在基础骨架之上展示了更强的工程化扩展可作为面试时的进阶谈资。7.1 Java 版Strategy State Observer 三模式组合Java 实现 solutions/java/src/tictactoe/ 采用了三层设计模式Strategy 模式把“行胜/列胜/对角胜”拆成三个独立的WinningStrategy实现strategy/RowWinningStrategy.java、strategy/ColumnWinningStrategy.java、strategy/DiagonalWinningStrategy.javaGame持有策略列表checkWinner遍历调用见 Game.java。新增“四连”“斜向更长连法”只需加策略类符合开闭原则State 模式把游戏生命周期建模为InProgressState、WinnerState、DrawState三个状态state/Game.makeMove委托给当前状态的handleMove终局判定被状态机化Observer 模式Game继承GameSubject当状态变为非 IN_PROGRESS 时通知Scoreboard等观察者Game.java为后续接 UI、记分板等外部系统提供了松耦合出口。7.2 C 版Minimax 算法驱动的电脑玩家C 实现把需求“双人”扩展为“人机对战”Game::initializePlayers(Human, Computer)中第二个玩家以isHumanfalse创建TicTacToeDemo.cpp。其 AI 核心是经典的Minimax 极大极小搜索Game.cpp评分规则电脑胜得10 - depth人类胜得depth - 10满盘平局为 0depth越小越优先追求速胜、避免拖局isMax层取最大值电脑视角isMin层取最小值人类视角搜索通过拷贝棋盘Board tempBoard board进行假设性落子不污染真实棋盘findBestMove()遍历每个空位模拟落子后用minimax求分取最高分位置落子Game.cpp。对 3x3 棋盘Minimax 全搜索即可保证电脑不输最佳应对是面试中“如何让机器不犯错”的标准答案。可以顺便指出更大的棋盘如 5x5需要 Alpha-Beta 剪枝或蒙特卡洛方法这能体现你对算法复杂度的意识。八、多语言实现导航与运行方式该题在仓库中提供了 5 种语言的完整实现可直接对照阅读同一份设计的差异化落地语言位置入口/说明Javasolutions/java/src/tictactoe/TicTacToeDemo.java演示Game/Board/Player/Cell分包组织README 含类设计与示例代码Csolutions/cpp/tictactoe/TicTacToeDemo.cpp为入口含人机对战与 Minimax AIC#solutions/csharp/tictactoe/与 C 同套类设计的 .NET 版本Gosolutions/golang/tictactoe/以 Go 结构体与接口组织的版本Pythonsolutions/python/tictactoe/Python 面向对象版本C 版可直接编译运行体验完整人机对战流程# 在解决方案目录下编译并运行需 C17 以支持结构化绑定 g -stdc17 TicTacToeDemo.cpp Board.cpp Game.cpp Player.cpp -o tictactoe ./tictactoe运行后程序会打印棋盘空位显示-提示人类玩家输入row与column取值 0~2电脑玩家则由 Minimax 自动落子最终输出胜者或Its a draw!。Java 版则参考其 README 中的示例用法Player p1 new Player(Alice, Symbol.X); Player p2 new Player(Bob, Symbol.O); Game game new Game(p1, p2); game.play();九、面试答题要点总结结合需求文档与仓库实现回答本题时的关键得分点归纳如下先定验收标准再画类图7 条需求逐条映射到类的哪个方法做到“需求可追踪”明确职责边界Board 管数据与规则Game 管流程Player 是纯实体入口类只做组装讲清两种终局checkWin 三方向判定 isFull 满盘平局注意“非法落子不换回合”的细节主动展示扩展性棋盘尺寸参数化NxN、Java 的 Strategy/State/Observer 组合、C 的 Minimax 人机对战都是把“能跑”升级为“好扩展”的证明多语言对照能指出 5 种语言的实现位置并对比其组织方式说明你不仅会设计还能工程化落地。这套“需求 → 类职责划分 → 核心算法 → 设计模式扩展 → 多语言落地”的流程可以直接套用到仓库中 problems/ 下的停车场、电梯、象棋、餐厅管理等同类 LLD 题目是面试准备的通用方法论。赞分享示例工程【免费下载链接】awesome-low-level-designLearn Low Level Design (LLD) and prepare for interviews using free resources.项目地址https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design点击查看免费下载相关推荐wewe-rss 私有化部署实战把微信公众号变成 RSS 订阅源的完整指南wewe rss 私有化部署实战把微信公众号变成 RSS 订阅源的完整指南 wewe rss 是一个可以私有化部署的微信公众号 RSS 生成服务。它借助微信读示例工程从零设计井字棋Tic Tac Toe基于 C 的状态机、策略与观察者模式实战剖析从零设计井字棋Tic Tac Toe基于 C 的状态机、策略与观察者模式实战剖析 井字棋Tic Tac Toe是低层设计LLD面试中最经典的入门题示例工程python-mini-projects 双人井字棋Tic Tac Toe命令行游戏运行方式与源码实现解析python mini projects 双人井字棋Tic Tac Toe命令行游戏运行方式与源码实现解析 本文以 python mini project示例工程上一篇终极指南如何在Mac上免费读写NTFS移动硬盘下一篇N_m3u8DL-RE 流媒体下载指南M3U8、DASH 与直播录制一次跑通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →