关于树莓派

注:这是本人最近玩树莓派的一些心得,本人算是第一此玩,我个人买的是树莓派zero w带WiFi的,可能没有那么专业,如有错误请请大佬指正。个人建议买一个HDMI mini转HDMI的转换器和usb转的扩展坞(最好是带网口的),方便插鼠标这些,虽然知道IP地址就可以访问,但是还是建议可以买一个。

1、关于我的理解

我个人认为他就是一个低功耗的小电脑。

缺点就是,他大部分是ARM架构的,本来是想买x86架构的,但是基本上没有,所以,我觉得想玩x86的就不用折腾树莓派了,虽然架构不算好,毕竟个人觉得x86架构的比ARM的使用体验会好的多,毕竟软件支持的要多一点,

优点首先他功耗真的很低,本人可以用它来执行一些小任务,而且稳定性很好,毕竟装的是Linux系统,然后扩展功能也很强,但是要求有一定的动手能力,本人只知道焊一点洞洞板,所以请人代工的,还加了针脚方便扩展,然后,我觉得他可以帮助我学习一些Linux指令,所以,对于想学习Linux系统的还是很推荐的,是个不错的入门方法,而且本身很便宜,买一些性能比较差的就行,毕竟一般不可能有树莓派连ssh都用不了的。

2、当你选好以后,就开始是刷系统了,个人推荐Raspberry pi os

下载树莓派烧录工具,选择好对应的就行

一步一步根据这些来,写入就行了,一般是TF卡吧,建议买一个读卡器。

3、基础设置

这是图形化界面,一般第一次玩,我建议全部默认设置。

然后进入桌面,我个人是在这个配置里的全部是打开的,一般开ssh和vnc应该就够了。

然后需要操控的电脑我建议安装

MobaXterm_Personal(用于ssh的GitHub上有汉化的)

realvnc(用于显示桌面图像的)

总结:大概就是这些吧,我个人也是第一次玩,所以感悟就这些,剩下的如docker什么的就自己配吧,本人这个性能很弱,跑docker基本就不要想了,所以,如果有多余的闲钱,可以上好一点的,但是,建议从性能比较弱的开始,便宜,就算坏了也不心疼,还可以试试焊接上其他的东西。

基于python的图书阅读器

项目地址:suyihang15/book_reader: 基于python的图书阅读器

下载链接:https://github.com/suyihang15/book_reader/releases/download/1.0.0/BookReader.exe

📚 BookReader — 图书管理与阅读器

一款用 Python + PyQt5 编写的桌面端图书管理与阅读器,支持多格式导入、分类管理、阅读进度追踪。本文将详细介绍该程序的设计原理、功能特性、使用方法及技术栈。

🧠 程序原理

整体架构

1
2
3
4
5
6
7
8
9
10
11
12
┌─────────────────────────────────────────────────────┐
│ MainWindow │
│ ┌──────────┬──────────────────────────────────────┐ │
│ │ Category │ QStackedWidget │ │
│ │ Sidebar │ ┌─────────────┬──────────────────┐ │ │
│ │ │ │ Library │ Reader │ │ │
│ │ 分类筛选 │ │ Widget │ Widget │ │ │
│ │ │ │ (书架视图) │ (阅读器) │ │ │
│ └──────────┘ └─────────────┴──────────────────┘ │ │
│ ↑ 信号驱动切换 │ │
└─────────────────────────────────────────────────────┘

三层数据流

1
2
3
4
5
6
7
8
9
10
11
[用户操作]        [UI 层]          [数据层]         [存储层]
│ │ │ │
导入图书 ──→ ImportDialog ──→ parsers.py ──→ SQLite DB
│ │ (解析元数据) (library.db)
│ │ │
点击分类 ──→ CategorySidebar ──→ database.py ──→ SQLite DB
│ (发信号) (get_books_by_category)
│ │ │
阅读图书 ──→ ReaderWidget ──→ parsers.py ──→ 文件系统
│ (逐页渲染) (library/)

设计原则

原则 体现
信号-槽解耦 组件间通过 PyQt5 信号通信,不直接调用彼此方法
数据与视图分离 database.py 只管数据 CRUD,UI 层只管展示
解析器策略模式 BaseParser 抽象基类,每种格式一个子类,通过工厂方法获取
线程分离 导入操作在 QThread 中执行,不阻塞主界面
增量迁移 数据库变更通过 ALTER TABLE 兼容已有数据,不丢记录

数据库模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──────────────────────┐       ┌──────────────────────┐
│ categories │ │ books │
├──────────────────────┤ ├──────────────────────┤
│ id (PK) │←──┐ │ id (PK) │
│ name (UNIQUE) │ └───│ category_id (FK) │
│ sort_order │ │ title │
└──────────────────────┘ │ author │
│ publisher │
│ description │
│ format │
│ file_path │
│ cover_path │
│ page_count │
│ current_page │
│ tags (JSON) │
│ date_added │
│ last_read │
└──────────────────────┘

✨ 功能特性

📥 图书导入

  • 支持 PDF / EPUB / MOBI / AZW3 / TXT / FB2 格式

  • 拖拽文件/文件夹到窗口即可批量导入

  • 自动解析元数据(书名、作者、出版社、ISBN)

  • 自动提取封面(PDF 首页、EPUB 内置封面、TXT 自动生成)

  • 基于文件 MD5 的重复检测,避免重复导入

  • 导入时可选择分类

📂 分类管理

  • 预设 8 个分类:小说、文学、科技、历史、哲学、艺术、教育、其他

  • 左侧栏按分类筛选图书,显示每类数量

  • 支持添加、重命名、删除自定义分类

  • 图书卡片显示分类标签

  • 编辑详情时可修改分类

📚 书架视图

  • 网格视图:卡片式封面展示,鼠标悬停放大效果

  • 列表视图:紧凑列表,适合大量图书浏览

  • 搜索:按书名/作者实时过滤

  • 排序:最近添加、书名 A-Z、作者 A-Z、最近阅读

📖 阅读器

  • PDF 高清渲染(150 DPI),逐页加载

  • EPUB/TXT HTML 文本渲染,自动分页

  • 三种主题:☀️ 日间 / 🌙 夜间 / 📜 护眼

  • 字体大小自由调节(A+/A- 按钮)

  • 键盘快捷键翻页(← → / A D)

  • 阅读进度自动保存,下次打开继续阅读

✏️ 元数据编辑

  • 编辑书名、作者、出版社、ISBN、描述

  • 自定义标签(逗号分隔)

  • 更换/重置封面图片

  • 修改所属分类

🚀 快速开始

环境要求

  • Python 3.8+

  • Windows / Linux / macOS

安装依赖

1
pip install -r requirements.txt

运行

1
python main.py

首次运行会自动创建 library.db 数据库和 library/ 目录结构。

🎮 操作指南

导入图书

方式 操作
按钮导入 点击工具栏「📥 导入图书」→ 选择文件
文件夹导入 菜单栏 文件 → 导入文件夹(Ctrl+Shift+I)
拖拽导入 将文件/文件夹直接拖入窗口

导入时可选择「导入到分类」,将图书直接归入指定分类。

浏览与管理

操作 方式
分类筛选 点击左侧栏分类名称
搜索图书 顶部搜索框输入书名或作者
排序切换 搜索框旁下拉菜单切换排序方式
视图切换 菜单栏 视图 → 网格视图 / 列表视图
编辑详情 右键图书卡片 → ✏️ 编辑详情
删除图书 右键图书卡片 → 🗑️ 删除
管理分类 左侧栏底部「⚙ 管理分类」按钮

阅读图书

操作 方式
打开阅读 点击图书封面 或 右键 → 📖 阅读
上一页 ← 键 / A 键 / 点击「◀ 上一页」
下一页 → 键 / D 键 / 点击「下一页 ▶」
跳转页码 导航栏输入页码或拖动滑块
首/末页 Home / End 键
字体放大 点击 A+ 按钮
字体缩小 点击 A- 按钮
切换主题 右上角下拉菜单(日间/夜间/护眼)
返回书架 Esc 键 / 点击「← 返回书架」

📂 项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
book_reader/
├── main.py # 程序入口
├── requirements.txt # Python 依赖清单
├── database.py # SQLite 数据库层(CRUD + 迁移)
├── parsers.py # 多格式解析器(策略模式)
├── utils.py # 工具函数(封面生成、文件哈希)
├── ui/
│ ├── __init__.py
│ ├── main_window.py # 主窗口(菜单、工具栏、状态栏)
│ ├── library_widget.py # 书架视图(网格/列表 + 图书卡片)
│ ├── reader_widget.py # 阅读器(PDF/EPUB/TXT 渲染)
│ ├── import_dialog.py # 导入对话框(多线程导入)
│ ├── detail_dialog.py # 详情编辑对话框
│ ├── category_sidebar.py # 分类侧边栏(分类筛选)
│ └── category_dialog.py # 分类管理对话框
├── library/ # 图书文件存储目录
│ └── .covers/ # 封面图片缓存
└── library.db # SQLite 数据库文件

各模块职责

模块 职责 依赖
database.py 数据库初始化、图书/分类 CRUD、增量迁移 SQLite3
parsers.py 解析各格式图书元数据与内容 PyMuPDF, ebooklib, BS4
utils.py 封面生成、哈希去重、格式判断 Pillow
main_window.py 窗口框架、菜单/工具栏、信号路由 PyQt5
library_widget.py 书架渲染、搜索/排序/分类筛选 PyQt5
reader_widget.py 阅读器渲染、主题/字体切换 PyQt5
import_dialog.py 导入 UI + 后台线程 PyQt5, parsers
detail_dialog.py 图书元数据编辑表单 PyQt5
category_sidebar.py 分类列表展示 + 筛选信号 PyQt5
category_dialog.py 分类增删改管理 PyQt5

🛠️ 技术栈

组件 技术 用途
GUI 框架 PyQt5 窗口、布局、信号槽
PDF 解析 PyMuPDF (fitz) PDF 元数据提取 + 页面渲染
EPUB 解析 ebooklib + BeautifulSoup4 EPUB 元数据 + HTML 内容提取
图像处理 Pillow 封面生成、缩放、格式转换
数据库 SQLite3 图书记录、分类、阅读进度
线程 QThread 导入不阻塞 UI

⚠️ 注意事项

  • 导入时会复制文件到 library/ 目录,原始文件不受影响

  • 删除图书会同时删除 library/ 中的副本和封面缓存

  • MOBI/AZW 格式仅基础元数据支持,建议转为 EPUB 后导入获得完整体验

  • 数据库文件 library.db 和 library/ 目录是核心数据,备份时请保留

  • 分类表中的默认分类可按需修改或删除

效果展示

总结:这是本人弄的一个图书阅读器,支持各种类型的图书文件,但是打包的是单文件,所以启动稍微有点慢,可以自行打包一下。

电脑安装claudecode并接入deepseek

注:本教程无需配置任何特殊网络环境,可绕开登录

1、环境准备

node.js

git

cc switch

deekseek申请API记得要有一定的额度。

2、检查环境并安装

node版本检查:node -v
npm版本检查:npm -v
npm国内镜像:npm config set registry https://registry.npmmirror.com/
git版本检查:git -v

关闭Windows安全策略:Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

ClaudeCode安装命令:npm install -g @anthropic-ai/claude-code
ClaudeCode版本检查:claude –version
启动ClaudeCode:claude

安装好以后配置.claude.json文件,要先在这里显示出隐藏的文件才能找到.claude.json文件用记事本打开。

打开以后,记得切换为英文模式,

上一个字段尾部加英文逗号后加入:”hasCompletedOnboarding”: true

记得写在}前面。

打开cc switch,添加deepseek模型,输入你上面申请的api的key后保存。

打开cmd输入claude启动他,再输入/model选择好配置的model就可以直接用了

效果展示

整体来说还是很不错的,当然你也可以配置其他的model,但是有的需要一些魔法环境,或者用ai中转站(当然个人不建议,因为ai中转站挂羊头卖狗肉的情况还是不少的,而且其本身是处于一个灰色产业),就在cc switch里配置就行,但是,我个人觉得deepseek v4是本人目前来说不用配置魔法环境,最好用的,但是,缺点个人用下来其图像识别能力是比较差的,写代码处理问题这些确实是不错的,很聪明。

总结:大致就这样,你后面还可以自行配置其他的如skills这些,还有注意key的消耗。

云电脑搭建

注:这是本人搭建的一个思路

1、准备条件

一台永不关机的电脑,性能不能太差,我这里是我自己的nas,可以装虚拟机

parsec(串流工具,用于远程连接)这是本人觉得不错的远程工具,就是没有汉化,但是多端都是可以使用的,手机也可以连接。

2、使用

在nas上部署一台虚拟机先安装好parsec

需要远程连接的设备上也下载好。

两边同时登录上同一个账户就可以连接上这台虚拟机了

效果

本人测试下来效果是不错的,偶尔会有点延迟,但是效果还是不错的,打小游戏都还可以,适合平板来玩。

3、搭建思路

这是本人之前想的,那些做云电脑的,一般来说不可能会有那么多钱去买那么多电脑来放到服务器上,所以思路就是,用一台性能不错的电脑通过开虚拟机的方式就可以一台电脑当几台电脑使用,只不过性能会有所损耗,而且达不到企业那样低延迟。

总结:虽然达效果达不到那么完美,但是我们也可以通过这种方式进行批量生成云电脑,而且建议可以用一些精简版的windows镜像文件,这样可以优化其网速,这是本人能想到最好的个人做云电脑的方案了。

Steam远程串流(steam Link)

注:其是本身steam自带的一种连接方式。

1、准备条件

电脑上安装steam

手机上下载Steam Link

2、使用

在steam里开启远程

手机上直接安装steam link在同一局域网里添加就行

这里直接开始运行,效果就是这样,但是要在同一局域网内。

如果想要在外面访问,就通过我前面博客写的那些,如异地组网等连接方式,之前已经说的很详细了不过多说。

总结:其效果还是不错的,还可以作为远程遥控电脑的一种手段,但是缺点也很明显,必须要提前开启steam。

基于python的井字棋游戏

项目地址:suyihang15/tic_tac_toe_gui: 基于python的井字棋游戏

下载地址:https://github.com/suyihang15/tic_tac_toe_gui/releases/download/1.0.0/tic_tac_toe_gui.exe

🎮 井字棋游戏 (Tic-Tac-Toe)

一个使用 Python 内置 tkinter 库开发的图形化井字棋游戏,支持双人模式人机对战模式,界面美观、交互流畅。


✨ 功能特性

特性 说明
👫 双人模式 (PvP) 两名玩家在同一台电脑上轮流落子
🤖 人机模式 (PvE) 与 AI 对战,AI 具备智能决策策略
🎨 深色主题 UI 美观的深色界面,X(蓝色)与 O(红色)颜色区分
🏆 获胜高亮 获胜连线自动变为金色,一目了然
🔄 模式随时切换 下拉菜单一键切换模式,自动重置棋盘
🖱️ 纯鼠标操作 点击即落子,无需键盘输入
📦 零依赖 完全基于 Python 内置库,无需安装任何第三方包

🚀 快速开始

环境要求

  • Python 3.6 或更高版本

  • 操作系统:Windows / macOS / Linux 均可

运行方法

1
2
3
4
5
# 进入项目目录
cd d:\zhuomian\游戏

# 运行游戏
python tic_tac_toe_gui.py

🎯 游戏规则

  1. 棋盘为 3×3 的九宫格,两名玩家轮流落子

  2. X 先手O 后手

  3. 点击空白格子即可落子

  4. 先将三个棋子连成一条直线(横、竖、斜)的玩家获胜

  5. 棋盘下满无人获胜则为平局

位置编号

1
2
3
4
5
 1 | 2 | 3 
---+---+---
4 | 5 | 6
---+---+---
7 | 8 | 9

💡 游戏中无需手动输入编号,只需点击对应格子即可。


🤖 AI 策略说明

AI 对手使用以下优先级策略来选择最佳落子位置:

优先级 策略 说明
🥇 直接获胜 如果 AI 下一步能赢,立即落子获胜
🥈 阻挡对手 如果对手下一步能赢,优先阻挡
🥉 占领中心 抢占棋盘正中央(5 号位)
4 选择角落 随机选择四个角位之一
5 选择边位 最后选择四条边上的位置

📁 项目结构

1
2
3
游戏/
├── tic_tac_toe_gui.py # 主程序文件(包含完整代码)
├── README.md # 项目说明文档(本文件)

🧩 代码架构

类设计:TicTacToeGUI

整个游戏封装在 TicTacToeGUI 类中,主要方法分类如下:

🏗️ GUI 构建方法

方法 功能
_create_widgets() 创建所有 GUI 组件
_create_title_bar() 创建标题栏
_create_mode_selector() 创建模式选择下拉菜单
_create_board() 创建 3×3 棋盘按钮
_create_status_bar() 创建状态信息栏
_create_control_buttons() 创建控制按钮(重新开始、退出)
_center_window() 将窗口居中于屏幕

🎮 事件处理方法

方法 功能
_on_mode_change(selection) 切换游戏模式
_on_button_click(index) 处理玩家点击棋盘
_make_move(index, symbol) 执行落子逻辑
_ai_turn() AI 回合自动落子

🧠 游戏逻辑方法

方法 功能
_check_winner(board) 检查是否有获胜者
_is_board_full(board) 检查棋盘是否已满
_get_available_positions(board) 获取所有空闲位置
_ai_move(board, symbol) AI 决策核心算法
_highlight_winner(winner) 高亮获胜连线
_update_status() 更新状态栏文字
_reset_game() 重置游戏到初始状态

🖼️ 界面预览

游戏界面包含以下区域:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌─────────────────────────────┐
│ 🎮 井字棋 │ ← 标题栏
├─────────────────────────────┤
│ 游戏模式:[双人模式 ▾] │ ← 模式选择
├─────────────────────────────┤
│ │
│ X │ │ O │
│ ───┼───┼─── │ ← 3×3 棋盘
│ │ X │ │
│ ───┼───┼─── │
│ O │ │ X │
│ │
├─────────────────────────────┤
│ 玩家 X 的回合 │ ← 状态栏
├─────────────────────────────┤
│ [🔄 重新开始] [🚪 退出] │ ← 控制按钮
└─────────────────────────────┘

💻 代码示例

核心胜负判定逻辑(仅需 8 行):

1
2
3
4
5
6
7
8
9
10
def _check_winner(self, board):
win_combinations = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], # 行
[0, 3, 6], [1, 4, 7], [2, 5, 8], # 列
[0, 4, 8], [2, 4, 6], # 对角线
]
for combo in win_combinations:
if board[combo[0]] == board[combo[1]] == board[combo[2]] != " ":
return board[combo[0]]
return None

🛠️ 自定义与扩展

你可以轻松修改以下内容:

  • 修改棋盘大小:调整 _create_board() 中的循环和 win_combinations

  • 更换主题颜色:修改 bgfg 等颜色值

  • 增强 AI:在 _ai_move() 中添加更复杂的策略(如 Minimax 算法)


📄 许可证

本项目仅供学习和娱乐使用,欢迎自由修改和分享。


✨ 小贴士:在双人模式下,两名玩家可以轮流使用同一台电脑进行对战;在人机模式下,你将与 AI 进行较量,看看你能连胜几局?

在线操作系统

注:这是本人发现的一些好玩的网页,可以直接当作一个网页版的操作系统。

一、Windows仿真系列

Windows 11 | https://win11.blueedge.me/
Windows 10 | https://siquan001.github.io/Win10online/windows/
Windows 7 | http://win7simu.visnalize.com/
Windows XP | https://quenq.com/apps/reborn-xp[/](https://quenq.com/apps/reborn-xp/)
Windows 98 | https://98.js.org/
Windows 93(趣味魔改)| http://www.windows93.net/
远古Windows合集(1.0/3.1/95)| https://www.pcjs.org/

二、macOS复古仿真系列

新版macOS仿真 | https://macos-web.app/
Mac System 7 | https://system7.app/
Mac OS 8 | https://macos8.app/
Mac OS 9 | https://macos9.app/

三、Linux在线系统
JS原生Linux虚拟机(命令行)| https://bellard.org/jslinux/
云端Linux图形桌面 | https://www.onworks.net/

四、多系统一键切换合集站

多系统合集(Win/mac/Linux)| https://webos.js.org

个人建议可以直接用这个整合的,里面整合了各家的,但是其本质主要是为了让你体验各家的操作系统,并不具备完整的功能,只是进行一些简单的交互功能,对于真正的体验还是要上手体验实机。

总结:我不希望这些在我们历史上的操作系统消失,我希望有人还能记着这些,本人用的第一款操作系统是windows xp所以我会永远记得那个打游戏的日子。

局域网传输文件工具(localsend)

注:本产品主要针对于那些在同一局域网下,对文件传输有需求的人,支持多端传输

项目地址:localsend/localsend:AirDrop 的开源跨平台替代方案

软件下载

打开项目地址,打开releases

下载对应你需要的客户端版本。这里一般电脑都是x86的.exe文件,手机上安装arm架构的apk,一般都是这样的

电脑端

手机端

大致就是这个样子,只需要手机和电脑下载好这个软件,然后,在同一局域网里就可以连接并传输文件了,整体来说是很简洁美观的。

总结:这就是本人推荐的一个局域网传输工具,对于想要用这个软件进行异地传输文件的,可以试试我前面博客写的关于异地组网的,可以研究一下,看看,就能实现异地传输,但效果肯定没有内网快。

对于ai

注:本人最近一直在玩ai,主要想说说自己的感受。

我个人是不反对ai的,因为ai确实带给了我很多东西,可以说我学习编程基本上就是靠ai一步一步学着来的,所以我觉得ai是使人进步的,科技本身是不断发展的,我们应该跟上时代,不断地学习才是我们应该做的。

最近也快高考了,我自己是2023年参加高考的,说实话,考的不算好,也没有那么差,虽然只是个二本,但是,我觉得没有什么不好的,起码我还在学习,并没有失败,我觉得这就是大学的意义,不会过多的去约束你,但基本的是要学的,在此之外,你还可以干你喜欢的事情,无论是什么,只要你开心就行。

我很反感的就是那些买课的,也不是说不好,就是感觉他们经常把一些很基础的东西包装的很高大上,教的很多都是网络上免费课程里学的东西,我觉得卖课的更多是教那些我们不付费学不到的东西,而不是教一些网上烂大街的东西。

对于API,我觉得主要是对于那些专业人员或者是尝鲜的人,否则,我不建议任何人去购买,就和前面龙虾热一样,网上一大堆部署的教程都看不懂,花钱代安装,这种就只能被割韭菜,这种就不要妄想能通过ai赚钱了,到哪里都只能是韭菜。

真的,技术永远是第一生产力,这点我觉得到什么时候都不会过时,所以我们无论何时都不要忘记学习,无论是学什么,我不喜欢以高高在上的语气去说任何人,但是事实就是这样,我们在不断发展,我们需要学习,这样才能使我们不掉队。

总结:以上就是我对于ai的看法,以及我胡说的一些东西。

基于python的扫雷

注:这是本人做的小游戏,目的是帮助人学习

项目地址:suyihang15/minesweeper_game: 基于python的扫雷小游戏

成品下载:https://github.com/suyihang15/minesweeper_game/releases/download/1.0.0/minesweeper.exe

扫雷游戏 — 原理与实现

一、游戏概述

扫雷(Minesweeper)是一款经典的单人逻辑推理游戏,核心玩法是在一个隐藏地雷的矩形网格中,通过翻开格子解读数字线索,安全地定位所有地雷。本实现使用 **Python + tkinter** 完整还原经典扫雷的核心机制,并加入了 Chord 双击展开、胜利烟花动画等进阶体验。

二、操作说明

| 左键点击(未翻开) | 翻开格子 |

| 左键点击(已插旗) | 快速解旗,无需右键循环 |

| 左键点击(已翻开数字格) | Chord 双击展开 |

| 右键点击 | 循环切换:无标记 → 旗子 → 问号 |

| 右键点击(游戏开始前) | 允许提前插旗标记(与标准扫雷一致) |

翻开格子显示 数字 (1~8):表示该格周围 8 个相邻格子中的地雷数。

翻开格子为 **空格**(雷数为 0):自动递归展开连通空白区域。

翻开格子为 **地雷**:游戏失败,展示所有地雷位置。

旗子和问号标记的格子受到保护,不会被左键意外翻开。

胜利条件

所有非雷格子均被翻开即获胜,无需给每一颗雷插旗。胜利时触发彩色烟花动画。

三、数据结构

board[r][c]    : int    -1 = 地雷, 0~8 = 周围雷数

revealed[r][c] : bool   是否已翻开

flagged[r][c]  : int    0 = 无标记, 1 = 旗子, 2 = 问号

buttons[r][c]  : Button  对应的 tkinter 按钮对象引用

所有数据以二维数组存储,索引 `(r, c)` 对应棋盘坐标。

四、核心算法

4.1 首次点击安全保障

首次点击前地雷尚未布置。玩家点击后:

1. 将该位置及其 3×3 邻域(共最多 9 格)标记为安全区;

2. 从安全区外的所有格子中随机选取 `mines_count` 个放置地雷;

3. 遍历棋盘,计算每个非雷格的周围地雷数。

  • safe_cells = {(safe_row + dr, safe_col + dc) for dr in (-1,0,1) for dc in (-1,0,1)}

  • candidates = [pos for pos in all_cells if pos not in safe_cells]

  • mine_positions = random.sample(candidates, mines_count)

复杂度:O(rows × cols),在布雷阶段一次性完成。

4.2 周围雷数统计

对每个非雷格子,统计其 8 个方向上的地雷数量:

    [NW] [N ] [NE]

    [W ] [ X] [E ]

    [SW] [S ] [SE]

count = 每个相邻位置是否为地雷(布尔累加)

该值直接决定了格子翻开后显示的数字或空格。

4.3 空格自动展开(Flood Fill)

翻开雷数为 0 的格子(空格)时,使用深度优先搜索(DFS)递归展开:

reveal_cell(r, c):

    if revealed[r][c] or 有旗子/问号标记 → 停止

    标记 (r, c) 为已翻开

    if board[r][c] > 0: 显示数字,停止

    if board[r][c] == 0: 对 8 个邻居递归调用 reveal_cell

点击一个空格即可让整个连通空白区域一次性展开,并在边界处停下显示数字。

4.4 Chord 双击展开

在已翻开的数字格上左键点击触发,是进阶玩家的高效操作:

do_chord(r, c):

    number = board[r][c]

    flag_count = 统计周围旗子数

    if flag_count != number:

        数字格金色闪烁 250ms(视觉反馈)

        return

    if 周围有未保护的地雷:

        游戏失败,直接展示所有雷(不翻开任何中间格)

        return

    翻开周围所有安全格子

原理:当周围插的旗子数恰好等于该格数字时,意味着剩余未翻开邻居必然是安全的。Chord 一键翻开它们,大幅提升操作效率。若旗子数与数字不匹配,数字格短暂变为金黄色作为反馈;若旗子标错且翻开的是地雷,直接判定失败。

4.5 胜利判定

遍历整个棋盘,确认没有非雷格子处于未翻开状态:

check_win():

    for each cell:

        if board[r][c] != -1 and not revealed[r][c]:

            return False

    return True

五、烟花庆祝动画

胜利后触发彩色粒子烟花:

1. Canvas 覆盖层 — 在窗口上方创建透明 tkinter Canvas 画布

2. 多轮爆发 — 分别在 100ms、600ms、1100ms 产生三轮随机位置爆发(4+3+3 次)

3. 粒子物理 — 每次爆发约 30 个粒子,具有随机方向初速度,受重力(+0.25/帧)和空气阻力(×0.94/帧)影响

4. 淡出效果 — 粒子生命周期内按比例缩小至消失

5. 自动清理 — 所有粒子消失后自动销毁 Canvas

六、难度配置

| 难度 | 棋盘大小 | 雷数 | 雷密度 |

| 初级 | 9×9 | 10 | ~12.3% |

| 中级 | 16×16 | 40 | ~15.6% |

| 高级 | 16×30 | 99 | ~20.6% |

七、运行方式

python minesweeper.py

环境要求:Python 3.x。tkinter 是 Python 标准库组件,无需额外安装依赖。

总结:具体可以看我项目仓库。