带你用Python制作一个经典小游戏:扫雷

news2024/12/22 19:28:17

名字:阿玥的小东东

学习:Python、C/C++

主页链接:阿玥的小东东的博客_CSDN博客-python&&c++高级知识,过年必备,C/C++知识讲解领域博主

目录

游戏界面尺寸

方块尺寸

雷的数量

游戏状态

最后,我们定义一个函数run(),用于运行游戏:


 

扫雷是一款单人益智游戏,目的是在不触雷的情况下,揭示所有非雷方块。玩家可以通过点击方块来揭示其内容,如果揭示到雷,游戏结束。在游戏开始前,玩家可以选择游戏难度,包括初级、中级和高级。

代码实现:

首先,我们需要导入必要的模块:

import random import pygame

然后,定义一些常量和变量:

游戏界面尺寸

SCREEN_WIDTH = 400 SCREEN_HEIGHT = 500

方块尺寸

BLOCK_WIDTH = 20 BLOCK_HEIGHT = 20

雷的数量

BOMB_COUNT = {"easy": 10, "medium": 40, "hard": 99}

游戏状态

GAME_START = 0 GAME_RUN = 1 GAME_OVER = 2

接下来,定义我们的主类Minesweeper:

class Minesweeper: def init(self): # 初始化游戏界面和游戏状态 self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) self.game_state = GAME_START self.clock = pygame.time.Clock() pygame.display.set_caption("Minesweeper")

# 初始化游戏
def init_game(self):
    # 初始化地图
    self.map = [[0 for i in range(10)] for j in range(10)]
    self.bomb_count = BOMB_COUNT[self.difficulty]
    self.flag_count = self.bomb_count
    self.bomb_location = []
    self.left_click_count = 0

    # 随机生成地雷
    while len(self.bomb_location) < self.bomb_count:
        x = random.randint(0, 9)
        y = random.randint(0, 9)
        if self.map[y][x] == 0:
            self.map[y][x] = -1
            self.bomb_location.append((x, y))

    # 计算每个方块周围的地雷数
    for y in range(10):
        for x in range(10):
            if self.map[y][x] == -1:
                continue
            count = 0
            for yy in range(y - 1, y + 2):
                for xx in range(x - 1, x + 2):
                    if xx < 0 or xx > 9 or yy < 0 or yy > 9:
                        continue
                    if self.map[yy][xx] == -1:
                        count += 1
            self.map[y][x] = count

在init_game()函数中,我们首先初始化了地图,然后随机生成地雷,并且计算每个方块周围的地雷数。

接下来,定义一个函数draw_block(),用于绘制方块:

 

# 绘制方块
def draw_block(self, x, y, value):
    if value == -1:
        # 绘制雷
        pygame.draw.rect(self.screen, (255, 0, 0), (x * BLOCK_WIDTH, y * BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT))
    else:
        # 绘制数字或空白方块
        pygame.draw.rect(self.screen, (255, 255, 255), (x * BLOCK_WIDTH, y * BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT))
        if value > 0:
            font = pygame.font.SysFont(None, BLOCK_HEIGHT - 2)
            text = font.render(str(value), True, (0, 0, 0))
            text_rect = text.get_rect()
            text_rect.centerx = x * BLOCK_WIDTH + BLOCK_WIDTH / 2
            text_rect.centery = y * BLOCK_HEIGHT + BLOCK_HEIGHT / 2
            self.screen.blit(text, text_rect)

在主类中,我们还需要定义事件处理函数handle_event():

# 事件处理函数
def handle_event(self, event):
    if event.type == pygame.QUIT:
        self.game_state = GAME_OVER
    elif event.type == pygame.KEYDOWN:
        if event.key == pygame.K_ESCAPE:
            self.game_state = GAME_OVER
        elif event.key == pygame.K_F2:
            self.init_game()
    elif event.type == pygame.MOUSEBUTTONDOWN:
        if self.game_state == GAME_START:
            self.game_state = GAME_RUN
        if event.button == 1:
            # 左键
            x, y = event.pos
            x = x / BLOCK_WIDTH
            y = y / BLOCK_HEIGHT
            if self.map[y][x] == -1:
                self.game_state = GAME_OVER
            else:
                self.reveal_block(x, y)
                self.left_click_count += 1
        elif event.button == 3:
            # 右键
            x, y = event.pos
            x = x / BLOCK_WIDTH
            y = y / BLOCK_HEIGHT
            if self.map[y][x] == -1:
                self.bomb_count += 1
                self.flag_count += 1
            else:
                self.flag_count -= 1
            self.map[y][x] = -2 if self.map[y][x] == 0 else 0

在handle_event()函数中,我们处理了游戏中的各种事件,包括鼠标左键点击、鼠标右键点击、键盘按键等。

接下来,我们定义一个函数reveal_block(),用于揭示方块:

# 揭示方块
def reveal_block(self, x, y):
    if x < 0 or x > 9 or y < 0 or y > 9:
        return
    if self.map[y][x] == -1 or self.map[y][x] == -2:
        return
    if self.map[y][x] > 0:
        self.map[y][x] = -2
        return
    self.map[y][x] = -2
    self.reveal_block(x - 1, y)
    self.reveal_block(x + 1, y)
    self.reveal_block(x, y - 1)
    self.reveal_block(x, y + 1)
    self.reveal_block(x - 1, y - 1)
    self.reveal_block(x + 1, y - 1)
    self.reveal_block(x - 1, y + 1)
    self.reveal_block(x + 1, y + 1)

在reveal_block()函数中,我们首先检查方块是否是地雷或旗子,如果是,则不做任何操作。如果方块是数字或空白方块,则将其标记为已经揭示,并递归揭示周围的方块。

最后,我们定义一个函数run(),用于运行游戏:

# 运行游戏
def run(self):
    while self.game_state != GAME_OVER:
        self.clock.tick(60)
        for event in pygame.event.get():
            self.handle_event(event)
        self.screen.fill((0, 0, 0))
        if self.game_state == GAME_RUN:
            for y in range(10):
                for x in range(10):
                    self.draw_block(x, y, self.map[y][x])
            if self.left_click_count == 100 - self.bomb_count:
                self.game_state = GAME_OVER
                font = pygame.font.SysFont(None, 30)
                text = font.render("You Win!", True, (0, 255, 0))
                text_rect = text.get_rect()
                text_rect.centerx = SCREEN_WIDTH / 2
                text_rect.centery = SCREEN_HEIGHT - 80
                self.screen.blit(text, text_rect)
        elif self.game_state == GAME_START:
            font = pygame.font.SysFont(None, 30)
            text = font.render("Press any key to start game", True, (255, 255, 255))
            text_rect = text.get_rect()
            text_rect.centerx = SCREEN_WIDTH / 2
            text_rect.centery = SCREEN_HEIGHT - 80
            self.screen.blit(text, text_rect)
        else:
            # GAME_OVER
            font = pygame.font.SysFont(None, 30)
            text = font.render("Game Over! Press F2 to restart", True, (255, 0, 0))
            text_rect = text.get_rect()
            text_rect.centerx = SCREEN_WIDTH / 2
            text_rect.centery = SCREEN_HEIGHT - 80
            self.screen.blit(text, text_rect)
        pygame.display.update()

最后,我们创建一个Minesweeper对象并运行游戏:

if name == "main": pygame.init() minesweeper = Minesweeper() minesweeper.difficulty = "easy" # 初级 minesweeper.init_game() minesweeper.run() pygame.quit()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件项目成本的计算

在《架构思维的六要素》中,列出的第一个要素就是成本,成本对项目设计和决策起着至关重要的作用。今天咱们就来看看直接成本、间接成本和总成本的关系。 直接成本 工作于服务的开发者工作于系统测试的测试者设计数据库的DBA设计界面和致力于优化用户体验的…

ROS学习篇之远程控制(七)-局域网内的控制

文章目录 一.pc与pc端二.手机与pc端(1)pc端:**步骤1:** 运行 roscore**步骤2:** 新开一个终端运行,运行 rosrun turtlesim turtlesim_node **步骤3:** 新建一个终端查看ip,运行ifcon…

基于matlab根据特征进行全景图像拼接(附源码)

一、前言 此示例演示如何使用基于特征的图像配准技术自动创建全景图。 特征检测和匹配是许多计算机视觉应用(如图像配准、跟踪和对象检测)中使用的强大技术。在此示例中,基于特征的技术用于自动拼接一组图像。图像拼接过程是基于特征的图像…

火车头采集:高效数据采集工具的介绍

火车头采集是一款基于Python语言开发的网络爬虫工具,用于快速高效地从互联网上采集数据并存储到本地或远程数据库。它简单易用且功能强大,在各行各业广泛应用。 1、设置chatgpt自定义key 添加网站 通过关键词批量生成原创文章 设置发布网站 发布成功 相…

Python GUI编程利器:Tkinker中的文本输入框和下拉菜单(4)

小朋友们好,大朋友们好! 我是猫妹,一名爱上Python编程的小学生。 和猫妹学Python,一起趣味学编程。 今日目标 实现下面效果: 文本输入框(Entry类) 文本输入框,顾名思义,就是实现文本输入功能…

dnsServer搭建

一、dokcer安装 #下载文件:https://github.com/TechnitiumSoftware/DnsServer/blob/master/docker-compose.yml #另存到/root/docker-compose.yml cd /root docker-compose -f docker-compose.yml up -d #启动成功后,浏览器输入:http://192…

Airtest:Windows桌面应用自动化测试【AirtestIDE功能】

AirtestIDE功能 基础功能一、设备窗二、Airtest辅助窗三、Poco辅助窗3.1UI树常见问题:3.1.1为什么我选择了Poco模式后,没有成功刷出UI树3.1.2为什么接入了SDK、使用了原生App依然看不到UI树3.1.3UI树在一段时间后没有正确刷新 四、脚本编辑窗五、Log查看…

蓝牙HID与Android的通信--多点触摸问题

通过蓝牙HID上传鼠标,键盘,按键的事件基本已经比较成熟。并且功能比较好实现,基本参照网络上的配置都可以弄出来。但多点触摸功能却怎么弄都没有满意的结果。搜罗了网上的很多报告描述符的描写,试验了一段时间,竟然没有…

OpenCV:深入Feature2D组件——角点检测

角点检测 1 Harris角点检测1.1 兴趣点与角点1.2 角点检测1.3 harris角点检测1.4 实现harris角点检测:cornerHarris()函数1.5 综合案例:harris角点检测与测绘 2. Shi—Tomasi角点检测2.1Shi—Tomasi角点检测概述2.2 确定图像强角点:goodFeatur…

硬件基本常识杂记1

文章目录 电感(RL电路),电容(RC电路),(LRC电路)谐振(串联、并联)滤波器(高通RC、低通RC、高通RL、低通RL、带通、Π型)积分电路、微分电路截至频率w信号传输、…

Docker迁移与备份

容器保存为镜像 语法: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 为nginx创建镜像: docker commit -a "leq" -m "nginx的镜像" 10053cd47ebf nginx:v1.0 -a 提交的镜像作者 -m 提交时的说明文字 镜像备份 语法: docker save…

深入理解C语言对文件的包装与缓冲区

内存级文件操作的运用 1.模拟实现文件分装2. 深入理解缓冲区的概念 1.模拟实现文件分装 【目标】 以最简单的方式,理解FILE结构体的原理。 头文件:mystdio.h(定义了MY_FILE结构体,声明fopen,fwrite,fclos…

『手撕 Mybatis 源码』10 - 一级缓存

一级缓存 概述 一级缓存是 SqlSession 级别的缓存。在操作数据库时需要构造 SqlSession 对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的 SqlSession 之间的缓存数据区域(HashMap)是互相不影响的二级缓…

hive基于新浪微博的日志数据分析——项目及源码

有需要本项目的全套资源资源以及部署服务可以私信博主!!! 本系统旨在对新浪微博日志进行大数据分析,探究用户行为、内容传播、移动设备等多个方面的特征和趋势,为企业和个人的营销策略、产品设计、用户服务等提供有益的…

PN结、二极管、三极管、三极管放大电路、上拉电路/下拉电路

1、N型参杂 与 P型参杂 B站 视频地址 :https://www.bilibili.com/video/BV1fB4y147Gn 1)N型参杂 (N型半导体) : 4价硅 参杂 5价麟,多一个自由负电子(带负电) 2)P型参杂…

Linux性能学习(4.2):网络_为什么MTU是1500

文章目录 1 基本概念2 为什么MTU是15003 有效载荷最大是1500吗4 Linux下如何修改MTU 参考资料: 1. RFC894 2. 什么是MTU(Maximum Transmission Unit)? 1 基本概念 Maximum Transmission Unit,缩写MTU,即…

Python爬虫:Scrapy框架

🚀Python爬虫:Scrapy框架 🕷️ Scrapy介绍📦 Scrapy框架📁 Scrapy项目🔍 创建爬虫过程🕸️ 页面分析📑 提取信息🎉 完整代码📝 结语 在本篇博文中&#xff0c…

C++6.29思维,作业

有以下类定义&#xff0c;按要求实现剩余功能 #include <iostream> using namespace std;class Person { private:int age;int *p; public://无参构造Person():p(new int(89)){age 18;cout << "无参构造" << endl;}//有参构造Person(int age,int …

docker的容器

首先要关闭防火墙,不然会阻止连接 查询防火墙状态 systemctl status firewalld 如果是running的状态要关闭一下 关闭防火墙 systemctl stop firewalld 禁用防火墙(禁止开机启动) systemctl disable firewalld 容器的创建语句: docker run …

第11节 跟上板块轮动的节奏

板块 文章目录 板块什么是板块板块的分类板块的轮动 板块相关接口本节课任务 什么是板块 股票板块是一些具有相同特征的股票的集合&#xff0c;命名通常也会简单明了的直接按照特征命名。例如沪深300板块&#xff0c;蓝筹板块。对上市公司进行“分班”不论是对于企业还是对于投…