最快的扫雷记录,初级只需要0.49秒,一眨眼就结束的操作!

使用Python的pygame库制作扫雷游戏,代码基于Python 3.6。游戏界面仿XP风格,通过创建类来表示不同状态的格子,随机布雷并判断点击是否踩中。点击无雷区域会递归展开直到遇到雷,同时处理鼠标左右键操作,展示扫雷核心逻辑。
摘要由CSDN通过智能技术生成

这次我们基于 pygame 来做一个扫雷,上次有朋友问我代码的 python 版本,我说明一下,我所有的代码都是基于 python 3.6 的。

先看截图,仿照 XP 上的扫雷做的,感觉 XP 上的样式比 win7 上的好看多了。

原谅我手残,扫雷基本就没赢过,测试的时候我是偷偷的把雷的数量从99改到50才赢了。。。

下面将一下我的实现逻辑。

首先,如何表示雷和非雷,一开始想的是,建立一个二维数组表示整个区域,0表示非地雷,1表示地雷。后来一想不对,还有标记为地雷,标记为问号,还有表示周边雷数的数字,好多状态,干脆就做个类吧

class BlockStatus(Enum):
    normal = 1  # 未点击
    opened = 2  # 已点击
    mine = 3    # 地雷
    flag = 4    # 标记为地雷
    ask = 5   # 标记为问号
    bomb = 6    # 踩中地雷
    hint = 7    # 被双击的周围
    double = 8  # 正被鼠标左右键双击
class Mine:
    def __init__(self, x, y, value=0):
        self._x = x
        self._y = y
        self._value = 0
        self._around_mine_count = -1
        self._status = BlockStatus.normal
        self.set_value(value)
    def __repr__(self):
        return str(self._value)
        # return f'({self._x},{self._y})={self._value}, status={self.status}'
    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, doc='0:非地雷 1:雷')
    def get_around_mine_count(self):
        return self._around_mine_count
    def set_around_mine_count(self, around_mine_count):
        self._around_mine_count = around_mine_count
    around_mine_count = property(fget=get_around_mine_count, fset=set_around_mine_count, doc='四周地雷数量')
    def get_status(self):
        return self._status
    def set_status(self, value):
        self._status = value
    status = property(fget=get_status, fset=set_status, doc='BlockStatus')

布雷就很简单了,随机取99个数,从上往下顺序排就是了。

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 = 1

我们点击一个格子的时候,只要根据点击的坐标,找到对应的 Mine,看它的值是多少,就知道有没有踩中雷了。

如果没踩中雷的话,要计算周边8个位置中有几个雷,以便显示对应的数字。

如果周边有雷,那么显示数字,这个简单,可是如果周边没有雷,那就要显示一片区域,直到有雷出现,如下图,我只点了当中一下,就出现了那么大一片区域。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值