Вот моя игра «Сапёр», и я хочу, чтобы пользователь вошел в систему перед запуском игры. Я попытался создать фрейм с аутентификацией, и он работает, но я не понимаю, как изменить вид с аутентификации на игру. Я не хочу, чтобы вы анализировали игровую логику, а только то, как обрабатывать смену экрана.
Код:
Код: Выделить всё
from random import shuffle
import tkinter as tk
from tkinter import messagebox
import sqlite3
colors = {
1: "green",
2: "dark orange",
3: "dark blue",
4: "light blue",
5: "light braun",
6: "light green",
7: "dakr yellow",
8: "dakr pink",
}
class Authentication(tk.Frame):
def __init__(self, root, on_login):
super().__init__(root)
self.root = root
self.on_login = on_login
self.root.title("Authentication")
self.__authenticated = False
self.conn = sqlite3.connect("users.db")
self.cursor = self.conn.cursor()
# Creating the users table if it doesn't exist
self.cursor.execute(
"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT)"
)
username_label = tk.Label(self.root, text="Username:")
username_label.grid(row=0, column=0, padx=10, pady=10)
self.username_entry = tk.Entry(self.root)
self.username_entry.grid(row=0, column=1, padx=10, pady=10)
password_label = tk.Label(self.root, text="Password:")
password_label.grid(row=1, column=0, padx=10, pady=10)
self.password_entry = tk.Entry(self.root, show="*")
self.password_entry.grid(row=1, column=1, padx=10, pady=10)
login_button = tk.Button(self.root, text="Login", command=self.login)
login_button.grid(row=2, column=0, padx=10, pady=10, columnspan=2, sticky="WE")
register_button = tk.Button(self.root, text="Register", command=self.register)
register_button.grid(
row=3, column=0, padx=10, pady=10, columnspan=2, sticky="WE"
)
def login(self):
username = self.username_entry.get()
password = self.password_entry.get()
self.cursor.execute(
"SELECT * FROM users WHERE username=? AND password=?", (username, password)
)
if self.cursor.fetchone():
self.__authenticated = True
messagebox.showinfo("Success", "Login successful!")
self.on_login()
else:
messagebox.showerror("Failure", "Invalid username or password!")
self.username_entry.delete(0, tk.END)
self.password_entry.delete(0, tk.END)
def register(self):
username = self.username_entry.get()
password = self.password_entry.get()
self.cursor.execute("SELECT * FROM users WHERE username=?", (username,))
if self.cursor.fetchone():
messagebox.showerror("Failure", "Username already exists!")
else:
self.cursor.execute(
"INSERT INTO users (username, password) VALUES (?, ?)",
(username, password),
)
self.conn.commit()
messagebox.showinfo("Success", "Registration successful!")
self.username_entry.delete(0, tk.END)
self.password_entry.delete(0, tk.END)
def is_authenticated(self):
return self.__authenticated
class MyButton(tk.Button):
def __init__(self, master, x, y, number=0, *args, **kwargs):
super().__init__(master, width=5, font="Calibri 15 bold", *args, **kwargs)
self.x = x
self.y = y
self.number = number
self.is_mine = False
self.count_bomb = 0
self.is_open = False
def __repr__(self):
return f"MyButton{self.x} {self.y} {self.number} {self.is_mine}"
class MineSweeper:
ROW = 9
COLUMNS = 9
MINES = 10
IS_GAME_OVER = False
IS_FIRST_CLICK = True
def __init__(self, root):
self.root = root
self.buttons = []
self.authentication = Authentication(root, on_login=self.start_game)
for i in range(MineSweeper.ROW + 2):
temp = []
for j in range(MineSweeper.COLUMNS + 2):
btn = MyButton(root, x=i, y=j)
btn.config(command=lambda button=btn: self.click(button))
btn.bind("", self.right_click)
temp.append(btn)
self.buttons.append(temp)
def right_click(self, event):
if MineSweeper.IS_GAME_OVER:
return
cur_btn = event.widget
if cur_btn["state"] == "normal":
cur_btn["state"] = "disabled"
cur_btn["text"] = "🏲"
cur_btn["disabledforeground"] = "dark red"
elif cur_btn["text"] == "🏲":
cur_btn["text"] = ""
cur_btn["state"] = "normal"
def click(self, clicked_button: MyButton):
if MineSweeper.IS_GAME_OVER:
return
if MineSweeper.IS_FIRST_CLICK:
self.insert_mines(clicked_button.number)
self.count_mines_in_buttons()
self.print_buttons()
MineSweeper.IS_FIRST_CLICK = False
if clicked_button.is_mine:
clicked_button.config(
text="*", background="red", disabledforeground="black"
)
clicked_button.is_open = True
MineSweeper.IS_GAME_OVER = True
messagebox.showinfo("Game over", "Ви програли")
for i in range(1, MineSweeper.ROW + 1):
for j in range(1, MineSweeper.COLUMNS + 1):
btn = self.buttons[i][j]
if btn.is_mine:
btn["text"] = "*"
else:
color = colors.get(clicked_button.count_bomb, "black")
if clicked_button.count_bomb:
clicked_button.config(
text=clicked_button.count_bomb, disabledforeground=color
)
clicked_button.is_open = True
else:
self.breadth_first_search(clicked_button)
clicked_button.config(state="disabled")
clicked_button.config(relief=tk.SUNKEN)
# check if the player won the game
no_of_closed_buttons = 0
for i in range(1, MineSweeper.ROW + 1):
for j in range(1, MineSweeper.COLUMNS + 1):
if not self.buttons[i][j].is_open:
no_of_closed_buttons += 1
if no_of_closed_buttons == MineSweeper.MINES:
MineSweeper.IS_GAME_OVER = True
messagebox.showinfo("Congratulations", "Ви виграли!")
def breadth_first_search(self, btn: MyButton):
queue = [btn]
while queue:
cur_btn = queue.pop()
color = colors.get(cur_btn.count_bomb, "black")
if cur_btn.count_bomb:
cur_btn.config(text=cur_btn.count_bomb, disabledforeground=color)
else:
cur_btn.config(text="", disabledforeground=color)
cur_btn.is_open = True
cur_btn.config(state="disabled")
cur_btn.config(relief=tk.SUNKEN)
if cur_btn.count_bomb == 0:
x, y = cur_btn.x, cur_btn.y
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
# if not abs(dx - dy) == 1:
# continue
next_btn = self.buttons[x + dx][y + dy]
if (
not next_btn.is_open
and 1
Подробнее здесь: [url]https://stackoverflow.com/questions/76279874/how-to-handle-multiple-views-in-tkinterpython[/url]