import tkinter as tk
from random import randint
from tkinter import Tk
import random
count = 0
root: Tk = tk.Tk()
moneystring = "Сапёр Количество монет = " + str(count)
root.title(moneystring)
root.geometry('500x500')
ROWS = 10
COLS = 10
MINES = 10
PAL = MINES / 2.5
FLAG = MINES
MON = MINES / 5
buttons = {}
flag = []
mines = []
pal = []
mon = []
mines_placed = 0
for x in range(0, ROWS):
for y in range(0, COLS):
# Каждая кнопка при клике вызывает функцию on_click с её координатами
btn = tk.Button(root, text='', width=2, height=1, command=lambda x=x, y=y: on_click(x, y))
btn.grid(row=x, column=y, sticky=tk.N + tk.W + tk.S + tk.E)
buttons[(x, y)] = btn
def __init__(self, master, ROWS, COLS, mines):
self.ROWS = ROWS
self.COLS = COLS
self.mines = mines
self.tiles = [[None for j in range(COLS)] for i in range(ROWS)]
self.is_mine = [[False for j in range(COLS)] for i in range(ROWS)]
self.is_revealed = [[False for j in range(COLS)] for i in range(ROWS)]
self.is_flagged = [[False for j in range(COLS)] for i in range(ROWS)]
self.num_mines_remaining = mines
self.num_tiles_remaining = ROWS * COLS
self.create_board()
def create_board(self, mines_placed=None):
for row in range(self.ROWS):
for col in range(self.COLS):
self.tiles[ROWS][COLS] = tk.Button(self.master, text="", width=3,
command=lambda row=ROWS, col=COLS: self.handle_click(row, col))
self.tiles[ROWS][COLS].grid(row=ROWS, column=COLS)
# добавляем обработчик событий для правой кнопки мыши
self.tiles[ROWS][COLS].bind("<Button-3>",
lambda e, row=ROWS, col=COLS: self.handle_right_click(row, col))
while mines_placed < self.mines:
row = random.randint(0, self.ROWS - 1)
col = random.randint(0, self.COLS - 1)
if not self.is_mine[row][col]:
self.is_mine[row][col] = True
mines_placed += 1
while len(mines) < MINES:
x, y = randint(0, ROWS - 1), randint(0, COLS - 1)
if (x, y) not in mines:
mines.append((x, y))
while len(mon) < MON:
x, y = randint(0, ROWS - 1), randint(0, COLS - 1)
if (x, y) not in mines:
mon.append((x, y))
def handle_click(self, row, col):
if self.is_flagged[row][col]:
return
if self.is_mine[row][col]:
self.tiles[row][col].config(bg="red", text="*", relief=tk.SUNKEN, state=tk.DISABLED)
self.show_gameover_message()
return
self.reveal_tile(row, col)
if self.num_tiles_remaining == self.mines:
self.show_win_message()
def handle_right_click(self, row, col):
if self.is_revealed[row][col]:
return
if self.is_flagged[row][col]:
self.tiles[row][col].config(text="")
self.is_flagged[row][col] = False
self.num_mines_remaining += 1
else:
self.tiles[row][col].config(text="F")
self.is_flagged[row][col] = True
self.num_mines_remaining -= 1
def on_click(x, y):
if (x, y) in mines:
buttons[(x, y)].config(text='?', background='red')
game_over()
else:
# Подсчет количества мин вокруг выбранной ячейки
count = sum(1 for dx in [-1, 0, 1] for dy in [-1, 0, 1] if (x + dx, y + dy) in mines)
buttons[(x, y)].config(text=str(count))
if (x, y) in mon:
buttons[(x, y)].config(text="?", background="yellow")
count += 1
moneystring = "Сапёр Количество монет = " + str(count)
root.title(moneystring)
def game_over():
# Покраска всех мин в красный
for (x, y) in mines:
buttons[(x, y)].config(text='?', background='red')
for x, y in buttons:
buttons[(x, y)]['state'] = 'disabled'
for (x, y) in mon:
buttons[(x, y)].config(text="?", background="yellow")
for x, y in buttons:
buttons[(x, y)]['state'] = 'disabled'
def restart_game(self):
for row in range(self.ROWS):
for col in range(self.COLS):
self.tiles[row][col].destroy()
self.__init__(self.master, self.ROWS, self.COLS, self.mines)
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)
file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="File", menu=file_menu)
file_menu.add_command(label="Restart", command=lambda: game.restart_game())
file_menu.add_command(label="Exit", command=root.quit)
game = ROWS, COLS, MINES, flag
root.mainloop()