蓝桥杯问题 1096: Minesweeper扫雷问题Python版

问题 1096: Minesweeper

题目描述
Minesweeper Have you ever played Minesweeper? This cute little game comes with a certain operating system whose name we can’t remember. The goal of the game is to find where all the mines are located within a M x N field. The game shows a number in a square which tells you how many mines there are adjacent to that square. Each square has at most eight adjacent squares. The 4 x 4 field on the left contains two mines, each represented by a ``*’’ character. If we represent the same field by the hint numbers described above, we end up with the field on the right: … … .… … 100 2210 110 1110

样例输入
4 4
**…
… .
.*…
.
3 5
**…

.*…
0 0
样例输出
Field #1:
*100
2210
1*10
1110

Field #2:
**100
33200
1*100

解题过程:

如果玩过windows里的一个小游戏叫做"挖地雷",那么这个题比较好理解。这个游戏的目的就是要在M*N的地雷区格子中找出所有的地雷。
为了要帮助你玩游戏,这里会在非地雷的格子上有些数字,告诉你与这一个格子邻居其他八个格子中共有多少个地雷。
所以这道题就是通过输入样例,找出每个点周围有多少个地雷(如果是地雷就原样输出地雷),每一个点,除了最边上的四个边的点,其他点均有8个邻居,你就需要判断这八个邻居有多少个是地雷,四个边上的可以使用条件判断一下,也就可以了,
如果[i][j]点是雷,就将跟它相邻的数字均加1

一、输入列表:获取输入的符号

符号输入有行、列,此处用列表来接收。可以将接收过程封装在函数中。
因为同一行一次性输入,Python中默认为将其认定为一个字符串,我们需要将这个字符串进行拆分成单个字符,再将每一行的单个字符追加到列表中

def myList(m):
   ls=[]
   for j in range(m):
       s=input()
       ll=[]
       for i in s:
           ll.append(i)
       ls.append(ll)
   return ls   
二、数字列表:对应每个点值

初始状态应该对应输入列表,除了对应的位置值为’ ,其它的位置初始值均为0

def result(ls):

   rs=ls
   for i in range(len(ls)):
       for j in range(len(ls[i])):
           if ls[i][j]=='*': rs[i][j]='*'
           else: rs[i][j]=0
  return (rs)
三、改变数字列表中的值

通过检查输入列表中[i][j]点是否为雷,即*,来决定相邻的八个点的值是不是要加1
注意一定要进行索引限制,i+1,j-1不能超出上限和下限


def check(m,n,ls):
   for i in range(m):
       for j in range(n):
           if ls[i][j]=='*':
               #rs[i][j]='*'
               if i-1>=0 and j-1>=0 and rs[i-1][j-1]!='*':   rs[i-1][j-1]+=1
               if i-1>=0  and rs[i-1][j]!='*':   rs[i-1][j]+=1   
               if i-1>=0 and j+1<n and rs[i-1][j+1]!='*':   rs[i-1][j+1]+=1
               if j-1>=0 and rs[i][j-1]!='*':     rs[i][j-1]+=1
               if j+1<n and rs[i][j+1]!='*':     rs[i][j+1]+=1    
               if i+1<m and j-1>=0 and rs[i+1][j-1]!='*':  rs[i+1][j-1]+=1
               if i+1<m  and rs[i+1][j]!='*':  rs[i+1][j]+=1   
               if i+1<m and j+1<n and rs[i+1][j+1]!='*':  rs[i+1][j+1]+=1
           else:
               continue
   return rs
四、输出结果

将改变过后的数字列表按要求进行输出。因为是二维列表,需要进行循环嵌套,实现按行输出。

def out(rs):   
   for s in rs :
       for ss in s:
           print(ss,end='')
       print()
五、主程序

数字输入:
输入两个数字,用于控制行数和每行的符号数:m,n=map(int,(input().split()))
定义一个变量K,用于记录输入的次数,也对应到输出的序号
只要输入的两个数值不是0 0,则一直进行循环
在循环体中调用前面定义的各函数。

m,n=map(int,(input().split()))
k=0
while True:
   k=k+1
   if m==0 and n==0:
       break
   else:
       ls=myList(m)
       rs=result(ls)
       rr=check(m,n,ls)
       print('Field #{}:'.format(k))
       out(rs)
       print()
       m,n=map(int,(input().split()))

六、测试结果
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Python扫雷游戏的代码示例,仅供参考: ```python import random # 扫雷游戏类 class Minesweeper: def __init__(self, width=10, height=10, mines=10): self.width = width self.height = height self.mines = mines self.board = [[' ' for _ in range(width)] for _ in range(height)] # 游戏板 self.visible = [[' ' for _ in range(width)] for _ in range(height)] # 显示板 self.gameover = False # 游戏结束标志 # 初始化雷区 self.minefield = [[0 for _ in range(width)] for _ in range(height)] while mines > 0: x, y = random.randint(0, width-1), random.randint(0, height-1) if self.minefield[y][x] == 0: self.minefield[y][x] = 1 mines -= 1 # 获取周围的雷数 def get_adjacent_mines(self, x, y): count = 0 for i in range(max(0, x-1), min(self.width, x+2)): for j in range(max(0, y-1), min(self.height, y+2)): if self.minefield[j][i] == 1: count += 1 return count # 翻开指定位置 def reveal(self, x, y): if self.gameover or self.visible[y][x] != ' ': # 游戏已结束或该位置已翻开 return if self.minefield[y][x] == 1: # 踩雷了,游戏结束 self.gameover = True self.visible[y][x] = 'X' return else: # 翻开该位置,并显示周围的雷数 self.visible[y][x] = str(self.get_adjacent_mines(x, y)) if self.visible[y][x] == '0': # 如果周围没有雷,则递归翻开周围的位置 for i in range(max(0, x-1), min(self.width, x+2)): for j in range(max(0, y-1), min(self.height, y+2)): self.reveal(i, j) # 打印游戏板和显示板 def print_board(self): print(' ' + ' '.join(str(i) for i in range(self.width))) print('-'*(self.width+1)) for i in range(self.height): print(str(i) + '|' + '|'.join(str(c) for c in self.visible[i]) + '|') print('-'*(self.width+1)) # 运行游戏 def run(self): while not self.gameover: self.print_board() x, y = input('请输入要翻开的位置,以逗号分隔:').split(',') self.reveal(int(x), int(y)) self.print_board() print('游戏结束!') # 运行游戏 game = Minesweeper() game.run() ``` 运行示例: ``` 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| | ----------- 4| | ----------- 5| | ----------- 6| | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:4,5 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| | ----------- 4| 1 | ----------- 5| | ----------- 6| | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:4,4 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| | ----------- 4| 1 | ----------- 5| 1 | ----------- 6| | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:3,4 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| 1 | ----------- 4| 1 | ----------- 5| 1 | ----------- 6| | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:4,3 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| 1 | ----------- 4| 1 | ----------- 5| 1 | ----------- 6| 1 | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:5,3 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| 1 | ----------- 4| 2 | ----------- 5| 1 | ----------- 6| 1 | ----------- 7| | ----------- 8| | ----------- 9| | ----------- 请输入要翻开的位置,以逗号分隔:6,3 游戏结束! 0123456789 ----------- 0| | ----------- 1| | ----------- 2| | ----------- 3| 1 | ----------- 4| 2 | ----------- 5| 1 | ----------- 6| X | ----------- 7| | ----------- 8| | ----------- 9| | ----------- ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值