P.S игра писалась ради структуры кода,в целях обучения,а не самой игры,
import random as rd import tkinter as tk import tkinter.messagebox as mb class MineField: def __init__(self, size, count_mines): """ создает матрицу с минами,и числом мин вокруг каждой ячейки :param size:размер матрицы :param count_mines: количество мин """ self.coords_mines = self.random_coords(0, size, count_mines) self.matrix = self.get_minefield_matrix(size, self.coords_mines) def random_coords(self, begin, end, count): coords = set() while len(coords) != count: coords.add((rd.randint(begin, end - 1), rd.randint(begin, end - 1))) return coords def get_minefield_matrix(self, size, coords_mines): m = [[0 for _ in range(size)] for _ in range(size)] for r, c in coords_mines: m[r][c] = 'm' out = self.calc_target_around_cell(m, 'm') return out def calc_target_around_cell(self, matrix, target): size = len(matrix) for x in range(size): for y in range(size): for i in range(x - 1, x + 2): if size > i >= 0: for j in range(y - 1, y + 2): if size > j >= 0: if matrix[i][j] == target: if matrix[x][y] == target: continue else: matrix[x][y] += 1 return matrix class Button(tk.Button): def __init__(self, r, c, f1, f2, f3): """ создает кнопку tkinter :param r: координата строки в матрице :param c: координата колонки в матрице :param f1: функция для лкм :param f2: функция для скм :param f3: функция для пкм """ self.default_option = { 'text': '', 'width': 3, 'font': 'Arial 10', 'foreground': 'yellow', 'state': 'normal', 'bg': 'SystemButtonFace', 'relief': 'raised' } super().__init__(**self.default_option) self.coord = r, c self.state = '' self.bind('<ButtonRelease - 1>', lambda e: f1(*self.coord)) self.bind('<ButtonRelease - 3>', lambda e: f2(*self.coord)) self.bind('<ButtonRelease - 2>', lambda e: f3(*self.coord)) self.grid(row=r, column=c) def set_color(self, color): self.config(bg=color) def set_text(self, text): self.config(text=text) def set_fg(self, color): self.config(fg=color) def set_default(self): self.config(self.default_option) class MineClearance: def __init__(self, master, size, mines_count): """ контроллер игры сапер :param master: окно для игры :param size: размер :param mines_count:количество мин """ self.size = size self.mines_count = mines_count self.mf = MineField(self.size, self.mines_count) self.btns = self.create_btn_matrix(self.size) self.flags = self.mines_count self.mines_clear = 0 self.master = master self.master.title(f'flags {self.flags}|mines {self.mines_count}') def create_btn_matrix(self, size): matrix = [[Button(r, c, self.open, self.flag, self.multi_open) for c in range(size)] for r in range(size)] return matrix # левая кнопка мыши def open(self, r, c): btn = self.btns[r][c] value = self.mf.matrix[r][c] if btn.state == 'open' or btn.state == 'flag': return if btn.state == 'ask': btn.config(btn.default_option) btn.state = '' btn.state = 'open' if value == 'm': btn.set_color('red') self.game_over() return True elif value == 0: btn.set_color('green') return self.multi_open(r, c) else: btn.set_color('brown') btn.set_text(value) # средняя кнопка мыши def multi_open(self, r, c): for i in range(r - 1, r + 2): if 0 <= i < self.size: for j in range(c - 1, c + 2): if 0 <= j < self.size: if self.open(i, j): return # правая кнопка мыши def flag(self, r, c): btn = self.btns[r][c] value = self.mf.matrix[r][c] if btn.state == 'open': return if btn.state == 'ask': btn.config(btn.default_option) btn.state = '' elif btn.state != 'flag' and self.flags > 0: btn.set_color('yellow') btn.state = 'flag' self.flags -= 1 if value == 'm': self.mines_clear += 1 if self.mines_clear == self.mines_count: self.win() return elif btn.state == 'flag': btn.config(btn.default_option) btn.state = 'ask' btn.set_text('?') btn.set_fg('black') self.flags += 1 if value == 'm': self.mines_clear -= 1 self.master.title(f'flags {self.flags}|mines {self.mines_count}') def win(self): mb.showinfo("Этап пройден", "Вы выйграли") self.__init__(self.master, self.size, self.mines_count + 1) def game_over(self): mb.showinfo("Взрыв", "Вы проиграли") self.__init__(self.master, self.size, self.mines_count) def main(): root = tk.Tk() MineClearance(root, 10, 15) mb.showinfo("Сапер", """ Разминируйте поле, число в ячейке подскажет вам сколько мин вокруг клетки, чтобы открыть клетку левая кнопка мыши устанавливайте флаг на мину правой кнопкой мыши открыть клетки вокруг клетки - средняя кнопка мыши Будте внимательны,прислушивайтесь к интуиции,первые шаги самые опасные """ ) root.mainloop() if __name__ == '__main__': main()