Python实现扫雷游戏,代码示例,边玩边学+回忆童年!

文章目录

  • 前言
  • 实现
  • 总结
      • 关于Python技术储备
        • 一、Python所有方向的学习路线
        • 二、Python基础学习视频
        • 三、精品Python学习书籍
        • 四、Python工具包+项目源码合集
        • ①Python工具包
        • ②Python实战案例
        • ③Python小游戏源码
        • 五、面试资料
        • 六、Python兼职渠道


前言

扫雷是一款益智类小游戏,最早于 1992 年由微软在 Windows 上发行,游戏适合于全年龄段,规则简单,即在最短的时间内找出所有非雷格子且在中间过程中不能踩到雷, 踩到雷则失败,需重新开始。

本文我们使用 Python 来实现扫雷游戏,主要用的 Python 库是 pygame。
在这里插入图片描述


实现

游戏组成比较简单,主要包括:小方格、计时器、地雷等。

首先,我们初始化一些常量,比如:横竖方块数、地雷数、鼠标点击情况等,如下所示:

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 16
# 块大小
SIZE = 20
# 地雷数
MINE_COUNT = 66
# 未点击
normal = 1
# 已点击
opened = 2
# 地雷
mine = 3
# 标记为地雷
flag = 4
# 标记为问号
ask = 5
# 踩中地雷
bomb = 6
# 被双击的周围
hint = 7
# 正被鼠标左右键双击
double = 8
readied = 1,
started = 2,
over = 3,
win = 4

接着定义一个地雷类,类中定义一些基本属性(如:坐标、状态等)及 get、set 方法,代码实现如下:

class Mine:def __init__(self, x, y, value=0):self._x = xself._y = yself._value = 0self._around_mine_count = -1self._status = normalself.set_value(value)def __repr__(self):return str(self._value)def get_x(self):return self._xdef set_x(self, x):self._x = xx = property(fget=get_x, fset=set_x)def get_y(self):return self._ydef set_y(self, y):self._y = yy = property(fget=get_y, fset=set_y)def get_value(self):return self._valuedef set_value(self, value):if value:self._value = 1else:self._value = 0value = property(fget=get_value, fset=set_value, doc='0:非地雷 1:雷')def get_around_mine_count(self):return self._around_mine_countdef set_around_mine_count(self, around_mine_count):self._around_mine_count = around_mine_countaround_mine_count = property(fget=get_around_mine_count, fset=set_around_mine_count, doc='四周地雷数量')def get_status(self):return self._statusdef set_status(self, value):self._status = valuestatus = property(fget=get_status, fset=set_status, doc='BlockStatus')

再接着定义一个 MineBlock 类,用来处理扫雷的基本逻辑,代码实现如下:

class MineBlock:def __init__(self):self._block = [[Mine(i, j) for i in range(BLOCK_WIDTH)] for j in range(BLOCK_HEIGHT)]# 埋雷for i in random.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1def get_block(self):return self._blockblock = property(fget=get_block)def getmine(self, x, y):return self._block[y][x]def open_mine(self, x, y):# 踩到雷了if self._block[y][x].value:self._block[y][x].status = bombreturn False# 先把状态改为 openedself._block[y][x].status = openedaround = _get_around(x, y)_sum = 0for i, j in around:if self._block[j][i].value:_sum += 1self._block[y][x].around_mine_count = _sum# 如果周围没有雷,那么将周围 8 个未中未点开的递归算一遍if _sum == 0:for i, j in around:if self._block[j][i].around_mine_count == -1:self.open_mine(i, j)return Truedef double_mouse_button_down(self, x, y):if self._block[y][x].around_mine_count == 0:return Trueself._block[y][x].status = doublearound = _get_around(x, y)# 周围被标记的雷数量sumflag = 0for i, j in _get_around(x, y):if self._block[j][i].status == flag:sumflag += 1# 周边的雷已经全部被标记result = Trueif sumflag == self._block[y][x].around_mine_count:for i, j in around:if self._block[j][i].status == normal:if not self.open_mine(i, j):result = Falseelse:for i, j in around:if self._block[j][i].status == normal:self._block[j][i].status = hintreturn resultdef double_mouse_button_up(self, x, y):self._block[y][x].status = openedfor i, j in _get_around(x, y):if self._block[j][i].status == hint:self._block[j][i].status = normal

我们接下来初始化界面,首先生成由小方格组成的面板,主要代码实现如下

for row in block.block:for mine in row:pos = (mine.x * SIZE, (mine.y + 2) * SIZE)if mine.status == opened:screen.blit(img_dict[mine.around_mine_count], pos)opened_count += 1elif mine.status == double:screen.blit(img_dict[mine.around_mine_count], pos)elif mine.status == bomb:screen.blit(img_blood, pos)elif mine.status == flag:screen.blit(img_flag, pos)flag_count += 1elif mine.status == ask:screen.blit(img_ask, pos)elif mine.status == hint:screen.blit(img0, pos)elif game_status == over and mine.value:screen.blit(img_mine, pos)elif mine.value == 0 and mine.status == flag:screen.blit(img_error, pos)elif mine.status == normal:screen.blit(img_blank, pos)

看一下效果:
在这里插入图片描述
再接着添加面板的 head 部分,包括:显示雷数、重新开始按钮(笑脸)、显示耗时,主要代码实现如下:

print_text(screen, font1, 30, (SIZE * 2 - fheight) // 2 - 2, '%02d' % (MINE_COUNT - flag_count), red)
if game_status == started:elapsed_time = int(time.time() - start_time)
print_text(screen, font1, SCREEN_WIDTH - fwidth - 30, (SIZE * 2 - fheight) // 2 - 2, '%03d' % elapsed_time, red)
if flag_count + opened_count == BLOCK_WIDTH * BLOCK_HEIGHT:game_status = win
if game_status == over:screen.blit(img_face_fail, (face_pos_x, face_pos_y))
elif game_status == win:screen.blit(img_face_success, (face_pos_x, face_pos_y))
else:screen.blit(img_face_normal, (face_pos_x, face_pos_y))

看一下效果:
在这里插入图片描述
再接着添加各种点击事件,代码实现如下:

for event in pygame.event.get():if event.type == QUIT:sys.exit()elif event.type == MOUSEBUTTONDOWN:mouse_x, mouse_y = event.posx = mouse_x // SIZEy = mouse_y // SIZE - 2b1, b2, b3 = pygame.mouse.get_pressed()if game_status == started:# 鼠标左右键同时按下,如果已经标记了所有雷,则打开周围一圈;如果还未标记完所有雷,则有一个周围一圈被同时按下的效果if b1 and b3:mine = block.getmine(x, y)if mine.status == opened:if not block.double_mouse_button_down(x, y):game_status = overelif event.type == MOUSEBUTTONUP:if y < 0:if face_pos_x <= mouse_x <= face_pos_x + face_size \and face_pos_y <= mouse_y <= face_pos_y + face_size:game_status = readiedblock = MineBlock()start_time = time.time()elapsed_time = 0continueif game_status == readied:game_status = startedstart_time = time.time()elapsed_time = 0if game_status == started:mine = block.getmine(x, y)# 按鼠标左键if b1 and not b3:if mine.status == normal:if not block.open_mine(x, y):game_status = over# 按鼠标右键elif not b1 and b3:if mine.status == normal:mine.status = flagelif mine.status == flag:mine.status = askelif mine.status == ask:mine.status = normalelif b1 and b3:if mine.status == double:block.double_mouse_button_up(x, y)

我们来看一下最终实现效果:
在这里插入图片描述


总结

本文我们通过 Python 简单的实现了扫雷游戏,大家有兴趣的话,可以实际操作一下,看看自己能否排除全部的雷。


关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉CSDN大礼包:《Python入门资料&实战源码&安装工具】免费领取安全链接,放心点击

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、Python基础学习视频

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~在这里插入图片描述
在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述
因篇幅有限,仅展示部分资料

三、精品Python学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、Python工具包+项目源码合集
①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

六、Python兼职渠道

而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
在这里插入图片描述
在这里插入图片描述
这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode刷题-双指针】--80.删除有序数组中的重复项II

80.删除有序数组中的重复项II 方法&#xff1a;双指针 因为给定数组是有序的&#xff0c;所以相同元素必然连续&#xff0c;使用双指针解决&#xff0c;遍历数组检查每一个元素是否应该被保留&#xff0c;如果应该保留&#xff0c;就将其移动到指定位置。我们定义两个指针slow…

【Java0基础学Java第八颗】 -- 继承与多态 -- 多态

8.继承与多态 8.2 多态8.2.1 多态的概念8.2.2 多态实现条件8.2.3 重写8.2.4 向上转型和向下转型8.2.5 向下转型8.2.6 多态的优缺点8.2.7 避免在构造方法中调用重写的方法 8.2 多态 8.2.1 多态的概念 通俗来说就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当…

ZYNQ_project:ram_dual_port

伪双端口ram&#xff1a;写端口&#xff1a;clk_w,en_A,we_A,addr_A,din_A;读端口:clk_r,en_B,addr_B;dout_B. 设计读写模块&#xff0c;写入256个数据&#xff0c;再读出256个数据。 输入时钟100Mhz&#xff0c;输出时钟50Mhz。 多bit数据&#xff0c;高速时钟域到低速时钟…

做一个springboot登陆注册功能

目录 一、环境搭建 1、数据库 2、引入依赖 3、配置信息 4、创建包结构和数据库实体类 二、接口开发-注册接口 前提准备 响应数据 需求分析 全局异常处理 代码编写 测试 三、接口开发-登录接口 前提准备 响应数据 需求分析 代码编写 测试 拦截器 测试 一、环…

字典管理怎么使用,vue3项目使用若依的的字典管理模块

若依框架数据字典的使用_若依数据字典_哈哈水水水水的博客-CSDN博客 【精选】关于数据字典的理解与设计_数据字典怎么设计-CSDN博客 若依的字典值如何使用&#xff08;超详细图文教程&#xff09;_若依字典管理_丿BAIKAL巛的博客-CSDN博客 Vue3组合式API&#xff1a;getCurr…

行业追踪,2023-11-13

自动复盘 2023-11-13 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

CentOs7 NAT模式连接网络

1.配置动态网络 1.1 检查主机网卡配置 检查主机的网络设置 进入控制面板&#xff0c;找到网络共享中心 查看适配器是否都已经开启 1.2 设置虚拟机的网络配置 打开虚拟机网络配置设置&#xff0c;对网卡VMnet8 进行设置 记住网关 全部选择应用&#xff0c;确定 1.3 设置…

您的计算机已被Mallox勒索病毒感染?恢复您的数据的方法在这里!

尊敬的读者&#xff1a; 随着科技的迅速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒是一种极具威胁性的恶意软件。在这些勒索病毒中&#xff0c;.mallox 勒索病毒尤为突出&#xff0c;它能够加密用户的数据文件&#xff0c;要求支付赎金才能解密。本文将介…

【Python基础】一个简单的TCP通信程序

&#x1f308;欢迎来到Python专栏 &#x1f64b;&#x1f3fe;‍♀️作者介绍&#xff1a;前PLA队员 目前是一名普通本科大三的软件工程专业学生 &#x1f30f;IP坐标&#xff1a;湖北武汉 &#x1f349; 目前技术栈&#xff1a;C/C、Linux系统编程、计算机网络、数据结构、Mys…

从0开始python学习-34.pytest常用插件

目录 1. pytest-html&#xff1a;生成HTML测试报告 2.pytest-xdist&#xff1a;并发执行用例 3. pytest-order&#xff1a;自定义用例的执行顺序 4. pytest-rerunfailures&#xff1a;用例失败时自动重试 5. pytest-result-log:用例执行结果记录到日志文件 1. pytest-html…

STM32笔记—USART

课外知识插入&#xff1a;STM32单片机extern全局变量_stm32全局变量-CSDN博客 如果你把temple定义在A中&#xff0c;然后让A.h和B.h包含在includes.h中&#xff0c;然后把includes.h放在A.c和B.c中单个编译是没有问题的&#xff0c;但是链接的时候会出现问题&#xff0c; “S…

Rust编程中的共享状态并发执行

1.共享状态并发 虽然消息传递是一个很好的处理并发的方式&#xff0c;但并不是唯一一个。另一种方式是让多个线程拥有相同的共享数据。在学习Go语言编程过程中大家应该听到过一句口号:"不要通过共享内存来通讯"。 在某种程度上&#xff0c;任何编程语言中的信道都类…