May-04-2021, 10:20 PM
(This post was last modified: May-04-2021, 10:20 PM by deanhystad.)
For a timer you'll need a periodic event. For something like this the easiest way to do something periodically is use the "after()" method. Here I added a status line to the bottom of the window which is updated every second to show elapsed time.
import random import time import datetime import tkinter as tk from tkinter import messagebox class Cell(tk.Button): """A button for the Minsweeper game. Press me to reveal a bomb or information about surrounding bombs. """ def __init__(self, parent, row, column, count): super().__init__(parent, text=' ', width=2, relief=tk.RAISED, command=self.press) self.parent = parent self.row = row self.column = column self.count = count self.pressed = False self.flagged = False self.bind("<Button-3>", self.flag) def press(self): """Button pressed. Show bomb info""" if not self.pressed: self.configure(relief=tk.SUNKEN) self.pressed = False self['text'] = 'X' if self.count < 0 else str(self.count) self.parent.clear_cell(self) def flag(self, _): """Right mouse button pressed. Toggle flag marker""" if not self.pressed: self.flagged = not self.flagged self['text'] = 'F' if self.flagged else ' ' class Board(tk.Frame): """Map for Minesweeper game. I make a grid of buttons that are pressed to reveal bombs or information about surrounding bombs. """ def __init__(self, parent, rows, columns, bomb_count): super().__init__(parent) self.safe_count = rows * columns - bomb_count # Make map of all the bombs bombs = [[0]*columns for row in range(rows)] for bomb in random.choices(range(rows*columns), k=bomb_count): bombs[bomb // columns][bomb % columns] = 1 # Make the board map self.cells = [] for row in range(rows): for column in range(columns): # Count bombs in surrounding cells. Use -1 to indicate cell has bomb if bombs[row][column]: count = -1 else: count = sum([bombs[r][c] for r in range(max(0, row-1), min(rows, row+2)) \ for c in range(max(0, column-1), min(columns, column+2))]) cell = Cell(self, row, column, count) cell.grid(row=row, column=column) self.cells.append(cell) # Add status display to bottom of window self.done = False self.status = tk.Label(parent, text='') self.status.grid(row=rows, column=0, columnspan=columns) self.start_time = time.time() self.update_status() def clear_cell(self, cell): """Cell was selected""" if cell.count < 0: self.done = True messagebox.showinfo('Game Over', 'Today marks the passing of you') else: self.safe_count -= 1 if self.safe_count <= 0: self.done = True messagebox.showinfo('Game Over', 'Winner, winner, chicken dinner!') def update_status(self): """Update status display""" delta = str(datetime.timedelta(seconds=int(time.time() - self.start_time))) self.status['text'] = f'{delta} Remaining {self.safe_count}' if not self.done: self.after(1000, self.update_status) # Run again after 1 second root = tk.Tk() root.title("Minesweeper") root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) board = Board(root, 20, 20, 30) board.grid(column=0, row=0, sticky='NEWS') root.mainloop()