用 minimax 算法构建带 AI 玩家的 Python 井字棋游戏引擎
示例工程教程【免费下载链接】materialsBonus materials, exercises, and example projects for our Python tutorials项目地址https://gitcode.com/gh_mirrors/ma/materials点击查看免费下载本文是井字棋Tic-Tac-ToeAI 项目实战指南。它以可复用的游戏引擎库为骨架把棋局逻辑与前端表现彻底解耦并提供了终端、桌面 GUITkinter与浏览器PyScript三套可直接运行的前端其中电脑玩家基于 minimax 算法实现不可战胜。读完本文你将掌握从零搭建井字棋引擎库、实现 minimax 与 alpha-beta 剪枝、预计算棋局评分表以及通过python -m方式启动不同前端、自由搭配人类/随机/minimax 玩家的完整实战方案。该项目的完整源码位于 tic-tac-toe-ai-python 目录包含source_code_bonus完整版含三个前端与source_code_final、source_code_step_1~3分步版本等快照便于对照学习演进过程。项目整体构成一个引擎库三种前端README 明确指出本项目由两大部分组成游戏引擎库Game Engine Library封装全部棋局逻辑可被多个前端复用而无需重复编写游戏前端Game Front Ends分别实现于独立的包中负责界面与交互。这种引擎库 多前端的架构使你可以轻松为同一套规则逻辑挂接任意交互载体。在完整版源码中引擎库位于 source_code_bonus/tic-tac-toe/library三个前端则位于 source_code_bonus/tic-tac-toe/frontends 下的console、window、browser三个子包中。游戏引擎库安装与打包创建虚拟环境并安装引擎库在运行任何前端之前需要先把引擎库安装进虚拟环境源码命令$ cd tic-tac-toe/ $ python -m venv venv/ $ source venv/bin/activate (venv) $ python -m pip install library/其中library/即引擎库目录其构建配置见 source_code_bonus/tic-tac-toe/library/pyproject.toml包名为tic-tac-toe、版本1.0.0、requires-python 3.10且不依赖任何第三方库dependencies []是地道的纯 Python 实现。安装成功后即可运行本项目提供的各个前端。打包成 wheel 供浏览器前端使用浏览器前端不通过虚拟环境加载引擎库而是依赖一个可分发的 Python wheel 文件。因此需要先构建并打包库$ cd tic-tac-toe/ $ python -m pip wheel library/ $ mv tic_tac_toe-1.0.0-py3-none-any.whl frontends/browser/README 特别注明这些命令不需要虚拟环境即可工作但在虚拟环境中执行也完全没问题。生成并移动后的 wheeltic_tac_toe-1.0.0-py3-none-any.whl正是浏览器前端通过 PyScript 动态加载的对象在 source_code_bonus/tic-tac-toe/frontends/browser/ 中可以看到该文件已就位。引擎库内部结构logic 层与 game 层从源码结构看引擎库按纯逻辑与游戏运行分成了两个子包边界清晰library/src/tic_tac_toe/ ├── logic/ # 纯棋局逻辑与界面完全无关 │ ├── models.py # Mark、Grid、Move、GameState 数据模型 │ ├── minimax.py # minimax 算法与评分表序列化 │ ├── validators.py │ └── exceptions.py └── game/ # 游戏运行层串联玩家与渲染器 ├── engine.py # TicTacToe 同步引擎 ├── engine_async.py # AsyncTicTacToe 异步引擎浏览器前端使用 ├── players.py # 玩家抽象与实现 ├── players_async.py # 异步玩家实现 └── renderers.py # 渲染器抽象基类数据模型用 9 字符字符串表示棋盘在 logic/models.py 中整个棋局被建模为三类不可变数据类Mark继承自str的枚举只有CROSS X与NAUGHT O两种子并通过other属性快速取对方的棋子Grid棋盘本体内部就是 9 个字符的字符串 * 9表示空盘X/O/空格分别代表两方棋子与空位x_count、o_count、empty_count由cached_property缓存GameState一局棋的完整状态棋盘 先手方通过属性推算出current_mark轮到谁走、game_over、tie、winner、winning_cells以及possible_moves所有合法走法列表。胜负判定非常巧妙代码里预定义了 8 个WINNING_PATTERNS3 行 3 列 2 条对角线用?通配位置再用正则pattern.replace(?, mark)去匹配当前棋盘字符串命中的子即胜者。possible_moves则用re.finditer(r\s, ...)扫描空位并为每个空位调用make_move_to(index)生成一手Move。校验器保证棋局状态永远合法logic/validators.py 在每次构造Grid与GameState时自动执行校验validate_grid棋盘必须恰好由 9 个X/O/空格组成validate_number_of_marks两方棋子数之差不能超过 1validate_starting_mark根据先手方与当前棋子数判断先手是否合理validate_winner结合先手方检查胜者对应的落子数关系validate_players两个玩家不能使用同一种棋子。这些校验保证了引擎在任意状态下都不会进入矛盾局面也是GameState.__post_init__自动触发的第一道防线。minimax 算法不可战胜的 AI 核心AI 的灵魂在 logic/minimax.py 中共提供了三档实现性能与复杂度逐级优化。评分规则GameState.evaluate_score(mark)见 models.py#L135定义了游戏终局评分平局返回0指定棋子获胜返回1指定棋子落败返回-1。标准 minimaxV1核心函数minimax()对每一步的后续局面递归求值max 层当前方取子局面评分最大值min 层对手方取最小值def minimax(move, maximizer, choose_highest_scoreFalse) - int: if move.after_state.game_over: return move.after_state.evaluate_score(maximizer) return (max if choose_highest_score else min)( minimax(next_move, maximizer, not choose_highest_score) for next_move in move.after_state.possible_moves )对外入口find_best_move(game_state)以当前玩家为maximizer对possible_moves按 minimax 评分取最大者。alpha-beta 剪枝优化V2/V3find_best_move_optimized()实现了 alpha-beta 剪枝在递归中维护alpha当前 max 层已获得的下界与beta当前 min 层已获得的上界一旦beta alpha立即剪掉剩余分支大幅减少探索节点。源码中用-2/2作为评分界合法评分只有-1/0/1保证剪枝不会误伤。V3 版本进一步做了一手开局优化当game_not_started空盘时先随机走一步以引入对局多样性。预计算评分表V4默认方案MinimaxSerializer 把以 X 先手和以 O 先手两种初始状态下、所有可达走法的评分一次性遍历计算出来序列化为minimax.json见 logic/minimax.json采用cache惰性加载。find_best_move_precomputed()直接查表即可在常数时间内返回最优走法——运行期零递归开销。关键结论在 game/players.py 中MinimaxComputerPlayer MinimaxComputerPlayerV4即项目默认的 AI 玩家用的正是预计算评分表方案。玩家抽象体系game/players.py 定义了清晰的三层抽象Player持有棋子标记make_move()负责校验是否轮到本方实际走法交给抽象方法get_move()ComputerPlayer在取走法前先time.sleep(delay_seconds)默认 0.25 秒制造自然的思考停顿再调用抽象方法get_computer_move()具体实现RandomComputerPlayer随机落子、MinimaxComputerPlayerV1~V4对应三档 minimax 方案。游戏引擎主循环game/engine.py 的TicTacToe.play()是同步引擎的主循环创建空盘GameState渲染当前状态若未结束则让当前玩家走一步捕获InvalidMove交给可选的error_handler如此往复直到game_over。构造引擎时还会校验两个玩家棋子不同。异步版 game/engine_async.py 的AsyncTicTacToe结构与同步版一致只是把player.make_move()换成await player.make_move()专供浏览器前端使用。三个前端从终端到 GUI 再到浏览器在 frontends 下运行任一前端前请先完成前面安装与打包的步骤然后切换到前端父目录$ cd tic-tac-toe/frontends/终端前端console终端前端最灵活可通过命令行参数自由搭配玩家(venv) $ python -m console参数说明见 frontends/console/args.py参数可选值默认值含义-Xhuman/random/minimaxhuman执 X 的玩家-Ohuman/random/minimaxminimax执 O 的玩家--startingX/OX先手方例如让 X 用 minimax、O 用随机策略且 O 先走(venv) $ python -m console -X minimax -O random --starting O从 args.py 可以看到当--starting O时内部会把两个玩家对象对调以符合引擎player1 先手的约定。人类玩家的落子格式是坐标制A1或1A均可字母表示列 A~C数字表示行 1~3。frontends/console/players.py 中的grid_to_index()负责把坐标转换为 0~8 的格子索引并会给出Please provide coordinates in the form of A1 or 1AThat cell is already occupied.等友好提示。frontends/console/renderers.py 的渲染器每次开局前清屏绘制带行列表头的 ASCII 棋盘获胜时用 ANSI 闪烁效果高亮胜利连线并打印X wins 或平局提示No one wins this time 。桌面 GUI 前端window用 Tkinter 构建的桌面窗口应用默认配置是人类玩家X对战 minimax 电脑O(venv) $ python -m window玩家组合目前是硬编码的。要更换玩家需要编辑 frontends/window/cli.py 中game_loop的片段def game_loop(window: Window, events: Queue) - None: player1 WindowPlayer(Mark(X), events) player2 MinimaxComputerPlayer(Mark(O)) starting_mark Mark(X) TicTacToe(player1, player2, WindowRenderer(window)).play(starting_mark)实现要点Window见 frontends/window/renderers.py用 3×3 的ttk.Button铺成棋盘点击事件把格子索引写入QueueWindowPlayer见 frontends/window/players.py通过events.get()阻塞等待点击从而把 Tkinter 事件循环与引擎的同步主循环衔接起来——main()中引擎被放到一个守护线程里运行窗口本身则由window.mainloop()驱动。获胜时窗口标题变为X wins 胜利连线上的按钮会加粗显示。浏览器前端browser基于 PyScript 的浏览器前端无需虚拟环境、无需安装引擎库——它从打包好的 wheel 文件动态加载引擎$ python -m browser该命令会启动一个本地 HTTP 服务器并在浏览器中打开页面。frontends/browser/index.html 中通过py-env声明依赖py-env - tic_tac_toe-1.0.0-py3-none-any.whl - paths: - players.py - renderers.py /py-env页面顶部提供了 X/O 的玩家下拉框Human / Random / Minimax棋盘由内联 SVG 绘制。frontends/browser/script.py 把点击事件放入asyncio.Queue由BrowserPlayer消费见 frontends/browser/players.py再交给异步引擎AsyncTicTacToe与异步 minimax 玩家AsyncMinimaxComputerPlayer同样使用预计算评分表方案驱动整局游戏结束时显示Replay?按钮可立即重开。目录速览与分步学习想要循序渐进地理解项目可以对照源码快照阅读source_code_step_1搭建包结构、数据模型与校验器source_code_step_2加入引擎、玩家抽象与渲染器基类source_code_step_3实现终端前端完整交互source_code_final教程正文的最终版本source_code_bonus扩展版额外包含 window、browser 两个前端、异步引擎以及 wheel 文件。小结通过本项目的源码与文档可以看到一个教科书级别的分层设计logic层把棋盘、规则、minimax 算法做成与界面无关的纯 Python 库game层用玩家 渲染器 引擎的组合把交互抽象出来而console、window、browser三个前端则分别演示了同步命令行、事件驱动 GUI 与浏览器异步运行三种承载方式。默认 AI 采用预计算评分表V4配合 minimax 的完整递归、alpha-beta 剪枝与开局随机化等变体完整覆盖了从理论到工程落地的整条路径。赞分享示例工程教程【免费下载链接】materialsBonus materials, exercises, and example projects for our Python tutorials项目地址https://gitcode.com/gh_mirrors/ma/materials点击查看免费下载相关推荐Python Minimax 实战在尼姆游戏中构建 AI 对弈引擎python-minimax-nim 详解Python Minimax 实战在尼姆游戏中构建 AI 对弈引擎python minimax nim 详解 导读 python minimax nim示例工程教程Minimax 算法原理与 Alpha-Beta 剪枝实战解析 cosmos 仓库的 Python 井字棋实现Minimax 算法原理与 Alpha Beta 剪枝实战解析 cosmos 仓库的 Python 井字棋实现 Minimax极小化极大是决策论与博弈论中教程示例工程TheAlgorithms/C游戏算法实现井字棋与海战游戏开发终极指南TheAlgorithms/C游戏算法实现井字棋与海战游戏开发终极指南 想要学习如何用C语言实现经典游戏算法吗TheAlgorithms/C项目提供了完美的示例工程上一篇5 大最常用部署策略详解Big Bang、Rolling、Blue-Green、Canary 与 Feature Togglesystem-design-101 实战指南下一篇Frontend Slides 的 Coral 模板设计系统Bebas Neue Inter 双字体海报体系的完整设计规范与实现指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Python语音控制无人机:从麦克风到Tello EDU指令的完整实战

Python语音控制无人机:从麦克风到Tello EDU指令的完整实战

坦白讲,这个项目听起来挺唬人,但拆开以后就是四件事:让电脑听懂人话、把语义翻译成指令、把指令发到无人机、无人机照着执行。我用 Python 给 Tello EDU 做了一套完整的语音控制系统,不需要额外硬件,电脑自带麦克风就能…

2026/10/16 17:36:54 阅读更多 →
Kali Linux命令行完全上手指南:从基础配置到高效排错

Kali Linux命令行完全上手指南:从基础配置到高效排错

1. 从图形界面到纯终端:为什么我最终选择了Kali命令行最开始接触Kali Linux时,我其实跟大多数人一样,习惯性地打开图形界面,用鼠标点开终端模拟器,输入几个命令,然后再点回浏览器查资料。那时候觉得命令行只…

2026/10/16 17:36:54 阅读更多 →
二维码纠错机制与修复实战:从里德-所罗门码到图像预处理

二维码纠错机制与修复实战:从里德-所罗门码到图像预处理

1. 二维码纠错机制到底在纠什么错很多人第一次接触二维码纠错,是在生成工具里看到那个"容错率"下拉框——L、M、Q、H四个档位,旁边标注着7%、15%、25%、30%的恢复能力。大部分人随手选个M就完事了,直到某天遇到一张被磨损、被遮挡、…

2026/10/16 17:36:54 阅读更多 →

最新新闻

Surfer中文版从安装到出图:网格化插值与等值线图实战指南

Surfer中文版从安装到出图:网格化插值与等值线图实战指南

简介:sufer中文版是一款面向地质、环境、地球物理、水文地质等领域研究人员的地质建模与绘图工具,提供三维图绘制、等值线图生成、数据导入与处理、地图制作及报告输出等完整功能。该版本已完成汉化,并采用免安装便携设计,解压即可…

2026/10/16 18:14:57 阅读更多 →
Qwen3.8-27B-singprobe核心架构揭秘:[20, 41, 62]三层隐藏状态如何变成安全信号

Qwen3.8-27B-singprobe核心架构揭秘:[20, 41, 62]三层隐藏状态如何变成安全信号

【免费下载链接】Qwen3.8-27B-singprobe 项目地址: https://ai.gitcode.com/hf_mirrors/inclusionAI/Qwen3.8-27B-singprobe 点击查看 免费下载 Qwen3.8-27B-singprobe 是一个构建在 Qwen/Qwen3.8-27B 之上的流式安全探针(streaming guardrail&#xff…

2026/10/16 18:14:57 阅读更多 →
大模型落地必读:99个案例拆解RAG与Agent主流路线

大模型落地必读:99个案例拆解RAG与Agent主流路线

简介:这份PDF汇集了大模型在各行业中的典型示范应用案例,参编单位覆盖阿里云、百度、华为、腾讯、OPPO、蚂蚁、商汤、MiniMax等头部科技企业,以及高校、医院、金融机构、研究机构等,适合AI产品经理、算法工程师、企业数字化转型负…

2026/10/16 18:14:57 阅读更多 →
基于STM32F103的数字万用表设计与Proteus仿真实现

基于STM32F103的数字万用表设计与Proteus仿真实现

简介:基于Proteus仿真环境的STM32F103数字万用表完整工程,面向嵌入式系统学习者、电子设计爱好者及STM32入门开发者,可在虚拟环境中完成电路搭建、固件编写与功能验证。压缩包内共1020个文件,大小约14.29MB,汇集C/H源码…

2026/10/16 18:14:57 阅读更多 →
游戏运营核心指标解读:从DAU、留存率到LTV与ROI的实战指南

游戏运营核心指标解读:从DAU、留存率到LTV与ROI的实战指南

游戏运营这行,外人看着热闹,以为就是“发发礼包、写写公告”,真正干过的人才知道,这活儿一半是数据,一半是人性。新人入行,往往先被满屏的英文缩写砸晕——DAU、ARPU、LTV、K因子、留存、裂变……这些名词每…

2026/10/16 18:14:57 阅读更多 →
DeepSeek API调用避坑指南:Python环境、SDK版本与模型参数三重校准

DeepSeek API调用避坑指南:Python环境、SDK版本与模型参数三重校准

简介:本资源是一份面向Python开发者与AI应用工程师的DeepSeek API实战入门指南,聚焦从零开始调用大模型接口的核心流程,解决API注册、环境配置、代码集成、流式响应与多轮对话等关键问题。适用于需快速将DeepSeek语言能力嵌入聊天机器人、智能…

2026/10/16 18:13:56 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →