1. 程式人生 > 實用技巧 >使用Python自制掃雷小遊戲

使用Python自制掃雷小遊戲

前言
本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,如有問題請及時聯絡我們以作處理。

PS:如有需要Python學習資料的小夥伴可以加下Python快樂交流群:1136201545

本文例項借鑑mvc模式,核心資料為model,維護1個矩陣,0表無雷,1表雷,-1表已經檢測過。
本例使用python的tkinter做gui,由於沒考慮可用性問題,因此UI比較難看,pygame更有趣更強大更好看,做這些小遊戲更合適,感興趣的讀者可以嘗試一下!

具體的功能程式碼如下:

# -*- coding: utf-8 -*-
import random
import sys
from Tkinter import *
'''
想要學習Python?Python學習交流群:1136201545滿足你的需求,資料都已經上傳群檔案,可以自行下載!
'''
class Model:
  """
  核心資料類,維護一個矩陣
  """
  def __init__(self,row,col):
    self.width=col
    self.height=row
    self.items=[[0 for c in range(col)] for r in range(row)]
 
  def setItemValue(self,r,c,value):
    """
    設定某個位置的值為value
    """
    self.items[r][c]=value;
 
  def checkValue(self,r,c,value):
    """
    檢測某個位置的值是否為value
    """
    if self.items[r][c]!=-1 and self.items[r][c]==value:
      self.items[r][c]=-1 #已經檢測過
      return True
    else:
      return False
     
  def countValue(self,r,c,value):
    """
    統計某個位置周圍8個位置中,值為value的個數
    """
    count=0
    if r-1>=0 and c-1>=0:
      if self.items[r-1][c-1]==1:count+=1
    if r-1>=0 and c>=0:
      if self.items[r-1][c]==1:count+=1
    if r-1>=0 and c+1<=self.width-1:
      if self.items[r-1][c+1]==1:count+=1
    if c-1>=0:
      if self.items[r][c-1]==1:count+=1
    if c+1<=self.width-1 :
      if self.items[r][c+1]==1:count+=1
    if r+1<=self.height-1 and c-1>=0:
      if self.items[r+1][c-1]==1:count+=1
    if r+1<=self.height-1 :
      if self.items[r+1][c]==1:count+=1
    if r+1<=self.height-1 and c+1<=self.width-1:
      if self.items[r+1][c+1]==1:count+=1
    return count
 
   
class Mines(Frame):
  def __init__(self,m,master=None):
    Frame.__init__(self,master)
    self.model=m
    self.initmine()
    self.grid()
    self.createWidgets()
 
  
   
  def createWidgets(self):
    #top=self.winfo_toplevel()
    #top.rowconfigure(self.model.height*2,weight=1)
    #top.columnconfigure(self.model.width*2,weight=1)
    self.rowconfigure(self.model.height,weight=1)
    self.columnconfigure(self.model.width,weight=1)
    self.buttongroups=[[Button(self,height=1,width=2) for i in range(self.model.width)]
              for j in range(self.model.height)]
    for r in range(self.model.width):
      for c in range(self.model.height):
        self.buttongroups[r][c].grid(row=r,column=c)
        self.buttongroups[r][c].bind('<Button-1>',self.clickevent)
        self.buttongroups[r][c]['padx']=r
        self.buttongroups[r][c]['pady']=c
 
  def showall(self):
    for r in range(model.height):
      for c in range(model.width):
        self.showone(r,c)
 
  def showone(self,r,c):
    if model.checkValue(r,c,0):
      self.buttongroups[r][c]['text']=model.countValue(r,c,1)
    else:
      self.buttongroups[r][c]['text']='Mines'
 
  def recureshow(self,r,c):
    if 0<=r<=self.model.height-1 and 0<=c<=self.model.width-1:
      if model.checkValue(r,c,0) and model.countValue(r,c,1)==0:
        self.buttongroups[r][c]['text']=''
        self.recureshow(r-1,c-1)
        self.recureshow(r-1,c)
        self.recureshow(r-1,c+1)
        self.recureshow(r,c-1)
        self.recureshow(r,c+1)
        self.recureshow(r+1,c-1)
        self.recureshow(r+1,c)
        self.recureshow(r+1,c+1)
      elif model.countValue(r,c,1)!=0:
        self.buttongroups[r][c]['text']=model.countValue(r,c,1)
    else:
      pass
         
       
  def clickevent(self,event):
    """
    點選事件
    case 1:是雷,所有都顯示出來,遊戲結束
    case 2:是周圍雷數為0的,遞迴觸發周圍8個button的點選事件
    case 3:周圍雷數不為0的,顯示周圍雷數
    """
    r=int(str(event.widget['padx']))
    c=int(str(event.widget['pady']))
    if model.checkValue(r,c,1):#是雷
      self.showall()
    else:#不是雷
      self.recureshow(r,c)
     
     
  def initmine(self):
    """
    埋雷,每行埋height/width+2個暫定
    """
    r=random.randint(1,model.height/model.width+2)
    for r in range(model.height):
      for i in range(2):
        rancol=random.randint(0,model.width-1)
        model.setItemValue(r,rancol,1)
 
   
  def printf(self):
    """
    列印
    """
    for r in range(model.height):
      for c in range(model.width):
        print model.items[r][c],
      print '/n'
       
 
def new(self):
  """
  重新開始遊戲
  """
  pass
 
if __name__=='__main__':
  model=Model(10,10)
  root=Tk()
   
  #menu
  menu = Menu(root)
  root.config(menu=menu)
  filemenu = Menu(menu)
  menu.add_cascade(label="File", menu=filemenu)
  filemenu.add_command(label="New",command=new)
  filemenu.add_separator()
  filemenu.add_command(label="Exit", command=root.quit)
 
  #Mines
  m=Mines(model,root)
  #m.printf()
  root.mainloop()