Advertisement
here2share

# Tk_minesweeper.py ^ 2018.10

Oct 27th, 2018
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.93 KB | None | 0 0
  1. # Tk_minesweeper.py
  2.  
  3. from random import *
  4. from time import *
  5. from Tkinter import *
  6. import tkSimpleDialog, tkMessageBox
  7. from PIL import *
  8.  
  9. INSTRUCTIONS = '''This is a single-player puzzle. \n\nThe objective of the game is to clear the board which contains hidden "mines" without detonating any of them with help from clues about the number of neighboring mines in each field.'''
  10.  
  11. def how2play():
  12.     tkMessageBox.showinfo("Tk MineSweeper", INSTRUCTIONS)
  13. 0
  14. def get_neighbours(cell):
  15.     row_id, col_id = cell
  16.     SURROUNDING = ((-1, -1), (-1,  0), (-1,  1),
  17.                    (0 , -1), (0 ,  0), (0 ,  1),
  18.                    (1 , -1), (1 ,  0), (1 ,  1))
  19.     zzz = [(row_id + surr_row, col_id + surr_col) for (surr_row, surr_col) in SURROUNDING]
  20.     return [z for z in zzz if z in cv.btn]
  21. 0
  22. def secs():
  23.     if curr and cv.go is 'active':
  24.         s = str(int((time()-curr)*10)*0.1)+'s'
  25.         cv.secs['text'] = s
  26. 0
  27. def create_board():
  28.     btn = cv.btn
  29.     cv.safe = [(r,c) for r in range(rrr) for c in range(ccc)]
  30.     btn['restart'] = Button(frame,text='Restart',bg='lightblue',command=restart)
  31.     btn['restart'].grid(row=0,column=ccc-2,columnspan=2,sticky=EW)
  32.     Radiobutton(variable=vvv,val='10 10 16',command=setgame).grid(row=1,column=0)
  33.     Radiobutton(variable=vvv,val='16 16 56',command=setgame).grid(row=1,column=1)
  34.     Radiobutton(variable=vvv,val='18 18 80',command=setgame).grid(row=1,column=2)
  35.     Checkbutton(variable=chkbtn,command=custom).grid(row=1,column=3)
  36.     Button(frame,text='(i)',bg='lightblue',command=how2play).grid(row=1,column=ccc-1,sticky=EW)
  37.     cv.secs = Label(fg='red',font=('Arial Narrow',16))
  38.     cv.secs.grid(row=0,column=ccc-5,columnspan=3,sticky=E)
  39.     cv.secs['text'] = '0.0s'
  40.     for r in range(rrr):
  41.         for c in range(ccc):
  42.             btn[(r,c)]=Button(frame,compound=TOP,width=25,height=25,image=btnSize,command=get_move((r,c)))
  43.             btn[(r,c)].grid(row=r+2,column=c,sticky=EW)
  44.             btn[(r,c)]['text']='%s'%(r*rrr+c%ccc+1)
  45.             btn[(r,c)]['bg']='darkgray'
  46.             btn[(r,c)]['fg']='black'
  47.     corners = [(0,0),(0,ccc-1),(rrr-1,0),(rrr-1,ccc-1)]
  48.     for z in corners:
  49.         btn[z]['bg']='yellow'
  50.         for cell in get_neighbours(z):
  51.             cv.safe.remove(cell)
  52.     m = mines
  53.     while m:
  54.         cell = choice(cv.safe)
  55.         if len([z for z in get_neighbours(cell) if z in loc_mines]) < 5:
  56.             loc_mines.append(cell)
  57.             hints(cell)
  58.             m -= 1
  59.         cv.safe.remove(cell)
  60.     root.deiconify()
  61. 0
  62. def custom():
  63.     if chkbtn.get():
  64.         Entry(textvariable=ent).grid(row=1,column=4,columnspan=4,sticky=EW)
  65.         setgame()
  66.         ent.set(cv.ent)
  67.     else:
  68.         oFrame()
  69. 0
  70. def setgame():
  71.     if chkbtn.get():
  72.         t = [int(z) for z in ent.get().split()]
  73.         if len(t) != 3:
  74.             t = [int(z) for z in cv.ent.split()]
  75.         r,c,m = t
  76.         r = max(10,min(r,18))
  77.         c = max(10,min(c,18))
  78.         rc_min,rc_max = 10,int((r*c)*0.36)
  79.         m = min(rc_max,m)
  80.         m = max(rc_min,m)
  81.         cv.ent = ' '.join([str(z) for z in [r,c,m]])
  82.         return r,c,m
  83.     else:
  84.         return oFrame()
  85. 0
  86. def oFrame():
  87.     r,c,m = cv.lv = [int(z) for z in vvv.get().split()]
  88.     t = '{}x{}: {} mines'.format(r,c,m)
  89.     Label(text=t,font=('Arial Narrow',14)).grid(row=1,column=4,columnspan=4,sticky=EW)
  90.     return r,c,m
  91. 0
  92. def hints(cell):
  93.     for z in get_neighbours(cell):
  94.         if z in cv.hints:
  95.             cv.hints[z] += 1
  96.         else:
  97.             cv.hints[z] = 1
  98. 0
  99. def restart():
  100.     cv.go = 'init'
  101.     root.update()
  102.     if chkbtn.get():
  103.         setgame()
  104.         cv.lv = cv.ent
  105. 0
  106. def get_clue():
  107.     if curr and cv.go is 'active':
  108.         c = int(clue['text'].split()[1])
  109.         if c:
  110.             clue['text'] = 'Clues: '+str(c-1)
  111.             cv.cell = choice(cv.safe)
  112.             cv.safe.remove(cv.cell)
  113.         if c is 1:
  114.             clue['bg']='red'
  115.             clue['fg']='white'
  116. 0
  117. def chgflag():
  118.     try:
  119.         flag
  120.     except:
  121.         return
  122.     if 'Off' in flag['text']:
  123.         flag['text']='Flag On'
  124.         flag['bg']='green'
  125.         flag['fg']='black'
  126.     else:
  127.         flag['text']='Flag Off'
  128.         flag['bg']='red'
  129.         flag['fg']='white'
  130. 0
  131. def get_move(rc=0):
  132.     def wrap():
  133.         cv.cell = rc
  134.     return wrap
  135. 0
  136. class Cv: 0
  137. cv = Cv()
  138. cv.cell = None
  139. cv.go = "init"
  140. cv.ent = '12 12 36'
  141. cv.lv = '10 10 16'
  142. cv.secs = {}
  143. cv.safe = []
  144. root = []
  145. while cv.go:
  146.     cell = cv.cell
  147.     if cv.go is 'init':
  148.         if root:
  149.             root.destroy()
  150.             root.mainloop() # to completely remove all remnants of deleted root
  151.         root = Tk()
  152.         root.title('Tk MineSweeper')
  153.         root.withdraw()
  154.         vvv = StringVar()
  155.         ent = StringVar()
  156.         chkbtn = IntVar()
  157.         chkbtn.set(0)
  158.         if ' ' not in cv.lv:
  159.             cv.lv = ' '.join([str(z) for z in cv.lv])
  160.         vvv.set(cv.lv)
  161.         frame=Frame().grid()
  162.         btnSize = PhotoImage()
  163.         loc_mines = []
  164.         clue=Button(frame,text='Clues: 5',bg='green',command=get_clue)
  165.         clue.grid(row=0,columnspan=2,sticky=EW)
  166.         '''
  167.         flag=Button(frame,command=chgflag)
  168.         flag.grid(row=0,columnspan=2,sticky=EW)
  169.         chgflag()
  170.         '''
  171.         cv.btn = {}
  172.         cv.hints = {}
  173.         curr = 0
  174.         rrr,ccc,mines = setgame()
  175.         create_board()
  176.         cv.go = 'active'
  177.     if cv.go is 'active':
  178.         if cell:
  179.             cv.cell = None
  180.             btn = cv.btn
  181.             if cell in loc_mines:
  182.                 for z in loc_mines:
  183.                     btn[z]['text']='O'
  184.                     btn[z]['font'] = ('Arial',21,'bold')
  185.                     btn[z]['fg']='white'
  186.                     btn[z]['bg']='orange'
  187.                     btn[z].config(relief=SUNKEN)
  188.                 btn[cell]['text']='X'
  189.                 btn[cell]['bg']='red'
  190.                 cv.go = 'inactive'
  191.             else:
  192.                 surr = get_neighbours(cell)
  193.                 for z in surr:
  194.                     if z not in (loc_mines+list(cv.hints)):
  195.                         if z in cv.safe:
  196.                             cv.safe.remove(z)
  197.                         btn[z]['text'] = ' '
  198.                         btn[z].config(relief=SUNKEN)
  199.                         btn[z]['bg'] = 'lightgray'
  200.                 if cell in cv.hints:
  201.                     btn[cell]['text'] = cv.hints[cell]
  202.                     btn[cell]['font'] = ('Arial',18,'bold')
  203.                     btn[cell].config(relief=SUNKEN)
  204.                     btn[cell]['bg'] = 'lightgray'
  205.                     btn[cell]['fg'] = 'blue'
  206.                     if cell in cv.safe:
  207.                         cv.safe.remove(cell)
  208.                 if not len(cv.safe):
  209.                     cv.go = 'inactive'
  210.                     for z in loc_mines:
  211.                         btn[z]['text']='O'
  212.                         btn[z]['font'] = ('Arial',21,'bold')
  213.                         btn[z]['fg']='white'
  214.                         btn[z]['bg']='green'
  215.                         btn[z].config(relief=SUNKEN)
  216.             if not curr:
  217.                 curr = time()
  218.             # print [r*rrr+c%ccc+1 for r,c in cv.safe[:20]]
  219.             # print len(cv.safe)
  220.         secs()
  221.     try:
  222.         root.update()
  223.     except: break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement