1. 程式人生 > 程式設計 >python實現掃雷遊戲的示例

python實現掃雷遊戲的示例

掃雷是一款益智類小遊戲,最早於 1992 年由微軟在 Windows 上發行,遊戲適合於全年齡段,規則簡單,即在最短的時間內找出所有非雷格子且在中間過程中不能踩到雷, 踩到雷則失敗,需重新開始。

本文我們使用 Python 來實現掃雷遊戲,主要用的 Python 庫是 pygame。

實現

遊戲組成比較簡單,主要包括:小方格、計時器、地雷等。

首先,我們初始化一些常量,比如:橫豎方塊數、地雷數、滑鼠點選情況等,如下所示:

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 16
# 塊大小
SIZE = 20
# 地雷數
MINE_COUNT = 66
# 未點選
normal = 1
# 已點選
opened = 2
# 地雷
mine = 3
# 標記為地雷
flag = 4
# 標記為問號
ask = 5
# 踩中地雷
bomb = 6
# 被雙擊的周圍
hint = 7
# 正被滑鼠左右鍵雙擊
double = 8
readied = 1,started = 2,over = 3,win = 4

接著定義一個地雷類,類中定義一些基本屬性(如:座標、狀態等)及 get、set 方法,程式碼實現如下:

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 = normal
  self.set_value(value)
 def __repr__(self):
  return str(self._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,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')

再接著定義一個 MineBlock 類,用來處理掃雷的基本邏輯,程式碼實現如下:

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,y):
  return self._block[y][x]
 def open_mine(self,y):
  # 踩到雷了
  if self._block[y][x].value:
   self._block[y][x].status = bomb
   return False
  # 先把狀態改為 opened
  self._block[y][x].status = 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,y):
  if self._block[y][x].around_mine_count == 0:
   return True
  self._block[y][x].status = double
  around = _get_around(x,y)
  # 周圍被標記的雷數量
  sumflag = 0
  for i,j in _get_around(x,y):
   if self._block[j][i].status == 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 == normal:
     if not self.open_mine(i,j):
      result = False
  else:
   for i,j in around:
    if self._block[j][i].status == normal:
     self._block[j][i].status = hint
  return result
 def double_mouse_button_up(self,y):
  self._block[y][x].status = opened
  for i,y):
   if self._block[j][i].status == hint:
    self._block[j][i].status = normal

我們接下來初始化介面,首先生成由小方格組成的面板,主要程式碼實現如下

for row in block.block:
	for mine in row:
		pos = (mine.x * SIZE,(mine.y + 2) * SIZE)
		if mine.status == opened:
			screen.blit(img_dict[mine.around_mine_count],pos)
			opened_count += 1
		elif mine.status == double:
			screen.blit(img_dict[mine.around_mine_count],pos)
		elif mine.status == bomb:
			screen.blit(img_blood,pos)
		elif mine.status == flag:
			screen.blit(img_flag,pos)
			flag_count += 1
		elif mine.status == ask:
			screen.blit(img_ask,pos)
		elif mine.status == hint:
			screen.blit(img0,pos)
		elif game_status == over and mine.value:
			screen.blit(img_mine,pos)
		elif mine.value == 0 and mine.status == flag:
			screen.blit(img_error,pos)
		elif mine.status == normal:
			screen.blit(img_blank,pos)

看一下效果:

python實現掃雷遊戲的示例

再接著新增面板的 head 部分,包括:顯示雷數、重新開始按鈕(笑臉)、顯示耗時,主要程式碼實現如下:

print_text(screen,font1,30,(SIZE * 2 - fheight) // 2 - 2,'%02d' % (MINE_COUNT - flag_count),red)
if game_status == started:
	elapsed_time = int(time.time() - start_time)
print_text(screen,SCREEN_WIDTH - fwidth - 30,'%03d' % elapsed_time,red)
if flag_count + opened_count == BLOCK_WIDTH * BLOCK_HEIGHT:
	game_status = win
if game_status == over:
	screen.blit(img_face_fail,(face_pos_x,face_pos_y))
elif game_status == win:
	screen.blit(img_face_success,face_pos_y))
else:
	screen.blit(img_face_normal,face_pos_y))

看一下效果:

python實現掃雷遊戲的示例

再接著新增各種點選事件,程式碼實現如下:

for event in pygame.event.get():
	if event.type == QUIT:
		sys.exit()
	elif event.type == MOUSEBUTTONDOWN:
		mouse_x,mouse_y = event.pos
		x = mouse_x // SIZE
		y = mouse_y // SIZE - 2
		b1,b2,b3 = pygame.mouse.get_pressed()
		if game_status == started:
			# 滑鼠左右鍵同時按下,如果已經標記了所有雷,則開啟周圍一圈;如果還未標記完所有雷,則有一個周圍一圈被同時按下的效果
			if b1 and b3:
				mine = block.getmine(x,y)
				if mine.status == opened:
					if not block.double_mouse_button_down(x,y):
						game_status = over
	elif event.type == MOUSEBUTTONUP:
		if y < 0:
			if face_pos_x <= mouse_x <= face_pos_x + face_size \
					and face_pos_y <= mouse_y <= face_pos_y + face_size:
				game_status = readied
				block = MineBlock()
				start_time = time.time()
				elapsed_time = 0
				continue
		if game_status == readied:
			game_status = started
			start_time = time.time()
			elapsed_time = 0
		if game_status == started:
			mine = block.getmine(x,y)
			# 按滑鼠左鍵
			if b1 and not b3:
				if mine.status == normal:
					if not block.open_mine(x,y):
						game_status = over
			# 按滑鼠右鍵
			elif not b1 and b3:
				if mine.status == normal:
					mine.status = flag
				elif mine.status == flag:
					mine.status = ask
				elif mine.status == ask:
					mine.status = normal
			elif b1 and b3:
				if mine.status == double:
					block.double_mouse_button_up(x,y)

我們來看一下最終實現效果:

python實現掃雷遊戲的示例

總結

本文我們通過 Python 簡單的實現了掃雷遊戲,大家有興趣的話,可以實際操作一下,看看自己能否排除全部的雷。

完整程式碼

專案地址

以上就是python實現掃雷遊戲的示例的詳細內容,更多關於python 掃雷的資料請關注我們其它相關文章!