|
扫雷游戏 python实现
借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过。
第一次使用python 的tkinter做gui,从构思到实现,基本1天时间,真是感慨python优越性。
还没考虑可用性问题,UI比较难看,pygame更有趣更强大更好看,做这些小游戏更合适。
- # -*- coding: utf-8 -*-
- import random
- import sys
- from Tkinter import *
-
- 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()
|
|