529. 扫雷游戏

题目来源:力扣(LeetCode)

https://leetcode-cn.com/problems/minesweeper

题目

让我们一起来玩扫雷游戏!

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

给定一个代表游戏板的二维字符矩阵。 M 代表一个 未挖出 的地雷, E 代表一个 未挖出 的空方块, B 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出 的空白方块, 数字('1' 到 '8')表示有多少地雷与这块 已挖出 的方块相邻, X 则表示一个 已挖出 的地雷。

现在给出在所有 未挖出 的方块中( M 或者 E )的下一个点击位置(行和列索引),根据以下规则,返回相应位置被点击后对应的面板:

  1. 如果一个地雷( M )被挖出,游戏就结束了- 把它改为  X 。
  2. 如果一个没有相邻地雷的空方块( E )被挖出,修改它为( B ),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。
  3. 如果一个 至少与一个地雷相邻 的空方块( E )被挖出,修改它为 数字 ('1'到'8'),表示相邻地雷的数量。
  4. 如果在此次点击中,若无更多方块可被揭露,则返回面板。

示例 1:

输入:[['E', 'E', 'E', 'E', 'E'],['E', 'E', 'M', 'E', 'E'],['E', 'E', 'E', 'E', 'E'],['E', 'E', 'E', 'E', 'E']]Click : [3,0]输出:[['B', '1', 'E', '1', 'B'],['B', '1', 'M', '1', 'B'],['B', '1', '1', '1', 'B'],['B', 'B', 'B', 'B', 'B']]解释:

示例 2:

输入:[['B', '1', 'E', '1', 'B'],['B', '1', 'M', '1', 'B'],['B', '1', '1', '1', 'B'],['B', 'B', 'B', 'B', 'B']]Click : [1,2]输出:[['B', '1', 'E', '1', 'B'],['B', '1', 'X', '1', 'B'],['B', '1', '1', '1', 'B'],['B', 'B', 'B', 'B', 'B']]解释:

注意:

  1. 输入矩阵的宽和高的范围为 [1,50]。
  2. 点击的位置只能是未被挖出的方块 ('M' 或者 'E'),这也意味着面板至少包含一个可点击的方块。
  3. 输入面板不会是游戏结束的状态(即有地雷已被挖出)。
  4. 简单起见,未提及的规则在这个问题中可被忽略。例如,当游戏结束时你不需要挖出所有地雷,考虑所有你可能赢得游戏或标记方块的情况。

以上图源均来自力扣(LeetCode)

解题思路

思路:模拟(DFS、BFS)

题目中给出 4 项规则,那么我们就根据这个规则去模拟,那么这里分情况来讨论:

以下 相邻 包括上,下,左,右,和所有4个对角线

  • 当点击的是 未挖出的地雷 (M),那么根据规则一,将其修改为 X;
  • 当点击的是 未挖出的方块 (E),这里要分情况讨论

    • 根据规则三,如果当前点击方块相邻未挖出的方块中含有地雷,那么统计地雷数,将当前方块改为数字(对应地雷数)
    • 根据规则二,如果当前点击方块相邻方块不含地雷,那么将当前方块修改为 B,然后向相邻的方块继续搜索。

那么这里我们可以使用深度优先搜索(DFS)、广度优先搜索(BFS)的思路来实现。

深度优先搜索

按照上面的分析,使用 DFS 的思路解决,不再赘述。

具体代码见【代码实现 # DFS】

广度优先搜索

这里需要注意,因为一个方块可能由其他方块延伸到达,为了避免重复将某个方块对应的坐标重复添加到队列中,这里需要进行标记。

具体代码见【代码实现 # BFS】

代码实现

# DFS
class Solution:def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:# 定义 8 个方位dx = [-1, -1, -1, 0, 1, 1, 1, 0] dy = [-1, 0, 1, 1, 1, 0, -1, -1]m = len(board)n = len(board[0])def in_board(x, y):"""判断坐标是否在限定边界内"""return 0 <= x < m and 0 <= y < ndef dfs(x, y):count = 0# 先判断相邻(8 个方位)的方块是否含有地雷for i in range(8):nx = x + dx[i]ny = y + dy[i]# 如果相邻方块都在限定范围内,且含有地雷,统计地雷数if in_board(nx, ny) and board[nx][ny] == 'M':count += 1if count > 0:# 含有地雷,修改当前点为数字对应地雷数,返回board[x][y] = str(count)return# 如果相邻方块不含地雷,修改为 'B'# 并向相邻位置扩散搜索board[x][y] = 'B'for i in range(8):nx = x + dx[i]ny = y + dy[i]if in_board(nx, ny) and board[nx][ny] == 'E':dfs(nx, ny)x, y = click# 如果当前点击的是未挖出的地雷,那么将其修改为 'X',返回if board[x][y] == 'M':board[x][y] = 'X'else:# 当点击的是未挖出的方块,分情况讨论dfs(x, y)return board# BFS
class Solution:def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:# 定义 8 个方位dx = [-1, -1, -1, 0, 1, 1, 1, 0] dy = [-1, 0, 1, 1, 1, 0, -1, -1]m = len(board)n = len(board[0])def in_board(x, y):"""判断坐标是否在限定边界内"""return 0 <= x < m and 0 <= y < ndef bfs(x, y):# 这里要注意一个点可能由其他点延伸到达,要注意标记,防止重复入队signed = [[False] * n for _ in range(m)]# 标记起始点signed[x][y] = Truefrom collections import dequequeue = deque()# 先将起始点入队queue.append([x, y])while queue:count = 0x, y = queue.popleft()# 如果直接点击的是地雷,修改当前方块为 'X',直接返回if board[x][y] == 'M':board[x][y] = 'X'return# 否则判断 8 个方位,先看是否有地雷for i in range(8):nx = x + dx[i]ny = y + dy[i]if in_board(nx, ny) and board[nx][ny] == 'M':count += 1if count > 0:# 当存在地雷时,修改当前点为数字,对应地雷数board[x][y] = str(count)else:# 先修改当前方块修改为 'B'board[x][y] = 'B'# 不存在地雷时,将周围的方块标记入队,继续搜索for i in range(8):nx = x + dx[i]ny = y + dy[i]# 当方块未标记,且在边界内,加入队列,并且标记if in_board(nx, ny) and signed[nx][ny] != True:queue.append([nx, ny])signed[nx][ny] = Truex, y = clickbfs(x, y)return board

实现结果

利用Python来玩扫雷,极致的思维体验相关推荐

  1. python扫雷脚本_利用 Python 实现 自动扫雷 小脚本

    原标题:利用 Python 实现 自动扫雷 小脚本 自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式.一.准备工作1.扫雷游戏 我是 ...

  2. python自动扫雷_利用Python实现自动扫雷

    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式. 一.准备工作 我的版本是 python 3.6.1 python的第三方库: w ...

  3. python自动卸载win程序_利用python实现自动扫雷程序

    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式. 一.准备工作 1.扫雷游戏 我是win10,没有默认的扫雷,所以去扫雷网下载 h ...

  4. python扫雷 高级算法_利用Python实现自动扫雷

    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式. 一.准备工作 我的版本是 python 3.6.1 python的第三方库: w ...

  5. 利用Python实现自动扫雷小脚本

    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式. 代码已上传至GitHub: https://github.com/chestnu ...

  6. python扫雷脚本_利用Python实现自动扫雷小脚本

    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式. 代码已上传至GitHub: https://github.com/chestnu ...

  7. 利用python爬取京东华为旗舰店手机信息(价格、型号、颜色、链接等)

    目 录 第一章.前言 1.1.效果展示 1.2.需要用到的库 1.3.原理分析 第二章.代码分开讲解 2.1.对象的定义及初始化 2.1.1.第一至二行 2.1.2.第三至四行 2.1.3.第五至六行 ...

  8. 利用python爬虫与数据分析,打造最强玩法,轻松成为大神级玩家!

    前言: 最近迷上了一款游戏,但是作为一名程序员的我是不可能只玩游戏的,我必须把它的官网数据采集下来! 环境: windows python3.6.5 模块: requests jsonpath pyg ...

  9. 整理总结:利用Python进行数据分析及思维导图

    参考资料:机械工业出版社的<利用Python进行数据分析>(思维导图在最后面) 本篇目录 参考资料:机械工业出版社的<利用Python进行数据分析>(思维导图在最后面) 第一章 ...

最新文章

  1. 决策树(chap3)Machine Learning In Action学习笔记
  2. 自己动手搭建Git服务器-SCM-Manager
  3. skinmagic对VC中程序窗口的换肤
  4. 蓝桥杯 BASIC-10 基础练习 十进制转十六进制
  5. 垃圾回收机制,是不是这样理解?
  6. Facebook是如何大幅提升TLS连接效率的?
  7. jquery匹配不区分大小写_jQuery实现contains方法不区分大小写的方法教程
  8. IMO FTPC Part 3-A、B和F级分隔耐火性能测试
  9. [玩转BLE]瑞昱RTL8762CMF蓝牙5.0(烧录篇)
  10. SSH2(Struts2、Spring3与Hibernate3)的整合
  11. Ubuntu 搭建opengrok 流程
  12. 区块链技术应用到现实场景中,是个什么样?
  13. 壕无人性!有公司年终奖发了50个月薪水?!
  14. DUTOJ-1205: 对圣杯宝具的威力值
  15. IP更新、释放、清除DNS的详细操作方法
  16. 计算机二级office模拟操作试题,计算机二级Office模拟试题及答案
  17. 在 vs code 中使用 go 插件时相关工具的正确安装方式
  18. 初中英语多词性单词怎么办_初中英语单词十大分类 你掌握多少?
  19. socket udp java_JAVA Socket之UDP | 学步园
  20. total recorder 注册码

热门文章

  1. 数据结构与算法-索引1909
  2. mysql-表关系模型,一对一,一对多,多对多
  3. Object类入门这一篇就够了!
  4. [转]IT开发工程师的悲哀
  5. C语言博客作业06--结构体文件
  6. Redis+Twemproxy安装与使用
  7. fastjson把对象转化成json避免$ref
  8. linux文件目录与管理
  9. 部署SCVMM2012 SP1 集群(1)---部署AD
  10. Internet路由结构学习心得二:通告汇聚和具体路由影响AS入流量