如何用python编一个扫雷游戏_用 Python 做一个 Windows 扫雷游戏
原標題:用 Python 做一個 Windows 掃雷游戲
本文代碼基于 python3.6 和 pygame1.9.4。
Windows XP 上的掃雷是無數(shù)80/90后的集體回憶,今天我們就用 Python 來制作一個高仿版的 掃雷游戲。
原諒我手殘,掃雷基本就沒贏過,測試的時候我是偷偷的把雷的數(shù)量從99改到50才贏了。。。
下面將一下我的實現(xiàn)邏輯。
首先,如何表示雷和非雷,一開始想的是,建立一個二維數(shù)組表示整個區(qū)域,0表示非地雷,1表示地雷。后來一想不對,還有標記為地雷,標記為問號,還有表示周邊雷數(shù)的數(shù)字,好多狀態(tài),干脆就做個類吧:
classBlockStatus(Enum):
normal = 1# 未點擊
opened = 2# 已點擊
mine = 3# 地雷
flag = 4# 標記為地雷
ask = 5# 標記為問號
bomb = 6# 踩中地雷
hint = 7# 被雙擊的周圍
double = 8# 正被鼠標左右鍵雙擊
classMine:
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):
returnstr(self._value)
# return f'({self._x},{self._y})={self._value}, status={self.status}'
defget_x(self):
returnself._x
defset_x(self, x):
self._x = x
x = property(fget=get_x, fset=set_x)
defget_y(self):
returnself._y
defset_y(self, y):
self._y = y
y = property(fget=get_y, fset=set_y)
defget_value(self):
returnself._value
defset_value(self, value):
ifvalue:
self._value = 1
else:
self._value = 0
value = property(fget=get_value, fset=set_value, doc= '0:非地雷 1:雷')
defget_around_mine_count(self):
returnself._around_mine_count
defset_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= '四周地雷數(shù)量')
defget_status(self):
returnself._status
defset_status(self, value):
self._status = value
status = property(fget=get_status, fset=set_status, doc= 'BlockStatus')
布雷就很簡單了,隨機取99個數(shù),從上往下順序排就是了:
classMineBlock:
def__init__(self):
self._block = [[Mine(i, j) fori inrange(BLOCK_WIDTH)] forj inrange(BLOCK_HEIGHT)]
# 埋雷
fori inrandom.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):
self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1
我們點擊一個格子的時候,只要根據(jù)點擊的坐標,找到對應(yīng)的 Mine,看它的值是多少,就知道有沒有踩中雷了。
如果沒踩中雷的話,要計算周邊8個位置中有幾個雷,以便顯示對應(yīng)的數(shù)字。
如果周邊有雷,那么顯示數(shù)字,這個簡單,可是如果周邊沒有雷,那就要顯示一片區(qū)域,直到有雷出現(xiàn),如下圖,我只點了當中一下,就出現(xiàn)了那么大一片區(qū)域
這個計算其實也容易,只要用遞歸就可以了,如果計算出周圍的雷數(shù)為0,則 遞歸計算周邊8個位置的四周雷數(shù),直到雷數(shù)不為0。
classMineBlock:
defopen_mine(self, x, y):
# 踩到雷了
ifself._block[y][x].value:
self._block[y][x].status = BlockStatus.bomb
returnFalse
# 先把狀態(tài)改為 opened
self._block[y][x].status = BlockStatus.opened
around = _get_around(x, y)
_sum = 0
fori, j inaround:
ifself._block[j][i].value:
_sum += 1
self._block[y][x].around_mine_count = _sum
# 如果周圍沒有雷,那么將周圍8個未中未點開的遞歸算一遍
# 這就能實現(xiàn)一點出現(xiàn)一大片打開的效果了
if_sum == 0:
fori, j inaround:
ifself._block[j][i].around_mine_count == -1:
self.open_mine(i, j)
returnTrue
def_get_around(x, y):
"""返回(x, y)周圍的點的坐標"""
# 這里注意,range 末尾是開區(qū)間,所以要加 1
return[(i, j) fori inrange(max( 0, x - 1), min(BLOCK_WIDTH - 1, x + 1) + 1)
forj inrange(max( 0, y - 1), min(BLOCK_HEIGHT - 1, y + 1) + 1) ifi != x orj != y]
接下來還有一個麻煩的地方,我們經(jīng)常鼠標左右鍵同時按下,如果雷被全部標記,則會一下子打開周圍所有的格子,如果其中有標記錯的,那么不好意思,GAME OVER。
如果沒有全標記完,會有一個效果顯示周圍一圈未被打開和標記的格子
classMineBlock:
defdouble_mouse_button_down(self, x, y):
ifself._block[y][x].around_mine_count == 0:
returnTrue
self._block[y][x].status = BlockStatus.double
around = _get_around(x, y)
sumflag = 0# 周圍被標記的雷數(shù)量
fori, j in_get_around(x, y):
ifself._block[j][i].status == BlockStatus.flag:
sumflag += 1
# 周邊的雷已經(jīng)全部被標記
result = True
ifsumflag == self._block[y][x].around_mine_count:
fori, j inaround:
ifself._block[j][i].status == BlockStatus.normal:
ifnotself.open_mine(i, j):
result = False
else:
fori, j inaround:
ifself._block[j][i].status == BlockStatus.normal:
self._block[j][i].status = BlockStatus.hint
returnresult
defdouble_mouse_button_up(self, x, y):
self._block[y][x].status = BlockStatus.opened
fori, j in_get_around(x, y):
ifself._block[j][i].status == BlockStatus.hint:
self._block[j][i].status = BlockStatus.normal
掃雷的主要邏輯就這么多,剩下來的就是一些雜七雜八的事件了。當然,這些雜七雜八的事件也還是夠你折騰一番的。
我們的代碼里已經(jīng)給大家完善并提供了相關(guān)的圖片資源供使用。 獲取源代碼,請在公眾號對話里回復(fù)關(guān)鍵字 掃雷
作者:丹楓無跡
責任編輯:
總結(jié)
以上是生活随笔為你收集整理的如何用python编一个扫雷游戏_用 Python 做一个 Windows 扫雷游戏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.7Web前端基础笔记
- 下一篇: python后端接收数据_python后