python 小游戏:扫雷

devtools/2025/2/6 9:40:35/

目录

1. 前言

2. 准备工作

3. 生成雷区

4. 鼠标点击扫雷

5. 胜利 or 失败

6. 游戏效果展示

7. 完整代码


1. 前言

本文使用 Pygame 实现的简化版扫雷游戏。

如上图所示,游戏包括基本的扫雷功能:生成雷区左键点击扫雷右键标记地雷显示数字提示等。

2. 准备工作

首先,当然要下载pygame 库文件,可以通过下面命令下载

pip install pygame

在这之前,我们需要提前规划好前期工作,例如游戏窗口多大,生成图形显示的颜色等等。

这里为了方便,我们采用大多数默认的版本,这里生成的格子数量就是 (400 / 40)*(400/40),也就是100个窗格

python">import pygame
import random# 初始化 Pygame
pygame.init()# 屏幕设置
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 400
CELL_SIZE = 40
GRID_WIDTH = SCREEN_WIDTH // CELL_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // CELL_SIZE# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
RED = (255, 0, 0)
GREEN = (0, 255, 0)# 字体设置
font = pygame.font.SysFont("Arial", 20)

如下:

3. 生成雷区

有了窗口格子区域,接下来就可以生成雷区,这里采用random函数随机生成,保证每次打开游戏雷区的位置不一样

python"># 生成雷区
def create_grid(width, height, num_mines):grid = [[0 for _ in range(width)] for _ in range(height)]mines = set()while len(mines) < num_mines:x = random.randint(0, width - 1)y = random.randint(0, height - 1)mines.add((x, y))grid[y][x] = -1  # -1 表示地雷# 计算每个格子周围的地雷数量for y in range(height):for x in range(width):if grid[y][x] == -1:continuecount = 0for dy in [-1, 0, 1]:for dx in [-1, 0, 1]:if 0 <= x + dx < width and 0 <= y + dy < height:if grid[y + dy][x + dx] == -1:count += 1grid[y][x] = countreturn grid, mines
  • 使用 create_grid 函数生成雷区,随机放置地雷,并计算每个格子周围的地雷数量。

 

4. 鼠标点击扫雷

生成雷区后,下面就是扫雷环节,之前写C语言扫雷,还需要在控制台键入区域。这里可以直接调用鼠标

python"># 绘制格子
def draw_grid():for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)if revealed[y][x]:if grid[y][x] == -1:pygame.draw.rect(screen, RED, rect)  # 地雷else:pygame.draw.rect(screen, GRAY, rect)if grid[y][x] > 0:text = font.render(str(grid[y][x]), True, BLACK)screen.blit(text, (x * CELL_SIZE + 10, y * CELL_SIZE + 10))else:pygame.draw.rect(screen, WHITE, rect)if flagged[y][x]:pygame.draw.circle(screen, GREEN, rect.center, 10)  # 标记地雷pygame.draw.rect(screen, BLACK, rect, 1)  # 格子边框# 翻开格子
def reveal_cell(x, y):if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT and not revealed[y][x]:revealed[y][x] = Trueif grid[y][x] == 0:for dy in [-1, 0, 1]:for dx in [-1, 0, 1]:reveal_cell(x + dx, y + dy)  # 递归翻开空白区域

5. 胜利 or 失败

胜利条件:所有非地雷格子都被翻开时,玩家胜利。

  • 游戏结束显示

    • 如果踩到地雷,显示 "Game Over!"。

    • 如果胜利,显示 "You Win!"。

python"># 检查是否胜利
def check_win():for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):if grid[y][x] != -1 and not revealed[y][x]:return Falsereturn True

6. 游戏效果展示

失败:

胜利: 

7. 完整代码

直接复制到py脚本运行即可:

python">import pygame
import random# 初始化 Pygame
pygame.init()# 屏幕设置
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 400
CELL_SIZE = 40
GRID_WIDTH = SCREEN_WIDTH // CELL_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // CELL_SIZE# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
RED = (255, 0, 0)
GREEN = (0, 255, 0)# 字体设置
font = pygame.font.SysFont("Arial", 20)# 初始化屏幕
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Minesweeper")# 游戏状态
game_over = False
win = False# 生成雷区
def create_grid(width, height, num_mines):grid = [[0 for _ in range(width)] for _ in range(height)]mines = set()while len(mines) < num_mines:x = random.randint(0, width - 1)y = random.randint(0, height - 1)mines.add((x, y))grid[y][x] = -1  # -1 表示地雷# 计算每个格子周围的地雷数量for y in range(height):for x in range(width):if grid[y][x] == -1:continuecount = 0for dy in [-1, 0, 1]:for dx in [-1, 0, 1]:if 0 <= x + dx < width and 0 <= y + dy < height:if grid[y + dy][x + dx] == -1:count += 1grid[y][x] = countreturn grid, mines# 初始化雷区
grid, mines = create_grid(GRID_WIDTH, GRID_HEIGHT, 10)# 记录翻开的格子和标记的地雷
revealed = [[False for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
flagged = [[False for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]# 绘制格子
def draw_grid():for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)if revealed[y][x]:if grid[y][x] == -1:pygame.draw.rect(screen, RED, rect)  # 地雷else:pygame.draw.rect(screen, GRAY, rect)if grid[y][x] > 0:text = font.render(str(grid[y][x]), True, BLACK)screen.blit(text, (x * CELL_SIZE + 10, y * CELL_SIZE + 10))else:pygame.draw.rect(screen, WHITE, rect)if flagged[y][x]:pygame.draw.circle(screen, GREEN, rect.center, 10)  # 标记地雷pygame.draw.rect(screen, BLACK, rect, 1)  # 格子边框# 翻开格子
def reveal_cell(x, y):if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT and not revealed[y][x]:revealed[y][x] = Trueif grid[y][x] == 0:for dy in [-1, 0, 1]:for dx in [-1, 0, 1]:reveal_cell(x + dx, y + dy)  # 递归翻开空白区域# 检查是否胜利
def check_win():for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):if grid[y][x] != -1 and not revealed[y][x]:return Falsereturn True# 游戏主循环
clock = pygame.time.Clock()
running = Truewhile running:screen.fill(WHITE)# 事件处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif not game_over and not win:if event.type == pygame.MOUSEBUTTONDOWN:x, y = event.posgrid_x = x // CELL_SIZEgrid_y = y // CELL_SIZEif event.button == 1:  # 左键翻开格子if grid[grid_y][grid_x] == -1:game_over = True  # 踩到地雷else:reveal_cell(grid_x, grid_y)if check_win():win = Trueelif event.button == 3:  # 右键标记地雷if not revealed[grid_y][grid_x]:flagged[grid_y][grid_x] = not flagged[grid_y][grid_x]# 绘制雷区draw_grid()# 游戏结束显示if game_over:text = font.render("Game Over!", True, RED)screen.blit(text, (SCREEN_WIDTH // 2 - 60, SCREEN_HEIGHT // 2 - 10))if win:text = font.render("You Win!", True, GREEN)screen.blit(text, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2 - 10))# 更新屏幕pygame.display.flip()clock.tick(30)# 退出游戏
pygame.quit()

 


http://www.ppmy.cn/devtools/156507.html

相关文章

【怎么用系列】短视频戒除-1-对推荐算法进行干扰

如今推荐算法已经渗透到人们生活的方方面面&#xff0c;尤其是抖音等短视频核心就是推荐算法。 【短视频的危害】 1> 会让人变笨&#xff0c;慢慢让人丧失注意力与专注力 2> 让人丧失阅读长文的能力 3> 让人沉浸在一个又一个快感与嗨点当中。当我们刷短视频时&#x…

基于单片机的超声波液位检测系统(论文+源码)

1总体设计 本课题为基于单片机的超声波液位检测系统的设计&#xff0c;系统的结构框图如图2.1所示。其中包括了按键模块&#xff0c;温度检测模块&#xff0c;超声波液位检测模块&#xff0c;显示模块&#xff0c;蜂鸣器等器件设备。其中&#xff0c;采用STC89C52单片机作为主控…

单片机基础模块学习——AT24C02芯片

一、EEPROM芯片 ROMRAM断电后数据保留断电后数据消失 因此&#xff0c;如果在断电后希望数据继续保留的话&#xff0c;就需要存储在EEPROM芯片中。 二、EEPROM芯片原理图 A0~A2与芯片地址相关连接到GND&#xff0c;为0GND 接地&#xff0c;VCC 正电源 WP——write protect写…

2. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--什么是微服务--微服务概述与演变

在软件架构不断演进的今天&#xff0c;微服务架构已成为许多企业构建现代化应用的首选方案。本文将深入探讨微服务的基本概念、演变历程及其出现的背景和推动因素&#xff0c;同时分析当前微服务在业界的应用现状和未来趋势&#xff0c;为读者提供一个全面的视角&#xff0c;理…

【大模型LLM面试合集】大语言模型架构_Transformer架构细节

Transformer架构细节 1.Transformer各个模块的作用 &#xff08;1&#xff09;Encoder模块 经典的Transformer架构中的Encoder模块包含6个Encoder Block. 每个Encoder Block包含两个⼦模块, 分别是多头⾃注意⼒层, 和前馈全连接层. 多头⾃注意⼒层采⽤的是⼀种Scaled Dot-Pr…

从离散傅里叶变换(DFT)到快速傅里叶变换(FFT)

摘要 离散傅里叶变换&#xff08;DFT&#xff09;是数字信号处理领域中分析信号频域特性的重要工具&#xff0c;但直接计算DFT的复杂度较高&#xff0c;限制了其在大规模数据处理中的应用。快速傅里叶变换&#xff08;FFT&#xff09;的出现显著降低了计算复杂度&#xff0c;极…

前端学习:Axios Http请求库入门与实战应用

什么是Promise&#xff1f; Promise 是一个表示异步操作最终完成或失败的对象。它允许你更优雅地处理异步操作&#xff0c;避免回调地狱&#xff08;Callback Hell&#xff09;。 特点&#xff1a; 异步性&#xff1a;Promise 代表一个异步操作的最终完成或失败。 不可更改&…

udp和tcp的区别

目录 UDP 和 TCP 的区别 1. 连接性 2. 可靠性 3. 数据传输顺序 4. 流量控制和拥塞控制 5. 效率 6. 应用场景 UDP 和 TCP 的 C/C 代码实现区别 1. TCP 服务器端和客户端 TCP 服务器端&#xff08;Server&#xff09; TCP 客户端&#xff08;Client&#xff09; 2. U…