python实现扫雷小游戏的方法-创新互联

这篇文章主要讲解了python实现扫雷小游戏的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

创新互联专注于松溪网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供松溪营销型网站建设,松溪网站制作、松溪网页设计、松溪网站官网定制、微信小程序开发服务,打造松溪网络公司原创品牌,更为您提供松溪网站排名全网营销落地服务。

构建地雷区

import random
from enum import Enum

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 16
SIZE = 20   # 块大小
MINE_COUNT = 99  # 地雷数


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')


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

 def get_block(self):
  return self._block

 block = 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 = BlockStatus.bomb
   return False

  # 先把状态改为 opened
  self._block[y][x].status = BlockStatus.opened

  around = _get_around(x, y)

  _sum = 0
  for i, j in around:
   if self._block[j][i].value:
    _sum += 1
  self._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 True

 def double_mouse_button_down(self, x, y):
  if self._block[y][x].around_mine_count == 0:
   return True

  self._block[y][x].status = BlockStatus.double

  around = _get_around(x, y)

  sumflag = 0  # 周围被标记的雷数量
  for i, j in _get_around(x, y):
   if self._block[j][i].status == BlockStatus.flag:
    sumflag += 1
  # 周边的雷已经全部被标记
  result = True
  if sumflag == self._block[y][x].around_mine_count:
   for i, j in around:
    if self._block[j][i].status == BlockStatus.normal:
     if not self.open_mine(i, j):
      result = False
  else:
   for i, j in around:
    if self._block[j][i].status == BlockStatus.normal:
     self._block[j][i].status = BlockStatus.hint
  return result

 def double_mouse_button_up(self, x, y):
  self._block[y][x].status = BlockStatus.opened
  for i, j in _get_around(x, y):
   if self._block[j][i].status == BlockStatus.hint:
    self._block[j][i].status = BlockStatus.normal


def _get_around(x, y):
 """返回(x, y)周围的点的坐标"""
 # 这里注意,range 末尾是开区间,所以要加 1
 return [(i, j) for i in range(max(0, x - 1), min(BLOCK_WIDTH - 1, x + 1) + 1)
   for j in range(max(0, y - 1), min(BLOCK_HEIGHT - 1, y + 1) + 1) if i != x or j != y]

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前名称:python实现扫雷小游戏的方法-创新互联
标题网址:http://scyanting.com/article/dsojdo.html