Python Forum
Adding the timer, smiley face, and flags in Minesweeper.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Adding the timer, smiley face, and flags in Minesweeper.
#6
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()
Reply


Messages In This Thread
RE: Adding the timer, smiley face, and flags in Minesweeper. - by deanhystad - May-04-2021, 10:20 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Adding timer on the Messagebox aniyanetworks 6 11,562 Feb-13-2019, 07:48 PM
Last Post: aniyanetworks
  Python minesweeper game gtk3 get label value after click lukassz 0 3,231 Mar-25-2017, 08:14 PM
Last Post: lukassz

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020