python实现扫雷,不一样的体验!

扫雷

新人博主,学习python一个多月,请大家多多关照,不足之处,敬请雅正。

准备工作

下载制作扫雷游戏所需要的一些图片,如数字0-8,雷等。
链接: link.

设计原理

定义一个类block_condition用来判断方块的状态。再用个类Mine返回方块的性质:坐标,是否为雷,周边雷的数量。类mine_block用来埋地雷和点击的效果,点到雷,返回False,没点到雷就点开这个方块,如果点击的方块周边无雷,则向周围递归打开,可以实现一点就是一片的效果。判断游戏胜利的标志为:点开的方块加地雷数等于总数,失败的标志为:踩到地雷。

实施步骤

1.定义一个类用来表示方块的状态

我们都知道扫雷是个鼠标操作的游戏,每个小方块都有不同的状态,仅对鼠标而言,就有被点击、未被点击,右键一次、两次,被点击的方块也有踩中地雷和没有踩中。这么多状态,一个个声明有些麻烦,索性将其封装到一个类里,方便调用。

class Block_Condition():
    unclicked = 1  # 未点击
    clicked = 2  # 已点击
    mine = 3    # 地雷
    flag = 4    # 标记为地雷
    ask = 5   # 标记为问号
    bomb = 6    # 踩中地雷

2.再定义一个类用来获取坐标,周边地雷的数量,方块的状态

鼠标点击,如何知道点击的是哪个方块,这就需要知道每个方块的坐标。点击下去,究竟是不是雷呢,那就还需要一个变量来确定是否是雷,此处,用x,y来表示坐标,value的值表示是否是地雷,0表示不是,1表示是,正好对应了布尔代数式的取值,方便程序编译理解。此处把周边地雷的数量设置成-1而非0,是因为如果设置成0,那根据游戏的原理,就直接向旁边递归打开了,那点一下,所有方块都要被点击了,游戏就不用玩了。在这个类中,condition对应了上一个类,用来存储方块的状态,我们依据方块的状态才能进行游戏,加载图片,判断胜利与否。

from block_condition import *

class Mine:
    def __init__(self, x, y, value=0):
        self._x = x
        self._y = y
        self._value = 0
        self._surround_count = -1 #周边雷的数量
        self._condition = Block_Condition.unclicked #初始设置为未点击
        self.set_value(value)

    def get_x(self):
        return self._x #直接传入
    def set_x(self, x):
        self._x = x #输入
    x = property(fget=get_x, fset=set_x) 

    def get_y(self):
        return self._y
    def set_y(self, y):
        self._y = y
    y = property(fget=get_y, fset=set_y)

    def get_value(self):
        return self._value
    def set_value(self, value):
        if value:
            self._value = 1 #是地雷
        else:
            self._value = 0 #不是雷
    value = property(fget=get_value, fset=set_value)

    def get_surround_count(self): #获取周边雷的数量
        return self._surround_count
    def set_surround_count(self, surround_count):
        self._surround_count = surround_count
    surround_count = property(fget=get_surround_count, fset=set_surround_count)

    def get_condition(self): #方块的状态
        return self._condition
    def set_condition(self, value):
        self._condition = value
    condition = property(fget=get_condition, fset=set_condition)

3.随机生成地雷,递归打开周边无雷的方块

要想实现扫雷,每个方块都得是一个类,包含其坐标,自身的状态(是否是雷或是周边有多少地雷),所以需要定义一个二维数组list_mine,每个元素都是Mine类。而要想实现一点开就是一片的效果,则需要函数返回某个方块周边的方块,我们用函数get_around来返回某一方块周边的方块。如果方块旁边的地雷数量为0,那就向周边打开(只打开周边没有地雷的方块),形成一点就是一片的效果。游戏可以从代码里调整方块和地雷的数量来改变难度。
初始化只要将每个方块都变成Mine类就行,将二维数组list_mine赋值给block即可。埋下地雷用random.sample,从指定序列中随机获取指定长度的片段,在此呢,就是把被系统随机选中的block的value变成1,即将其变成地雷。

import random
import time
from Mine import *
from block_condition import *
BLOCK_WIDTH=30
BLOCK_HEIGHT=20
MINE_COUNT=99 #地雷数量

list_mine=[[]]
list_mine=[[Mine(i,j) for i in range(BLOCK_WIDTH)] for j in range(BLOCK_HEIGHT)]
def get_around(x, y):
    #返回(x, y)周围一圈的点
        return [(i, j) for i in range(max(0, x - 1), min(BLOCK_WIDTH - 1, x + 1) + 1) #range是左闭右开
                for j in range(max(0, y - 1), min(BLOCK_HEIGHT - 1, y + 1) + 1) ]
class Mine_Block:
    def __init__(self):
        self._block = list_mine

        # 埋下地雷的种子
        for i in random.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):
            self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1
    def getblock(self, x, y):
        return self._block[y][x]
    def open_block(self, x, y):
        # 真不幸,这是颗地雷
        if self._block[y][x].value:
            self._block[y][x].condition = Block_Condition.bomb
            return False

        self._block[y][x].condition = Block_Condition.clicked #没踩雷

        around = get_around(x, y)

        sum1 = 0
        for i, j in around:
            if self._block[j][i].
  • 18
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
### 回答1: 扫雷是一个经典的小游戏,以下是一个简单的Python实现: ```python import random # 初始化游戏棋盘 def init_board(width, height, mines): board = [[0 for i in range(width)] for j in range(height)] for i in range(mines): x = random.randint(0, width - 1) y = random.randint(0, height - 1) while board[y][x] == -1: x = random.randint(0, width - 1) y = random.randint(0, height - 1) board[y][x] = -1 for i in range(height): for j in range(width): if board[i][j] == -1: continue count = 0 if i > 0 and j > 0 and board[i - 1][j - 1] == -1: count += 1 if i > 0 and board[i - 1][j] == -1: count += 1 if i > 0 and j < width - 1 and board[i - 1][j + 1] == -1: count += 1 if j > 0 and board[i][j - 1] == -1: count += 1 if j < width - 1 and board[i][j + 1] == -1: count += 1 if i < height - 1 and j > 0 and board[i + 1][j - 1] == -1: count += 1 if i < height - 1 and board[i + 1][j] == -1: count += 1 if i < height - 1 and j < width - 1 and board[i + 1][j + 1] == -1: count += 1 board[i][j] = count return board # 显示游戏棋盘 def show_board(board, status): for i in range(len(board)): for j in range(len(board[i])): if status[i][j] == 0: print('_', end=' ') elif status[i][j] == 1: if board[i][j] == -1: print('*', end=' ') elif board[i][j] == 0: print(' ', end=' ') else: print(board[i][j], end=' ') else: print('F', end=' ') print() # 游戏主循环 def main_loop(width, height, mines): board = init_board(width, height, mines) status = [[0 for i in range(width)] for j in range(height)] show_board(board, status) while True: x = int(input('请输入要翻开的格子的横坐标:')) y = int(input('请输入要翻开的格子的纵坐标:')) if board[y][x] == -1: print('你输了!') status[y][x] = 1 show_board(board, status) break else: status[y][x] = 1 show_board(board, status) ``` 你可以通过调用 `main_loop()` 函数来开始游戏,需要输入游戏棋盘的宽度、高度和雷的数量。在游戏中,你需要输入要翻开的格子的坐标,程序会自动进行处理并显示游戏棋盘。 ### 回答2: 扫雷是一个非常经典的游戏,Python可以很方便地实现扫雷游戏。 首先,我们可以创建一个二维列表作为游戏的棋盘,每个元素代表一个方块。我们可以用数字来表示每个方块的状态,比如0表示未点击过的空白方块,-1表示雷,1到8表示周围雷的数量。 接下来,我们需要实现一些函数来实现游戏的逻辑。例如,当玩家点击一个方块时,需要判断点击的方块是否是雷,如果是雷,则游戏结束,玩家失败;如果不是雷,则需要计算周围雷的数量,并显示在点击的方块上。当玩家点击一个空白方块时,需要递归地显示周围的方块,直到遇到有雷的方块为止。 另外,我们还需要实现一些辅助函数来生成雷的位置,以及判断游戏是否胜利等。 总结起来,实现扫雷游戏的关键步骤包括创建棋盘、处理玩家的点击事件、递归显示周围的方块、判断游戏是否胜利等。 Python的语法和数据结构非常适合实现扫雷游戏,而且Python还有很多库可以用来实现界面的绘制和交互。通过使用适当的数据结构和算法,我们可以很方便地实现一个简单而有趣的扫雷游戏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值