diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc index 3b44c60..36ca5eb 100644 Binary files a/__pycache__/config.cpython-313.pyc and b/__pycache__/config.cpython-313.pyc differ diff --git a/assets/background.png b/assets/background.png new file mode 100644 index 0000000..77fd3ed Binary files /dev/null and b/assets/background.png differ diff --git a/assets/bone.png b/assets/bone.png new file mode 100644 index 0000000..a42994f Binary files /dev/null and b/assets/bone.png differ diff --git a/assets/dogs/Chihuahua.png b/assets/dogs/Chihuahua.png new file mode 100644 index 0000000..95324a8 Binary files /dev/null and b/assets/dogs/Chihuahua.png differ diff --git a/assets/dogs/Corgi.png b/assets/dogs/Corgi.png new file mode 100644 index 0000000..d10a6ae Binary files /dev/null and b/assets/dogs/Corgi.png differ diff --git a/assets/dogs/Golden_Retriever.png b/assets/dogs/Golden_Retriever.png new file mode 100644 index 0000000..d2ad479 Binary files /dev/null and b/assets/dogs/Golden_Retriever.png differ diff --git a/assets/dogs/Husky.png b/assets/dogs/Husky.png new file mode 100644 index 0000000..1977b7b Binary files /dev/null and b/assets/dogs/Husky.png differ diff --git a/assets/dogs/Pomeranian.png b/assets/dogs/Pomeranian.png new file mode 100644 index 0000000..eeb1161 Binary files /dev/null and b/assets/dogs/Pomeranian.png differ diff --git a/assets/dogs/Pug.png b/assets/dogs/Pug.png new file mode 100644 index 0000000..dfcfd68 Binary files /dev/null and b/assets/dogs/Pug.png differ diff --git a/assets/dogs/Yorkshire_Terrier.png b/assets/dogs/Yorkshire_Terrier.png new file mode 100644 index 0000000..31c9290 Binary files /dev/null and b/assets/dogs/Yorkshire_Terrier.png differ diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..de57dd2 Binary files /dev/null and b/assets/logo.png differ diff --git a/config.py b/config.py index b790cde..79e6719 100644 --- a/config.py +++ b/config.py @@ -6,7 +6,7 @@ ADMIN_BUTTON_TEXT_COLOR = "#ffffff" ADMIN_FONT = ("Comic Sans MS", 25) ADMIN_BIG_FONT = ("Comic Sans MS", 40) -# Интерфейс пользователя +# Интерфейс пользователя (АВТОРИЗАЦИЯ) BACKGROUND_COLOR = "#f8e1e1" PRIMARY_COLOR = "#ff6347" BUTTON_COLOR = "#87ceeb" @@ -14,6 +14,26 @@ BUTTON_TEXT_COLOR = "white" FONT = ("Comic Sans MS", 25) BIG_FONT = ("Comic Sans MS", 40) +# ГЛАВНОЕ МЕНЮ +BACKGROUND_COLOR_USER = "#bcabe5" # Основной фон +TOP_PANEL_COLOR_USER = "#aa9bcd" # Цвет верхней панели +BUTTON_COLOR_PROFILE_USER = "#a2c792" # Цвет кнопок "Профиль", "Магазин", "База знаний" +BUTTON_COLOR_PLAY_USER = "#b4e1a1" # Цвет кнопки "Играть" +BUTTON_COLOR_EXIT_USER = "#a2c792" # Цвет кнопки "Выход" +BUTTON_TEXT_COLOR_USER = "white" # Цвет текста на кнопках +FONT_USER = ("Comic Sans MS", 20) # Шрифт для текста кнопок +BIG_FONT_USER = ("Comic Sans MS", 30) # Большой шрифт (например, для заголовков) +BUTTON_RADIUS_USER = 50 # Радиус круглой кнопки +EXIT_BUTTON_SIZE_USER = (80, 40) # Размер кнопки "Выход" +TOP_PANEL_COLOR = "#BBA0D0" +BUTTON_COLOR_PROFILE = "#8FC085" +BUTTON_COLOR_PLAY = "#8FC085" +BUTTON_COLOR_EXIT = "#8FC085" +# Размеры +PLAY_BUTTON_RADIUS = 100 +EXIT_BUTTON_WIDTH = 100 +EXIT_BUTTON_HEIGHT = 50 + # Данные для авторизации администратора ADMIN_LOGIN = "admin" ADMIN_PASSWORD = "admin123" @@ -23,23 +43,78 @@ DATABASE_URL = "sqlite:///database/DogAcademy.db" # Обновлено на п # Иконки SETTINGS_IMG = "assets/settings.png" +LOGO = "F:/Projects/Dog_Academy/assets/logo.png" +BACKGROUND_GAME = "F:/Projects/Dog_Academy/assets/background.png" +BONE = "F:/Projects/Dog_Academy/assets/bone.png" + +# Собаки +CHIHUAHUA = "F:/Projects/Dog_Academy/assets/dogs/Chihuahua.png" +CORGI = "F:/Projects/Dog_Academy/assets/dogs/Corgi.png" +RETRIEVER = "F:/Projects/Dog_Academy/assets/dogs/Golden_Retriever.png" +HUSKY = "F:/Projects/Dog_Academy/assets/dogs/Husky.png" +POMERANIAN = "F:/Projects/Dog_Academy/assets/dogs/Pomeranian.png" +PUG = "F:/Projects/Dog_Academy/assets/dogs/Pug.png" +YORKSHIRE = "F:/Projects/Dog_Academy/assets/dogs/Yorkshire_Terrier.png" + +DOG_CHARACTERS = { + "Chihuahua": { + "image": CHIHUAHUA, + "speed": 8, + "endurance": 5, + "special_ability": "Fast Dodge", # Уклонение от препятствий + }, + "Corgi": { + "image": CORGI, + "speed": 6, + "endurance": 7, + "special_ability": "Extra Jump", # Дополнительный прыжок + }, + "Golden Retriever": { + "image": RETRIEVER, + "speed": 7, + "endurance": 8, + "special_ability": "Bonus Points", # Увеличенные очки за правильные ответы + }, + "Husky": { + "image": HUSKY, + "speed": 9, + "endurance": 6, + "special_ability": "Speed Boost", # Ускорение + }, + "Pomeranian": { + "image": POMERANIAN, + "speed": 7, + "endurance": 4, + "special_ability": "Charm", # Уменьшает штраф за ошибки + }, + "Pug": { + "image": PUG, + "speed": 5, + "endurance": 9, + "special_ability": "Resilience", # Сохраняет здоровье при столкновениях + }, + "Yorkshire Terrier": { + "image": YORKSHIRE, + "speed": 6, + "endurance": 5, + "special_ability": "Quick Recovery", # Быстрое восстановление характеристик + }, +} # Утилиты NOTIFICATION_LEVEL = "info" # Возможные значения: "info", "warning", "error" USE_DATABASE_LOGS = True -# ГЛАВНОЕ МЕНЮ -BACKGROUND_COLOR_USER = "#bcabe5" # Основной фон -TOP_PANEL_COLOR_USER = "#aa9bcd" # Цвет верхней панели -BUTTON_COLOR_PROFILE_USER = "#a2c792" # Цвет кнопок "Профиль", "Магазин", "База знаний" -BUTTON_COLOR_PLAY_USER = "#b4e1a1" # Цвет кнопки "Играть" -BUTTON_COLOR_EXIT_USER = "#a2c792" # Цвет кнопки "Выход" +# Игровые параметры +INITIAL_SCORE = 5 # Начальные очки игрока +POINTS_CORRECT_ANSWER = 2 # Очки за правильный ответ +POINTS_WRONG_ANSWER = -1 # Штраф за неправильный ответ +MAX_LEVELS = 100 # Максимальное количество уровней +INITIAL_DOG_STATUS = {"health": 100, "hunger": 0, "sleepiness": 0} # Стартовые характеристики собаки -# Текст и шрифты -BUTTON_TEXT_COLOR_USER = "white" # Цвет текста на кнопках -FONT_USER = ("Comic Sans MS", 20) # Шрифт для текста кнопок -BIG_FONT_USER = ("Comic Sans MS", 30) # Большой шрифт (например, для заголовков) +# Параметры карты +MIN_OBSTACLES = 3 # Минимум препятствий на уровне +MAX_OBSTACLES = 6 # Максимум препятствий на уровне -# Размеры кнопок -BUTTON_RADIUS_USER = 50 # Радиус круглой кнопки -EXIT_BUTTON_SIZE_USER = (80, 40) # Размер кнопки "Выход" \ No newline at end of file +# Графика и анимация +COUNTDOWN_DURATION = 3 # Продолжительность обратного отсчёта в секундах diff --git a/database/__pycache__/db_events.cpython-313.pyc b/database/__pycache__/db_events.cpython-313.pyc index ee32482..ccc45cf 100644 Binary files a/database/__pycache__/db_events.cpython-313.pyc and b/database/__pycache__/db_events.cpython-313.pyc differ diff --git a/database/__pycache__/db_session.cpython-313.pyc b/database/__pycache__/db_session.cpython-313.pyc index 2eda891..ce6c9c5 100644 Binary files a/database/__pycache__/db_session.cpython-313.pyc and b/database/__pycache__/db_session.cpython-313.pyc differ diff --git a/database/__pycache__/models.cpython-313.pyc b/database/__pycache__/models.cpython-313.pyc index 21b985a..b57ef30 100644 Binary files a/database/__pycache__/models.cpython-313.pyc and b/database/__pycache__/models.cpython-313.pyc differ diff --git a/database/db_events.py b/database/db_events.py index 4a6eb60..05365a4 100644 --- a/database/db_events.py +++ b/database/db_events.py @@ -1,12 +1,18 @@ +from sqlalchemy import func +from sqlalchemy.orm import joinedload from database.db_session import get_session -from database.models import Auth, Notifications, Users +from database.models import Auth, Notifications, Users, GameSession, Dogs, Questions from sqlalchemy.exc import SQLAlchemyError -def create_user(login, password): +def create_user(login, password, username): """Создание нового пользователя в базе данных.""" session = get_session() try: - new_user = Auth(login=login, password=password) + new_user_auth = Auth(login=login, password=password) + session.add(new_user_auth) + session.commit() + + new_user = Users(username=username, auth=new_user_auth) session.add(new_user) session.commit() except SQLAlchemyError as e: @@ -20,9 +26,111 @@ def check_user(login, password): session = get_session() try: user = session.query(Auth).filter_by(login=login, password=password).first() - return user is not None + if user: + return user.user_id + return None except SQLAlchemyError as e: print(f"Ошибка при проверке пользователя: {e}") - return False + return None finally: - session.close() \ No newline at end of file + session.close() + +def save_progress(user_id, level, score, duration, health, hunger, sleepiness): + """Сохраняет прогресс пользователя в базу данных.""" + session = get_session() + try: + session_data = GameSession( + user_id=user_id, + level=level, + score=score, + duration=duration, + health=health, + hunger=hunger, + sleepiness=sleepiness, + end_time=func.now() + ) + session.add(session_data) + session.commit() + except SQLAlchemyError as e: + print(f"Ошибка при сохранении прогресса: {e}") + session.rollback() + finally: + session.close() + +def get_user_progress(user_id): + """Получение прогресса пользователя по его ID.""" + session = get_session() + try: + progress = session.query(GameSession).filter_by(user_id=user_id).all() + return progress + except SQLAlchemyError as e: + print(f"Ошибка при получении прогресса: {e}") + return [] + finally: + session.close() + +def create_notification(user_id, message): + """Создание уведомления для пользователя.""" + session = get_session() + try: + notification = Notifications(user_id=user_id, message=message) + session.add(notification) + session.commit() + except SQLAlchemyError as e: + print(f"Ошибка при создании уведомления: {e}") + session.rollback() + finally: + session.close() + +def get_notifications(user_id): + """Получение уведомлений для пользователя.""" + session = get_session() + try: + notifications = session.query(Notifications).filter_by(user_id=user_id).all() + return notifications + except SQLAlchemyError as e: + print(f"Ошибка при получении уведомлений: {e}") + return [] + finally: + session.close() + +def get_knowledge_base(): + """Получение базы знаний (статей о собаках).""" + session = get_session() + try: + dogs = session.query(Dogs).all() + return dogs # Список объектов Dogs + except SQLAlchemyError as e: + print(f"Ошибка при получении базы знаний: {e}") + return [] + finally: + session.close() + +def get_dogs(): + """Получение списка пород собак.""" + session = get_session() + try: + dogs = session.query(Dogs).all() + return dogs # Список объектов Dogs + except SQLAlchemyError as e: + print(f"Ошибка при получении списка собак: {e}") + return [] + finally: + session.close() + +def update_user_dog(user_id, dog_id): + """Обновление выбранной пользователем породы собаки.""" + session = get_session() + try: + user = session.query(Users).filter_by(user_id=user_id).first() + if user: + user.dog_id = dog_id + session.commit() + print(f"Порода пользователя обновлена на {dog_id}") + else: + print("Пользователь не найден.") + except SQLAlchemyError as e: + print(f"Ошибка при обновлении породы собаки: {e}") + session.rollback() + finally: + session.close() diff --git a/database/db_session.py b/database/db_session.py index bf7dff3..4acd1d2 100644 --- a/database/db_session.py +++ b/database/db_session.py @@ -13,7 +13,6 @@ Session = sessionmaker(bind=engine) # Переменная для хранения текущей сессии current_session = None - def init_db(refresh=False): """ Инициализация базы данных: создание файла и таблиц. @@ -33,18 +32,14 @@ def init_db(refresh=False): # Инициализация сессии при запуске current_session = get_session() - def get_session(): """Возвращает сессию для работы с базой данных.""" return Session() - def close_sessions(): """Закрытие всех сессий перед выходом из программы.""" - global current_session - if current_session is not None: + if current_session: print("Закрытие сессии...") - current_session.close() # Закрываем текущую сессию базы данных - current_session = None + current_session.close() else: print("Нет активной сессии для закрытия.") diff --git a/database/models.py b/database/models.py index cb33f92..d0725c9 100644 --- a/database/models.py +++ b/database/models.py @@ -1,11 +1,10 @@ -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, UniqueConstraint, Boolean from sqlalchemy.orm import relationship from sqlalchemy.sql import func from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() - class Auth(Base): __tablename__ = 'auth' user_id = Column(Integer, primary_key=True) @@ -50,7 +49,7 @@ class Questions(Base): __tablename__ = 'questions' question_id = Column(Integer, primary_key=True) dog_id = Column(Integer, ForeignKey('dogs.dog_id')) - question_text = Column(Text, nullable=False) # Исправлено поле + question_text = Column(Text, nullable=False) image_url = Column(String) helpful_info = Column(Text) incorrect_attempts = Column(Integer, default=0) @@ -61,24 +60,31 @@ class Questions(Base): class GameSession(Base): __tablename__ = 'game_sessions' + __table_args__ = ( + UniqueConstraint('user_id', 'level', name='uix_user_level'), + ) session_id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.user_id')) level = Column(Integer, nullable=False) score = Column(Integer, default=0) duration = Column(Integer) # Время игры в секундах - start_time = Column(DateTime, default=func.now()) # Исправлено + start_time = Column(DateTime, default=func.now()) end_time = Column(DateTime, nullable=True) + health = Column(Integer, default=100) # Здоровье + hunger = Column(Integer, default=0) # Голод + sleepiness = Column(Integer, default=0) # Сонливость # Связь с таблицей Users user = relationship("Users", back_populates="game_sessions") + class Notifications(Base): __tablename__ = 'notifications' notification_id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.user_id')) message = Column(Text, nullable=False) timestamp = Column(DateTime, default=func.now()) - is_read = Column(Integer, default=0) # 0 - не прочитано, 1 - прочитано + is_read = Column(Boolean, default=False) # Булевый тип для read # Связь с таблицей Users user = relationship("Users", back_populates="notifications") diff --git a/ishodniki/background_game.psd b/ishodniki/background_game.psd new file mode 100644 index 0000000..666a896 Binary files /dev/null and b/ishodniki/background_game.psd differ diff --git a/ishodniki/dogs.psd b/ishodniki/dogs.psd new file mode 100644 index 0000000..34f1af6 Binary files /dev/null and b/ishodniki/dogs.psd differ diff --git a/ishodniki/user_ui.psd b/ishodniki/user_ui.psd new file mode 100644 index 0000000..fc6a611 Binary files /dev/null and b/ishodniki/user_ui.psd differ diff --git a/logs/logfile.log b/logs/logfile.log index 623e4c1..11d367d 100644 --- a/logs/logfile.log +++ b/logs/logfile.log @@ -1343,3 +1343,128 @@ WHERE auth.login = ? AND auth.password = ? LIMIT ? OFFSET ? 2024-11-25 22:36:09 - [generated in 0.00045s] ('lubluNikitu', 'meow123', 1, 0) 2024-11-25 22:36:09 - ROLLBACK +2024-11-26 12:26:39 - BEGIN (implicit) +2024-11-26 12:26:39 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 12:26:39 - [generated in 0.00021s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 12:26:39 - ROLLBACK +2024-11-26 12:33:48 - BEGIN (implicit) +2024-11-26 12:33:48 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 12:33:48 - [generated in 0.00022s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 12:33:48 - ROLLBACK +2024-11-26 12:38:38 - BEGIN (implicit) +2024-11-26 12:38:38 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 12:38:38 - [generated in 0.00029s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 12:38:38 - ROLLBACK +2024-11-26 17:00:02 - BEGIN (implicit) +2024-11-26 17:00:02 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 17:00:02 - [generated in 0.00024s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 17:00:02 - ROLLBACK +2024-11-26 17:01:01 - BEGIN (implicit) +2024-11-26 17:01:01 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 17:01:01 - [generated in 0.00021s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 17:01:01 - ROLLBACK +2024-11-26 17:07:02 - BEGIN (implicit) +2024-11-26 17:07:02 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 17:07:02 - [generated in 0.00023s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 17:07:02 - ROLLBACK +2024-11-26 17:08:03 - BEGIN (implicit) +2024-11-26 17:08:03 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 17:08:03 - [generated in 0.00025s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 17:08:03 - ROLLBACK +2024-11-26 17:27:44 - BEGIN (implicit) +2024-11-26 17:27:44 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 17:27:44 - [generated in 0.00021s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 17:27:44 - ROLLBACK +2024-11-26 19:46:13 - BEGIN (implicit) +2024-11-26 19:46:13 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 19:46:13 - [generated in 0.00029s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 19:46:13 - ROLLBACK +2024-11-26 21:23:20 - BEGIN (implicit) +2024-11-26 21:23:20 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 21:23:20 - [generated in 0.00025s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 21:23:20 - ROLLBACK +2024-11-26 21:31:58 - BEGIN (implicit) +2024-11-26 21:31:58 - SELECT count(*) AS count_1 +FROM (SELECT users.user_id AS users_user_id, users.dog_id AS users_dog_id, users.username AS users_username, users.level AS users_level, users.achievement AS users_achievement +FROM users) AS anon_1 +2024-11-26 21:31:58 - [generated in 0.00026s] () +2024-11-26 21:31:58 - SELECT game_sessions.level AS game_sessions_level, count(game_sessions.session_id) AS count_1 +FROM game_sessions GROUP BY game_sessions.level +2024-11-26 21:31:58 - [generated in 0.00022s] () +2024-11-26 21:31:58 - SELECT questions.question_text AS questions_question_text, questions.incorrect_attempts AS questions_incorrect_attempts +FROM questions ORDER BY questions.incorrect_attempts DESC +2024-11-26 21:31:58 - [generated in 0.00019s] () +2024-11-26 21:31:58 - SELECT avg(game_sessions.duration) AS avg_1 +FROM game_sessions +2024-11-26 21:31:58 - [generated in 0.00014s] () +2024-11-26 21:31:58 - ROLLBACK +2024-11-26 21:31:58 - BEGIN (implicit) +2024-11-26 21:31:58 - SELECT game_sessions.start_time AS game_sessions_start_time +FROM game_sessions +2024-11-26 21:31:58 - [generated in 0.00017s] () +2024-11-26 21:31:58 - ROLLBACK +2024-11-26 21:34:57 - BEGIN (implicit) +2024-11-26 21:34:57 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 21:34:57 - [generated in 0.00025s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 21:34:57 - ROLLBACK +2024-11-26 21:47:02 - BEGIN (implicit) +2024-11-26 21:47:02 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 21:47:02 - [generated in 0.00021s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 21:47:02 - ROLLBACK +2024-11-26 21:49:25 - BEGIN (implicit) +2024-11-26 21:49:25 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 21:49:25 - [generated in 0.00023s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 21:49:25 - ROLLBACK +2024-11-26 21:54:33 - BEGIN (implicit) +2024-11-26 21:54:33 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 21:54:33 - [generated in 0.00025s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 21:54:33 - ROLLBACK +2024-11-26 22:41:31 - BEGIN (implicit) +2024-11-26 22:41:31 - SELECT auth.user_id AS auth_user_id, auth.login AS auth_login, auth.password AS auth_password +FROM auth +WHERE auth.login = ? AND auth.password = ? + LIMIT ? OFFSET ? +2024-11-26 22:41:31 - [generated in 0.00027s] ('lubluNikitu', 'meow123', 1, 0) +2024-11-26 22:41:31 - ROLLBACK diff --git a/src/__pycache__/utils.cpython-313.pyc b/src/__pycache__/utils.cpython-313.pyc index 40b1f47..f79902e 100644 Binary files a/src/__pycache__/utils.cpython-313.pyc and b/src/__pycache__/utils.cpython-313.pyc differ diff --git a/src/main.py b/src/main.py index 73f6bb3..652f530 100644 --- a/src/main.py +++ b/src/main.py @@ -1,3 +1,7 @@ +import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(__file__))) + from tkinter import Tk, messagebox from src.ui.auth_ui import DogAcademyApp # Путь к приложению from database.db_session import init_db, close_sessions # Функция для закрытия сессий diff --git a/src/ui/__pycache__/auth_ui.cpython-313.pyc b/src/ui/__pycache__/auth_ui.cpython-313.pyc index 742395b..056a4b4 100644 Binary files a/src/ui/__pycache__/auth_ui.cpython-313.pyc and b/src/ui/__pycache__/auth_ui.cpython-313.pyc differ diff --git a/src/ui/auth_ui.py b/src/ui/auth_ui.py index 7bfa52f..a127f0e 100644 --- a/src/ui/auth_ui.py +++ b/src/ui/auth_ui.py @@ -219,4 +219,4 @@ class DogAcademyApp: def show_user_dashboard(self): self.clear_frame() """Перейти к главному меню пользователя после авторизации.""" - UserApp(self.root, self) + UserApp(self.root) diff --git a/src/ui/user_ui/__pycache__/game_ui.cpython-313.pyc b/src/ui/user_ui/__pycache__/game_ui.cpython-313.pyc new file mode 100644 index 0000000..d885137 Binary files /dev/null and b/src/ui/user_ui/__pycache__/game_ui.cpython-313.pyc differ diff --git a/src/ui/user_ui/__pycache__/knowledge_ui.cpython-313.pyc b/src/ui/user_ui/__pycache__/knowledge_ui.cpython-313.pyc new file mode 100644 index 0000000..fda259a Binary files /dev/null and b/src/ui/user_ui/__pycache__/knowledge_ui.cpython-313.pyc differ diff --git a/src/ui/user_ui/__pycache__/main_menu.cpython-313.pyc b/src/ui/user_ui/__pycache__/main_menu.cpython-313.pyc index ff6afd0..2ef8d79 100644 Binary files a/src/ui/user_ui/__pycache__/main_menu.cpython-313.pyc and b/src/ui/user_ui/__pycache__/main_menu.cpython-313.pyc differ diff --git a/src/ui/user_ui/__pycache__/profile_ui.cpython-313.pyc b/src/ui/user_ui/__pycache__/profile_ui.cpython-313.pyc new file mode 100644 index 0000000..1926996 Binary files /dev/null and b/src/ui/user_ui/__pycache__/profile_ui.cpython-313.pyc differ diff --git a/src/ui/user_ui/__pycache__/shop_ui.cpython-313.pyc b/src/ui/user_ui/__pycache__/shop_ui.cpython-313.pyc new file mode 100644 index 0000000..5040a0c Binary files /dev/null and b/src/ui/user_ui/__pycache__/shop_ui.cpython-313.pyc differ diff --git a/src/ui/user_ui/game_ui.py b/src/ui/user_ui/game_ui.py index e69de29..b0df6b8 100644 --- a/src/ui/user_ui/game_ui.py +++ b/src/ui/user_ui/game_ui.py @@ -0,0 +1,149 @@ +import tkinter as tk +from PIL import Image, ImageTk +from src.utils import clear_frame +from config import DOG_CHARACTERS, BACKGROUND_GAME, LOGO, COUNTDOWN_DURATION +from src.user_functions.map_generator import generate_map +from src.user_functions.game_functions import handle_obstacle + + +class GameUI: + def __init__(self, root, user_id): + self.root = root + self.user_id = user_id + self.selected_dog = None + self.current_level = 1 + self.score = 0 + + self.root.configure(bg="lightblue") + self.create_logo() + self.show_dog_selection() + + def create_logo(self): + """Создание логотипа.""" + logo_image = Image.open(LOGO) + logo_photo = ImageTk.PhotoImage(logo_image.resize((200, 100), Image.Resampling.LANCZOS)) + logo_label = tk.Label(self.root, image=logo_photo, bg="lightblue") + logo_label.image = logo_photo + logo_label.pack(pady=10) + + def show_dog_selection(self): + """Выбор собаки пользователем.""" + clear_frame(self.root) + tk.Label( + self.root, text="Выберите собаку", font=("Comic Sans MS", 24), bg="lightblue" + ).pack(pady=20) + + dog_frame = tk.Frame(self.root, bg="lightblue") + dog_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # Центрируем фрейм + + for breed, details in DOG_CHARACTERS.items(): + dog_image = Image.open(details["image"]) + dog_photo = ImageTk.PhotoImage(dog_image.resize((150, 150), Image.Resampling.LANCZOS)) + + # Фрейм для кнопки и подписи + dog_item = tk.Frame(dog_frame, bg="lightblue") + dog_item.pack(side=tk.LEFT, padx=15, pady=15) + + # Кнопка с изображением + button = tk.Button( + dog_item, + image=dog_photo, + command=lambda b=breed: self.confirm_dog_selection(b), + bg="lightblue", + borderwidth=0, + ) + button.image = dog_photo # Сохраняем ссылку на изображение + button.pack() + + # Подпись с породой собаки + tk.Label( + dog_item, + text=breed, + font=("Comic Sans MS", 16), + bg="lightblue" + ).pack(pady=5) + + def confirm_dog_selection(self, breed): + """Подтверждение выбора собаки.""" + self.selected_dog = breed + self.show_level_selection() + + def show_level_selection(self): + """Отображение выбора уровня.""" + clear_frame(self.root) + tk.Label( + self.root, text="Выберите уровень", font=("Comic Sans MS", 20), bg="lightblue" + ).pack(pady=10) + + level_frame = tk.Frame(self.root, bg="lightblue") + level_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # Центрируем фрейм + + for level in range(1, 6): # Доступно 5 уровней + tk.Button( + level_frame, + text=f"Уровень {level}", + command=lambda l=level: self.start_level(l), + font=("Comic Sans MS", 16), + bg="lightgreen", + width=12, + ).pack(pady=10) + + def start_level(self, level): + """Начало выбранного уровня.""" + self.current_level = level + self.countdown() + + def countdown(self): + """Обратный отсчёт перед началом уровня.""" + clear_frame(self.root) + countdown_label = tk.Label( + self.root, text="", font=("Comic Sans MS", 30), bg="lightblue" + ) + countdown_label.pack(expand=True) + + for i in range(COUNTDOWN_DURATION, 0, -1): + countdown_label.config(text=f"{i}...") + self.root.update() + self.root.after(1000) + + self.start_game() + + def start_game(self): + """Запуск игрового процесса.""" + clear_frame(self.root) + + # Генерация карты + map_data = generate_map(self.current_level) + + for obstacle in map_data: + result = handle_obstacle(obstacle, self.score, self.root) + self.score = result["new_score"] + + if self.score >= 10: # Условие победы + self.show_victory_screen() + + def show_victory_screen(self): + """Экран победы.""" + clear_frame(self.root) + + tk.Label( + self.root, text="Ура, победа!", font=("Comic Sans MS", 30), bg="lightblue" + ).pack(pady=10) + + dog_image = Image.open(DOG_CHARACTERS[self.selected_dog]["image"]) + dog_photo = ImageTk.PhotoImage(dog_image.resize((150, 150), Image.Resampling.LANCZOS)) + tk.Label(self.root, image=dog_photo, bg="lightblue").pack(pady=10) + tk.Label( + self.root, + text=f"Порода: {self.selected_dog}\nСобрано косточек: {self.score}", + font=("Comic Sans MS", 20), + bg="lightblue", + ).pack(pady=10) + + tk.Button( + self.root, + text="Вернуться в главное меню", + command=lambda: self.__init__(self.root, self.user_id), + font=("Comic Sans MS", 16), + bg="lightgreen", + ).pack(pady=10) diff --git a/src/ui/user_ui/knowledge_ui.py b/src/ui/user_ui/knowledge_ui.py index e69de29..659a2fd 100644 --- a/src/ui/user_ui/knowledge_ui.py +++ b/src/ui/user_ui/knowledge_ui.py @@ -0,0 +1,34 @@ +import tkinter as tk +from src.utils import clear_frame +from database.db_events import get_knowledge_base + + +def knowledge_ui(root): + """Интерфейс базы знаний.""" + clear_frame(root) + + frame = tk.Frame(root, bg="#f8e1e1") + frame.pack(fill=tk.BOTH, expand=True) + + tk.Label(frame, text="База знаний", font=("Comic Sans MS", 30), bg="#f8e1e1").pack(pady=20) + + articles = get_knowledge_base() + for article in articles: + article_frame = tk.Frame(frame, bg="#f8f8f8", bd=2, relief=tk.RIDGE) + article_frame.pack(pady=5, padx=10, fill=tk.X) + + tk.Label(article_frame, text=article.breed, font=("Comic Sans MS", 20), bg="#f8f8f8").pack(side=tk.LEFT, + padx=10) + tk.Button(article_frame, text="Читать", command=lambda a=article: show_article(a)).pack(side=tk.RIGHT, padx=10) + + tk.Button(frame, text="Назад", command=lambda: clear_frame(root), font=("Comic Sans MS", 20)).pack(pady=20) + + +def show_article(article): + """Показать содержимое статьи.""" + top = tk.Toplevel() + top.title(article.breed) + text = tk.Text(top, wrap=tk.WORD) + text.pack(fill=tk.BOTH, expand=True) + text.insert(tk.END, article.content) + text.config(state=tk.DISABLED) diff --git a/src/ui/user_ui/main_menu.py b/src/ui/user_ui/main_menu.py index 5c0e8d2..7b3a64f 100644 --- a/src/ui/user_ui/main_menu.py +++ b/src/ui/user_ui/main_menu.py @@ -1,78 +1,167 @@ import tkinter as tk -from config import ( - BACKGROUND_COLOR_USER, - TOP_PANEL_COLOR_USER, - BUTTON_COLOR_PROFILE_USER, - BUTTON_COLOR_PLAY_USER, - BUTTON_COLOR_EXIT_USER, - BUTTON_TEXT_COLOR_USER, - FONT_USER, - BIG_FONT_USER, - BUTTON_RADIUS_USER, - EXIT_BUTTON_SIZE_USER, -) +from tkinter import Canvas +from PIL import Image, ImageTk +import math + +from config import EXIT_BUTTON_WIDTH, EXIT_BUTTON_HEIGHT, BUTTON_COLOR_EXIT +from src.ui.user_ui.game_ui import GameUI +from src.ui.user_ui.profile_ui import profile_ui +from src.ui.user_ui.shop_ui import shop_ui +from src.ui.user_ui.knowledge_ui import knowledge_ui +from src.utils import clear_frame + +# Пути к изображениям собак +DOG_IMAGES = [ + "F:/Projects/Dog_Academy/assets/dogs/Chihuahua.png", + "F:/Projects/Dog_Academy/assets/dogs/Corgi.png", + "F:/Projects/Dog_Academy/assets/dogs/Golden_Retriever.png", + "F:/Projects/Dog_Academy/assets/dogs/Husky.png", + "F:/Projects/Dog_Academy/assets/dogs/Pomeranian.png", + "F:/Projects/Dog_Academy/assets/dogs/Pug.png", + "F:/Projects/Dog_Academy/assets/dogs/Yorkshire_Terrier.png" +] + +# Настройки +BACKGROUND_COLOR = "#E5E5E5" # Цвет фона +BUTTON_COLOR_PLAY = "#4CAF50" # Цвет кнопки играть +BUTTON_TEXT_COLOR = "white" # Цвет текста на кнопке +FONT = ("Arial", 12) +BIG_FONT = ("Arial", 24) +PLAY_BUTTON_RADIUS = 100 # Радиус кнопки "Играть" class UserApp: - def __init__(self, root, auth_ui): + def __init__(self, root, user_id=None): self.root = root - self.auth_ui = auth_ui - self.root.configure(bg=BACKGROUND_COLOR_USER) - self.root.geometry("1920x1080") # Разрешение окна + self.user_id = user_id + self.root.configure(bg=BACKGROUND_COLOR) + self.root.geometry("1920x1080") self.root.title("Собачья академия") - print("Главное меню активно") # Лог при открытии меню self.show_user_dashboard() def show_user_dashboard(self): """Показать интерфейс пользователя.""" + center_x, center_y = 960, 540 # Центр экрана + radius = 300 # Радиус круга для размещения собак + num_dogs = len(DOG_IMAGES) + # Верхняя панель - top_panel = tk.Frame(self.root, bg=TOP_PANEL_COLOR_USER, height=100) + top_panel = tk.Frame(self.root, bg="#333333", height=100) top_panel.pack(fill=tk.X, side=tk.TOP) # Кнопки на верхней панели - for text, command in [("Профиль", self.show_profile), ("Магазин", self.show_shop), ("База знаний", self.show_knowledge)]: - button = tk.Button( - top_panel, - text=text, - bg=BUTTON_COLOR_PROFILE_USER, - fg=BUTTON_TEXT_COLOR_USER, - font=FONT_USER, - relief=tk.FLAT, - padx=20, - pady=10, - command=command, - ) - button.pack(side=tk.LEFT, padx=20) - - # Кнопка "Играть" в центре - play_button = tk.Button( - self.root, - text="Играть", - bg=BUTTON_COLOR_PLAY_USER, - fg=BUTTON_TEXT_COLOR_USER, - font=BIG_FONT_USER, + profile_button = tk.Button( + top_panel, + text="Профиль", + bg="#555555", + fg="white", + font=FONT, relief=tk.FLAT, - height=2, - width=10, - command=self.play_game, + padx=20, + pady=10, + command=self.show_profile ) - play_button.place(relx=0.5, rely=0.5, anchor=tk.CENTER) + profile_button.pack(side=tk.LEFT, padx=20) - # Кнопка "Выход" в правом нижнем углу - exit_button = tk.Button( - self.root, - text="Выход", - bg=BUTTON_COLOR_EXIT_USER, - fg=BUTTON_TEXT_COLOR_USER, - font=FONT_USER, - width=EXIT_BUTTON_SIZE_USER[0] // 10, - height=EXIT_BUTTON_SIZE_USER[1] // 10, - command=self.exit_app, + shop_button = tk.Button( + top_panel, + text="Магазин", + bg="#555555", + fg="white", + font=FONT, + relief=tk.FLAT, + padx=20, + pady=10, + command=self.show_shop ) - exit_button.place(relx=1.0, rely=1.0, x=-20, y=-20, anchor=tk.SE) + shop_button.pack(side=tk.LEFT, padx=20) + + knowledge_button = tk.Button( + top_panel, + text="База знаний", + bg="#555555", + fg="white", + font=FONT, + relief=tk.FLAT, + padx=20, + pady=10, + command=self.show_knowledge + ) + knowledge_button.pack(side=tk.LEFT, padx=20) + + # Размещение собак по кругу + self.place_dog_images(center_x, center_y, radius, num_dogs) + + # Кнопка "Играть" (увеличенная) + play_button_canvas = tk.Canvas( + self.root, + width=PLAY_BUTTON_RADIUS * 2, + height=PLAY_BUTTON_RADIUS * 2, + bg=BACKGROUND_COLOR, + highlightthickness=0, + ) + play_button_canvas.place(relx=0.5, rely=0.5, anchor=tk.CENTER) + + play_button_canvas.create_oval( + 0, 0, PLAY_BUTTON_RADIUS * 2, PLAY_BUTTON_RADIUS * 2, + fill=BUTTON_COLOR_PLAY, + outline=BUTTON_COLOR_PLAY, + ) + play_button_canvas.create_text( + PLAY_BUTTON_RADIUS, + PLAY_BUTTON_RADIUS, + text="Играть", + fill=BUTTON_TEXT_COLOR, + font=BIG_FONT, + ) + play_button_canvas.tag_bind("all", "", lambda e: self.play_game()) + + def place_dog_images(self, center_x, center_y, radius, num_dogs): + """Размещает изображения собак по кругу.""" + angle_step = 2 * math.pi / num_dogs # Шаг угла для размещения собак + for i in range(num_dogs): + angle = i * angle_step + x = center_x + radius * math.cos(angle) + y = center_y + radius * math.sin(angle) + + # Загрузка изображения собаки + image_path = DOG_IMAGES[i] + try: + dog_image = Image.open(image_path) + dog_image = dog_image.resize((100, 100), Image.Resampling.LANCZOS) + dog_photo = ImageTk.PhotoImage(dog_image) + + # Создание метки с изображением + dog_label = tk.Label(self.root, image=dog_photo, bg=BACKGROUND_COLOR) + dog_label.image = dog_photo # Сохраняем ссылку на изображение + dog_label.place(x=x - 50, y=y - 50) # Центрируем метку относительно позиции + except Exception as e: + print(f"Ошибка загрузки изображения {image_path}: {e}") + + def show_profile(self): + """Показать экран профиля пользователя.""" + self.clear_frame() + profile_ui(self.root, self.user_id) # Передаем user_id в profile_ui + + def show_shop(self): + """Показать экран магазина.""" + self.clear_frame() + shop_ui(self.root) + + def show_knowledge(self): + """Показать базу знаний.""" + self.clear_frame() + knowledge_ui(self.root) + + def clear_frame(self): + """Очистить текущий экран.""" + for widget in self.root.winfo_children(): + widget.destroy() def play_game(self): - """Заглушка для игры.""" + """Переход к игровому интерфейсу.""" + clear_frame(self.root) # Очищаем главное меню + GameUI(self.root, self.user_id) # Открываем игровой интерфейс print("Запуск игры...") def exit_app(self): @@ -80,14 +169,9 @@ class UserApp: print("Приложение закрыто") self.root.quit() - def show_profile(self): - """Заглушка для профиля.""" - print("Переход в профиль...") +# Запуск главного окна +if __name__ == "__main__": + root = tk.Tk() + app = UserApp(root, user_id=123) # Передаем user_id (это может быть получено после авторизации) + root.mainloop() - def show_shop(self): - """Заглушка для магазина.""" - print("Переход в магазин...") - - def show_knowledge(self): - """Заглушка для базы знаний.""" - print("Переход в базу знаний...") diff --git a/src/ui/user_ui/profile_ui.py b/src/ui/user_ui/profile_ui.py index e69de29..3419300 100644 --- a/src/ui/user_ui/profile_ui.py +++ b/src/ui/user_ui/profile_ui.py @@ -0,0 +1,23 @@ +import tkinter as tk +from src.utils import clear_frame +from database.db_events import get_user_progress + + +def profile_ui(root, user_id): + """Интерфейс профиля пользователя.""" + clear_frame(root) + + frame = tk.Frame(root, bg="#f8e1e1") + frame.pack(fill=tk.BOTH, expand=True) + + tk.Label(frame, text="Профиль", font=("Comic Sans MS", 30), bg="#f8e1e1").pack(pady=20) + + # Статистика пользователя + progress = get_user_progress(user_id) + levels_completed = len(progress) + bones_collected = sum([session.score for session in progress]) + + stats_text = f"Пройдено уровней: {levels_completed}\nСобрано косточек: {bones_collected}" + tk.Label(frame, text=stats_text, font=("Comic Sans MS", 20), bg="#f8e1e1").pack(pady=10) + + tk.Button(frame, text="Назад", command=lambda: clear_frame(root), font=("Comic Sans MS", 20)).pack(pady=20) diff --git a/src/ui/user_ui/shop_ui.py b/src/ui/user_ui/shop_ui.py index e69de29..834545e 100644 --- a/src/ui/user_ui/shop_ui.py +++ b/src/ui/user_ui/shop_ui.py @@ -0,0 +1,24 @@ +import tkinter as tk +from src.utils import clear_frame +from database.db_events import get_dogs, update_user_dog + + +def shop_ui(root, user_id): + """Интерфейс магазина.""" + clear_frame(root) + + frame = tk.Frame(root, bg="#e5e5e5") + frame.pack(fill=tk.BOTH, expand=True) + + tk.Label(frame, text="Магазин", font=("Comic Sans MS", 30), bg="#e5e5e5").pack(pady=20) + + dogs = get_dogs() # Получить список собак из базы данных + for dog in dogs: + dog_frame = tk.Frame(frame, bg="#f8f8f8", bd=2, relief=tk.RIDGE) + dog_frame.pack(pady=5, padx=10, fill=tk.X) + + tk.Label(dog_frame, text=dog.breed, font=("Comic Sans MS", 20), bg="#f8f8f8").pack(side=tk.LEFT, padx=10) + tk.Button(dog_frame, text="Купить", command=lambda d=dog: update_user_dog(user_id, d.dog_id)).pack( + side=tk.RIGHT, padx=10) + + tk.Button(frame, text="Назад", command=lambda: clear_frame(root), font=("Comic Sans MS", 20)).pack(pady=20) diff --git a/src/user_functions/__pycache__/game_functions.cpython-313.pyc b/src/user_functions/__pycache__/game_functions.cpython-313.pyc new file mode 100644 index 0000000..ed3eed8 Binary files /dev/null and b/src/user_functions/__pycache__/game_functions.cpython-313.pyc differ diff --git a/src/user_functions/__pycache__/map_generator.cpython-313.pyc b/src/user_functions/__pycache__/map_generator.cpython-313.pyc new file mode 100644 index 0000000..1016ba4 Binary files /dev/null and b/src/user_functions/__pycache__/map_generator.cpython-313.pyc differ diff --git a/src/user_functions/__pycache__/menu_functions.cpython-313.pyc b/src/user_functions/__pycache__/menu_functions.cpython-313.pyc deleted file mode 100644 index cce9cff..0000000 Binary files a/src/user_functions/__pycache__/menu_functions.cpython-313.pyc and /dev/null differ diff --git a/src/user_functions/game_functions.py b/src/user_functions/game_functions.py index e69de29..a8c4119 100644 --- a/src/user_functions/game_functions.py +++ b/src/user_functions/game_functions.py @@ -0,0 +1,57 @@ +import time +import tkinter as tk +from src.utils import clear_frame +from database.db_events import save_progress + + +def start_game(root, user_id, dog_id): + """Игровой процесс.""" + clear_frame(root) + + # Обратный отсчет + for i in range(3, 0, -1): + clear_frame(root) + tk.Label(root, text=f"{i}...", font=("Comic Sans MS", 30)).pack(expand=True) + root.update() + time.sleep(1) + + # Начало уровня + # Здесь подключается логика работы с картой и вопросами + pass + + +def handle_obstacle(obstacle, current_score, root): + """ + Обработка препятствия (вопроса) с использованием окна. + Возвращает новый счёт игрока. + """ + result = {"new_score": current_score} + + def submit_answer(): + user_answer = answer_var.get().strip().lower() + if user_answer == "правильно": # Условие для правильного ответа + result["new_score"] += 1 + else: + result["new_score"] -= 1 + question_window.destroy() # Закрываем окно вопроса + + # Создаём новое окно для вопроса + question_window = tk.Toplevel(root) + question_window.title("Вопрос") + question_window.geometry("400x200") + + # Отображение текста вопроса + tk.Label(question_window, text=f"Вопрос сложности {obstacle['difficulty']}:", font=("Arial", 14)).pack(pady=10) + + # Поле ввода ответа + answer_var = tk.StringVar() + tk.Entry(question_window, textvariable=answer_var, font=("Arial", 12)).pack(pady=10) + + # Кнопка подтверждения ответа + tk.Button(question_window, text="Ответить", command=submit_answer).pack(pady=10) + + # Ожидаем закрытия окна + question_window.grab_set() # Блокируем основное окно + root.wait_window(question_window) # Ждём завершения окна вопроса + + return result diff --git a/src/user_functions/knowledge_functions.py b/src/user_functions/knowledge_functions.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/user_functions/map_generator.py b/src/user_functions/map_generator.py new file mode 100644 index 0000000..b86d377 --- /dev/null +++ b/src/user_functions/map_generator.py @@ -0,0 +1,13 @@ +import random + +def generate_map(level): + """Генерация карты уровня.""" + num_obstacles = random.randint(3, 6) + map_data = [] + for i in range(num_obstacles): + map_data.append({ + "type": "question", + "difficulty": level, + "position": random.randint(1, 100) + }) + return map_data diff --git a/src/user_functions/menu_functions.py b/src/user_functions/menu_functions.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/user_functions/profile_functions.py b/src/user_functions/profile_functions.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/user_functions/shop_functions.py b/src/user_functions/shop_functions.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/utils.py b/src/utils.py index b73ac70..da21308 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,4 +1,6 @@ import tkinter as tk +from tkinter import messagebox + def clear_frame(frame): """Удаление всех виджетов из фрейма.""" @@ -16,16 +18,10 @@ def feature_in_development(frame): font=("Comic Sans MS", 16) ).pack(expand=True) -def create_tooltip(widget, text): - """Создание подсказки для виджета.""" - tooltip = tk.Toplevel() - tooltip.wm_overrideredirect(True) # Отключаем рамки окна - tooltip.wm_geometry(f"+{widget.winfo_rootx() + 20}+{widget.winfo_rooty() + 20}") - label = tk.Label(tooltip, text=text, bg="#333", fg="#fff", font=("Comic Sans MS", 10), padx=5, pady=5) - label.pack() - - def hide_tooltip(event): - tooltip.destroy() - - widget.bind("", lambda event: tooltip.deiconify()) - widget.bind("", hide_tooltip) +def show_message(message): + """Показать сообщение пользователю""" + message_window = tk.Toplevel() + message_label = tk.Label(message_window, text=message, font=("Comic Sans MS", 16)) + message_label.pack(pady=20) + ok_button = tk.Button(message_window, text="OK", command=message_window.destroy) + ok_button.pack(pady=10) \ No newline at end of file