从零实现Python扫雷游戏:完整开发指南与深度解析

article/2025/7/5 21:31:35

目录

一、游戏架构设计

1.1 核心组件

1.2 类结构设计

二、核心算法实现

2.1 地雷生成算法

2.2 数字计算算法

2.3 空白区域展开算法

三、图形界面开发

3.1 主界面布局

3.2 交互事件处理

左键点击事件

右键点击事件

3.3 游戏状态显示

四、游戏功能扩展

4.1 多难度级别支持

4.2 最佳成绩系统

五、游戏测试与优化

5.1 常见问题与解决方案

5.2 性能优化建议

六、完整代码

6.1 效果图

七、继续完善的思路

结语


欢迎来到 盹猫(>^ω^<)的博客

本篇文章主要介绍了

[从零实现Python扫雷游戏:完整开发指南与深度解析]
❤博主广交技术好友,喜欢文章的可以关注一下❤


         扫雷作为Windows经典游戏,承载了许多人的童年回忆。本文将详细介绍如何使用Python和Tkinter库从零开始构建一个功能完整的扫雷游戏,涵盖游戏设计、算法实现和界面开发的全过程。

一、游戏架构设计

1.1 核心组件

我们的扫雷游戏由以下几个核心模块组成:

  1. ​游戏逻辑模块​​:处理地雷生成、数字计算、胜负判断等核心逻辑
  2. ​图形界面模块​​:使用Tkinter构建可视化界面
  3. ​数据持久化模块​​:记录和读取最佳成绩
  4. ​游戏控制模块​​:管理游戏状态和流程

1.2 类结构设计

class Minesweeper:def __init__(self, master, width=10, height=10, mines=10, difficulty="medium"):# 初始化游戏参数self.width = width      # 游戏板宽度self.height = height    # 游戏板高度self.mines = mines      # 地雷数量self.difficulty = difficulty  # 游戏难度# 游戏数据结构self.board = []         # 游戏板二维数组self.buttons = []       # 按钮二维数组self.mine_positions = set()  # 地雷位置集合self.flag_positions = set()  # 标记位置集合self.revealed_positions = set()  # 已揭开位置集合# 游戏状态self.start_time = 0     # 游戏开始时间self.highscores = {}    # 最佳成绩记录

二、核心算法实现

2.1 地雷生成算法

地雷生成需要满足两个条件:

  1. 随机分布
  2. 数量精确

我们使用Python的random模块实现:

def setup_board(self):# 随机放置地雷while len(self.mine_positions) < self.mines:x = random.randint(0, self.width - 1)y = random.randint(0, self.height - 1)self.mine_positions.add((x, y))self.board[y][x] = -1  # -1表示地雷

2.2 数字计算算法

每个非地雷格子需要计算周围8个格子中的地雷数量:

# 计算每个格子周围的地雷数
for y in range(self.height):for x in range(self.width):if self.board[y][x] == -1:  # 跳过地雷格子continue# 检查周围8个格子for nx, ny in [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y),             (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)]:if 0 <= nx < self.width and 0 <= ny < self.height and self.board[ny][nx] == -1:self.board[y][x] += 1

2.3 空白区域展开算法

当玩家点击空白格子时,需要自动展开所有相邻的空白区域:

def reveal_neighbors(self, x, y):# 检查周围8个格子for nx, ny in [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y),             (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)]:# 确保坐标在范围内且未被揭开if 0 <= nx < self.width and 0 <= ny < self.height and (nx, ny) not in self.revealed_positions:self.on_click(nx, ny)  # 递归揭开该格子

三、图形界面开发

3.1 主界面布局

使用Tkinter的网格布局管理器创建游戏板:

def create_widgets(self):for y in range(self.height):for x in range(self.width):btn = tk.Button(self.master, text="", width=2, height=1, bg="#f0f0f0",relief=tk.RAISED,font=("Helvetica", 10, "bold"),command=lambda x=x, y=y: self.on_click(x, y))btn.bind("<Button-3>", lambda e, x=x, y=y: self.on_right_click(x, y))btn.grid(row=y, column=x)self.buttons[y][x] = btn

3.2 交互事件处理

左键点击事件

def on_click(self, x, y):if (x, y) in self.mine_positions:  # 踩到地雷self.game_over()elif self.board[y][x] > 0:  # 数字格子self.reveal_number(x, y)else:  # 空白格子self.reveal_neighbors(x, y)self.check_victory()

右键点击事件

def on_right_click(self, x, y):btn = self.buttons[y][x]if btn['state'] != tk.DISABLED:if btn['text'] == "":  # 未标记btn.config(text="🚩", fg="red")self.flag_positions.add((x, y))elif btn['text'] == "🚩":  # 已标记btn.config(text="", fg="black")self.flag_positions.remove((x, y))self.check_victory()

3.3 游戏状态显示

计时器实现:

def update_timer(self):elapsed_time = int(time.time() - self.start_time)self.timer_label.config(text=f"时间: {elapsed_time}秒 | 最佳: {self.highscores.get(self.difficulty, 999)}秒")self.master.after(1000, self.update_timer)  # 每秒更新一次

四、游戏功能扩展

4.1 多难度级别支持

def change_difficulty(self, difficulty):self.difficulty = difficulty# 根据难度设置参数if difficulty == "easy":self.width, self.height, self.mines = 8, 8, 10elif difficulty == "hard":self.width, self.height, self.mines = 16, 16, 40else:  # mediumself.width, self.height, self.mines = 10, 10, 10self.restart_game()

4.2 最佳成绩系统

使用JSON文件存储成绩:

def __init__(self, master, ...):self.highscores_file = "minesweeper_scores.json"if not os.path.exists(self.highscores_file):with open(self.highscores_file, 'w') as f:json.dump({"easy": 999, "medium": 999, "hard": 999}, f)with open(self.highscores_file, 'r') as f:self.highscores = json.load(f)

成绩更新逻辑:

def check_victory(self):if self.is_win():elapsed_time = int(time.time() - self.start_time)if elapsed_time < self.highscores[self.difficulty]:self.highscores[self.difficulty] = elapsed_timewith open(self.highscores_file, 'w') as f:json.dump(self.highscores, f)

五、游戏测试与优化

5.1 常见问题与解决方案

  1. ​第一次点击就踩雷​​:

    • 解决方案:在第一次点击后再生成地雷,确保点击位置安全
  2. ​递归展开堆栈溢出​​:

    • 解决方案:对于大型游戏板,使用迭代代替递归
  3. ​界面卡顿​​:

    • 解决方案:减少不必要的界面刷新,使用双缓冲技术

5.2 性能优化建议

  1. 使用位运算加速邻居位置计算
  2. 预计算所有格子的邻居位置,避免重复计算
  3. 使用更高效的数据结构存储游戏状态

六、完整代码

"""
扫雷游戏主程序
使用tkinter实现的图形界面扫雷游戏
支持三种难度级别和最佳成绩记录
"""import tkinter as tk
from tkinter import messagebox, ttk
import random  # 用于随机生成地雷位置
import time    # 用于游戏计时
import json    # 用于读写最佳成绩
import os      # 用于检查文件是否存在class Minesweeper:"""扫雷游戏主类"""def __init__(self, master, width=10, height=10, mines=10, difficulty="medium"):"""初始化游戏:param master: tkinter根窗口:param width: 游戏板宽度(默认10):param height: 游戏板高度(默认10) :param mines: 地雷数量(默认10):param difficulty: 游戏难度(easy/medium/hard)"""# 初始化最佳成绩文件self.highscores_file = "minesweeper_scores.json"# 如果成绩文件不存在,创建并初始化if not os.path.exists(self.highscores_file):with open(self.highscores_file, 'w') as f:# 默认设置各难度最佳成绩为999秒json.dump({"easy": 999, "medium": 999, "hard": 999}, f)self.master = master  # tkinter主窗口self.difficulty = difficulty  # 游戏难度# 根据难度设置不同参数if difficulty == "easy":self.width, self.height, self.mines = 8, 8, 10    # 简单: 8x8, 10个地雷elif difficulty == "hard":self.width, self.height, self.mines = 16, 16, 40  # 困难: 16x16, 40个地雷else:  # mediumself.width, self.height, self.mines = width, height, mines  # 中等: 默认参数# 加载最佳成绩with open(self.highscores_file, 'r') as f:self.highscores = json.load(f)# 设置不同数字对应的颜色self.colors = {-1: "red",      # 地雷1: "blue",      # 1个地雷2: "green",     # 2个地雷3: "red",       # 3个地雷4: "purple",    # 4个地雷5: "maroon",    # 5个地雷6: "turquoise", # 6个地雷7: "black",     # 7个地雷8: "gray"       # 8个地雷}# 初始化游戏板(二维数组)self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]# 初始化按钮网格self.buttons = [[None for _ in range(self.width)] for _ in range(self.height)]self.mine_positions = set()      # 地雷位置集合self.flag_positions = set()      # 标记位置集合self.revealed_positions = set()  # 已揭开位置集合# 创建菜单栏self.create_menu()# 设置游戏板(放置地雷)self.setup_board()# 创建游戏界面控件self.create_widgets()# 记录游戏开始时间self.start_time = time.time()# 创建计时器标签self.timer_label = tk.Label(master, text=f"时间: 0秒 | 最佳: {self.highscores.get(self.difficulty, 999)}秒", font=("Helvetica", 10))self.timer_label.grid(row=self.height, columnspan=self.width)# 开始更新计时器self.update_timer()def create_menu(self):"""创建游戏菜单栏"""menubar = tk.Menu(self.master)self.master.config(menu=menubar)# 创建游戏菜单game_menu = tk.Menu(menubar, tearoff=0)menubar.add_cascade(label="游戏", menu=game_menu)# 添加难度选项game_menu.add_command(label="简单", command=lambda: self.change_difficulty("easy"))game_menu.add_command(label="中等", command=lambda: self.change_difficulty("medium"))game_menu.add_command(label="困难", command=lambda: self.change_difficulty("hard"))game_menu.add_separator()# 添加功能选项game_menu.add_command(label="最佳成绩", command=self.show_highscores)game_menu.add_command(label="重新开始", command=self.restart_game)game_menu.add_command(label="退出", command=self.master.quit)# 创建帮助菜单help_menu = tk.Menu(menubar, tearoff=0)menubar.add_cascade(label="帮助", menu=help_menu)help_menu.add_command(label="游戏说明", command=self.show_help)def show_help(self):"""显示游戏帮助信息"""help_text = """扫雷游戏规则:1. 左键点击格子揭开它
2. 右键点击格子标记/取消标记地雷
3. 数字表示周围8个格子中的地雷数量
4. 标记所有地雷并揭开所有安全格子获胜
5. 踩到地雷游戏结束难度说明:
- 简单:8x8 格子,10个地雷
- 中等:10x10 格子,10个地雷 
- 困难:16x16 格子,40个地雷"""messagebox.showinfo("游戏帮助", help_text)def show_highscores(self):"""显示各难度最佳成绩"""with open(self.highscores_file, 'r') as f:scores = json.load(f)messagebox.showinfo("最佳成绩", f"简单: {scores['easy']}秒\n"f"中等: {scores['medium']}秒\n"f"困难: {scores['hard']}秒")def change_difficulty(self, difficulty):"""更改游戏难度:param difficulty: 新难度级别(easy/medium/hard)"""self.difficulty = difficulty# 重新加载最佳成绩with open(self.highscores_file, 'r') as f:self.highscores = json.load(f)# 重新开始游戏self.restart_game()def restart_game(self):"""重新开始游戏"""# 清除现有按钮for y in range(len(self.buttons)):for x in range(len(self.buttons[0])):if self.buttons[y][x]:self.buttons[y][x].destroy()# 根据当前难度重置游戏参数if self.difficulty == "easy":self.width, self.height, self.mines = 8, 8, 10elif self.difficulty == "hard":self.width, self.height, self.mines = 16, 16, 40else:self.width, self.height, self.mines = 10, 10, 10# 重置游戏板状态self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]self.buttons = [[None for _ in range(self.width)] for _ in range(self.height)]self.mine_positions = set()self.flag_positions = set()self.revealed_positions = set()# 重新初始化游戏self.setup_board()self.create_widgets()self.start_time = time.time()  # 重置计时器def setup_board(self):"""设置游戏板,随机放置地雷并计算周围地雷数"""# 随机放置地雷while len(self.mine_positions) < self.mines:x = random.randint(0, self.width - 1)y = random.randint(0, self.height - 1)self.mine_positions.add((x, y))self.board[y][x] = -1  # -1表示地雷# 计算每个格子周围的地雷数for y in range(self.height):for x in range(self.width):if self.board[y][x] == -1:  # 跳过地雷格子continue# 检查周围8个格子for nx, ny in [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y),             (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)]:# 确保坐标在游戏板范围内且是地雷if 0 <= nx < self.width and 0 <= ny < self.height and self.board[ny][nx] == -1:self.board[y][x] += 1  # 增加周围地雷计数def create_widgets(self):"""创建游戏界面按钮网格"""for y in range(self.height):for x in range(self.width):# 创建按钮btn = tk.Button(self.master, text="",  # 初始无文本width=2, height=1, bg="#f0f0f0",  # 背景色relief=tk.RAISED,  # 3D凸起效果font=("Helvetica", 10, "bold"),  # 字体command=lambda x=x, y=y: self.on_click(x, y)  # 左键点击事件)# 绑定右键点击事件(标记地雷)btn.bind("<Button-3>", lambda e, x=x, y=y: self.on_right_click(x, y))# 将按钮放置在网格中btn.grid(row=y, column=x)# 保存按钮引用self.buttons[y][x] = btndef on_click(self, x, y):"""处理格子点击事件:param x: 点击格子的x坐标:param y: 点击格子的y坐标"""if (x, y) in self.mine_positions:  # 点击到地雷self.buttons[y][x].config(bg="red", text="*")  # 显示地雷messagebox.showinfo("游戏结束", "你踩到地雷了!")self.reveal_all_mines()  # 显示所有地雷self.restart_game()  # 重新开始游戏elif (x, y) not in self.revealed_positions:  # 未揭开的格子self.revealed_positions.add((x, y))  # 标记为已揭开btn = self.buttons[y][x]if self.board[y][x] > 0:  # 周围有地雷的格子btn.config(text=str(self.board[y][x]),  # 显示地雷数state=tk.DISABLED,  # 禁用按钮disabledforeground=self.colors[self.board[y][x]],  # 设置数字颜色relief=tk.SUNKEN  # 凹陷效果)else:  # 空白格子btn.config(state=tk.DISABLED, relief=tk.SUNKEN, bg="#e0e0e0")self.reveal_neighbors(x, y)  # 自动揭开周围空白格子self.check_victory()  # 检查是否获胜def on_right_click(self, x, y):"""处理右键点击事件(标记/取消标记地雷):param x: 点击格子的x坐标:param y: 点击格子的y坐标"""btn = self.buttons[y][x]if btn['state'] != tk.DISABLED:  # 只有未禁用的按钮可以标记if btn['text'] == "":  # 未标记状态btn.config(text="🚩", fg="red")  # 添加旗帜标记self.flag_positions.add((x, y))  # 记录标记位置elif btn['text'] == "🚩":  # 已标记状态btn.config(text="", fg="black")  # 取消标记self.flag_positions.remove((x, y))  # 移除标记记录self.check_victory()  # 检查是否获胜def reveal_neighbors(self, x, y):"""递归揭开周围的空白格子:param x: 当前格子的x坐标:param y: 当前格子的y坐标"""# 检查周围8个格子for nx, ny in [(x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y),             (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1)]:# 确保坐标在范围内且未被揭开if 0 <= nx < self.width and 0 <= ny < self.height and (nx, ny) not in self.revealed_positions:self.on_click(nx, ny)  # 揭开该格子def reveal_all_mines(self):"""显示所有地雷位置"""for x, y in self.mine_positions:self.buttons[y][x].config(text="*", bg="red")  # 红色背景显示地雷def check_victory(self):"""检查游戏是否胜利"""# 条件1: 所有地雷都被正确标记# 条件2: 所有非地雷格子都被揭开if (self.flag_positions == self.mine_positions and len(self.revealed_positions) == self.width * self.height - self.mines):elapsed_time = int(time.time() - self.start_time)  # 计算用时# 检查是否打破记录if elapsed_time < self.highscores[self.difficulty]:self.highscores[self.difficulty] = elapsed_time  # 更新记录with open(self.highscores_file, 'w') as f:json.dump(self.highscores, f)  # 保存新记录messagebox.showinfo("胜利", f"新纪录!用时: {elapsed_time}秒")else:messagebox.showinfo("胜利", f"你赢了!用时: {elapsed_time}秒\n"f"当前记录: {self.highscores[self.difficulty]}秒")self.restart_game()  # 重新开始游戏def update_timer(self):"""更新计时器显示"""elapsed_time = int(time.time() - self.start_time)self.timer_label.config(text=f"时间: {elapsed_time}秒 | 最佳: {self.highscores.get(self.difficulty, 999)}秒")# 1秒后再次更新self.master.after(1000, self.update_timer)if __name__ == "__main__":"""程序入口"""root = tk.Tk()  # 创建主窗口root.title("扫雷游戏")  # 设置窗口标题root.resizable(False, False)  # 禁止调整窗口大小game = Minesweeper(root)  # 创建游戏实例root.mainloop()  # 启动主事件循环

6.1 效果图

下面是实现的效果图,看起来和原版还是非常相似的 。

七、继续完善的思路

  1. ​添加音效系统​​:为点击、胜利、失败等事件添加音效
  2. ​实现主题切换​​:支持多种颜色主题和皮肤
  3. ​添加解谜模式​​:预生成有趣的谜题布局
  4. ​网络对战功能​​:实现多人扫雷对战

结语

        通过本项目,我们完整实现了一个功能丰富的扫雷游戏,涵盖了从算法设计到界面开发的全过程。这个项目不仅可以帮助理解游戏开发的基本原理,也是学习Python GUI编程的绝佳案例。你可以基于这个基础版本,继续扩展更多有趣的功能。

​完整代码​​已在文中提供,建议亲自运行并尝试修改,这是学习编程的最佳方式。如果你有任何问题或改进建议,欢迎在评论区交流讨论!


如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链

感谢您的关注和收藏!!!!!!


http://www.hkcw.cn/article/jMrQAyBcPE.shtml

相关文章

hooks组件-useState

hooks组件-useState hook组件的本质就是函数组件&#xff0c;但是基于各种hook让其动态化&#xff01; 常用hook&#xff1a; useReducer&#xff1a;redux useCallback useMemo&#xff1a;去做一些优化。 useRef&#xff1a;使用ref useImperativeHandle&#xff1a;拿到子组…

X浏览器APP:轻巧快捷,畅享极速浏览

在移动互联网时代&#xff0c;浏览器作为我们获取信息、娱乐和社交的重要工具&#xff0c;其性能和功能直接影响着我们的使用体验。X浏览器APP正是这样一款专为移动设备设计的轻巧快捷的网络浏览器&#xff0c;它凭借独特的核心引擎和多项实用功能&#xff0c;为用户提供了极速…

一种基于性能建模的HADOOP配置调优策略

1.摘要 作为分布式系统基础架构的Hadoop为应用程序提供了一组稳定可靠的接口。该文作者提出了一种基于集成学习建模的Hadoop配置参数调优的方法。实验结果表明&#xff0c;该性能模型可以准确预测MapReduce应用程序的运行时间。采用提出的Hadoop配置参数方法调优后&#xff0c…

【001】利用github搭建静态网站_essay

文章目录 1. 简介2. 先了解网址规则2.1 文件及网址形式2.2 相互访问 3. 搭建网页的过程3.1 网页文件3.2 github搭建仓库及文件上传3.3 搭建网站 1. 简介 相信大家都有过想要自己搭建一个稳定可靠的网站&#xff0c;github是一个不错的选择&#xff0c;本来国内有gitee可以搭建…

太极APP:免Root,畅享Xposed模块的神奇魅力

在安卓系统中&#xff0c;Xposed框架一直以其强大的功能和高度的自定义能力受到众多用户的喜爱。然而&#xff0c;传统的Xposed框架需要Root权限和复杂的刷机操作&#xff0c;这使得许多普通用户望而却步。太极APP的出现&#xff0c;打破了这一限制&#xff0c;它为用户提供了一…

大学专业解读——电子信息

家里娃要高考了&#xff0c;面临专业和学校选择的问题。虽然我们家长做为职场人已经工作超过30年&#xff0c;但实际上对于专业和就业的问题&#xff0c;也不是太懂&#xff0c;网上有很多营销号在讲专业的志愿填报&#xff0c;但信息都比较碎片。所以&#xff0c;抽出一点时间…

实验一:PyTorch基本操作实验

import torch # PyTorch中初始化矩阵常见有以下几种方法 # 1. 直接使用固定值初始化 # M torch.tensor([[1.0, 2.0, 3.0]]) # 1x3矩阵 # 2. 随机初始化 # M torch.rand(1, 3) # 1x3矩阵&#xff0c;元素在0-1之间均匀分布 # M torch.randn(1, 3) # 1x3矩阵&#xff0c;元…

深入理解 C++ 中的 list 容器:从基础使用到模拟实现

一、list 的底层数据结构与核心特性 1.1 双向循环链表的物理结构 节点定义&#xff1a;每个节点包含三个部分 template <typename T> struct ListNode {T data; // 存储的数据ListNode* prev; // 指向前驱节点的指针ListNode* next; // 指向后继节点的指针L…

【iOS】YYModel源码解析

YYModel源码解析 文章目录 YYModel源码解析前言YYModel性能优势YYModel简介YYClassInfo解析YYClassIvarInfo && objc_ivarYYClassMethodInfo && objc_methodYYClassPropertyInfo && property_tYYClassInfo && objc_class YYClassInfo的初始化细…

nssctf第二题[SWPUCTF 2021 新生赛]简简单单的逻辑

这是题目&#xff0c;下载后得到一个python文件,打开 解读代码&#xff1a; for i in range(len(list)):key (list[i]>>4)((list[i] & 0xf)<<4)result str(hex(ord(flag[i])^key))[2:].zfill(2)list[i]>>4&#xff1a;从列表中取数字同时高4位向右位…

linux驱动 - 5: simple usb device驱动

参考第2节, 准备好编译环境并实现hello.ko: linux驱动 - 2: helloworld.ko_linux 驱动开发 hello world ko-CSDN博客 下面在hello模块的基础上, 添加代码, 实现一个usb设备驱动的最小骨架. #include <linux/init.h> #include <linux/module.h> #include <lin…

某电子计数跳绳的一次修复经历

引子 这阵子开始锻炼身体&#xff0c;感觉投入成本低的&#xff0c;就是跳绳了&#xff0c;所以从20块钱的竹节跳起&#xff0c;随着100、1000、2000、3000个数的加码&#xff0c;还是需要一个电子计数会更好些&#xff0c;不用心中默数了。 这样在某宝上购入一个电子自动计数&…

【设计模式-3.5】结构型——装饰器模式

说明&#xff1a;本文介绍结构型设计模式之一的装饰器模式 定义 装饰器模式&#xff08;Decorator Pattern&#xff09;也叫作包装器模式&#xff08;Wrapper Pattern&#xff09;&#xff0c;指再不改变原有对象的基础上&#xff0c;动态地给一个对象添加一些额外的职责。就…

交换机、路由器配置

四、交换机配置 1、以太网MAC地址 以太网地址用来识别一个以太网上的某个单独的设备或一组设备。 2、Ethernet II帧格式 3、交换机工作原理 初始状态 MAC地址学习&#xff08;源MAC&#xff09; 广播未知数据帧 接收方回应&#xff0c;交换机再次学习MAC地址 交换机实现单播…

业务系统-AI 智能导航设计-系统设计篇(上)

引言 在数字化转型加速推进的当下&#xff0c;企业业务系统正朝着复杂化、集成化方向快速发展。据 Gartner 调研数据显示&#xff0c;超过 68% 的企业业务系统因功能模块激增导致员工平均操作失误率上升 23%&#xff0c;传统菜单式导航与标准化培训模式已难以应对 "功能爆…

如何把电脑桌面设置在D盘?

一、桌面路径默认设置在C盘的问题 桌面路径默认设置在C盘的问题&#xff1a;如果你习惯于将重要文件存放在桌面上&#xff0c;那么在系统崩溃时&#xff0c;这些文件可能会遭受损失&#xff0c;因为只有重装系统才能解决问题。为了避免这种情况&#xff0c;你可以考虑将桌面路…

Mysql水平分表(基于Mycat)及常用分片规则

参考资料: 参考视频 参考博客 视频资料:链接: https://pan.baidu.com/s/1xT_WokN_xlRv0h06b6F3yg 提取码: aag3 Mysql分库分表(基于Mycat)的基本部署 MySQL垂直分库(基于MyCat) 概述: 本例是在垂直分库的基础上,又作的水平分库,参照前文也可以单独拿出来做水平分…

「Java教案」算术运算符与表达式

课程目标 1&#xff0e;知识目标 能够区分Java运算符的种类&#xff0c;例如&#xff0c;算术、赋值、关系、逻辑、位运算等。能够区分Java各类运算符的功能和使用场景。能够根据表达式的构成和计算规则&#xff0c;写出正确的表达式。能够根据运算符优先级与结合性&#xff…

普中STM32F103ZET6开发攻略(二)

接上文&#xff1a;普中STM32F103ZET6开发攻略&#xff08;一&#xff09;-CSDN博客 各位看官老爷们&#xff0c;点击关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 目录 接上文&#xff1a;普中…

FPGA仿真中阻塞赋值(=)和非阻塞赋值(<=)区别

FPGA仿真中阻塞赋值和非阻塞赋值的区别 单独仿真小模块对但将小模块加入整个工程仿真不对就有可能是没有注意到仿真中阻塞赋值和非阻塞赋值的区别 目录 前言 一、简介 二、设计实例 三、仿真实例 1、仿真用非阻塞赋值 2、仿真用阻塞赋值 总结 前言 网上很多人介绍verilo…