Загрузка данных


import pygame
import sys
import random
import os
import array
from pathlib import Path

pygame.init()
pygame.mixer.init()

# Размеры экрана
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("КПП: Пограничный досмотр")

# Базовый путь к папке скрипта
BASE_DIR = Path(__file__).parent.resolve()

# Шрифты
font = pygame.font.SysFont("Arial", 16)
big_font = pygame.font.SysFont("Arial", 20, bold=True)
small_font = pygame.font.SysFont("Arial", 13)

# Цвета
GRAY = (140, 140, 140)
DARK_WALL = (40, 42, 48)
BORDER_FRAME = (25, 27, 32)
DESK_COLOR = (70, 50, 35)
DESK_DARK = (50, 35, 22)
WINDOW_BG = (100, 140, 180)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (180, 30, 30)
GREEN = (30, 160, 30)
BLUE = (40, 80, 160)
YELLOW = (220, 170, 20)
BROWN = (110, 65, 25)
PASSPORT_COVER = (20, 45, 90)
PAPER_COLOR = (245, 240, 225)
PHONE_BG = (25, 25, 35)

# --- ЗВУКОВЫЕ ЭФФЕКТЫ ---
def create_synth_sound(freq, duration):
    sample_rate = 44100
    n_samples = int(sample_rate * duration)
    buf = array.array('h', [0] * n_samples)
    for i in range(n_samples):
        t = float(i) / sample_rate
        buf[i] = int(0.3 * 32767.0 * (1.0 if (int(t * freq * 2) % 2) else -1.0))
    return pygame.mixer.Sound(buffer=buf)

def load_sound(filename, fallback_freq, fallback_dur):
    sounds_dir = BASE_DIR / "sounds"
    if sounds_dir.exists():
        for ext in [".mp3", ".wav", ".MP3", ".WAV"]:
            sound_path = sounds_dir / f"{filename}{ext}"
            if sound_path.exists():
                try:
                    return pygame.mixer.Sound(str(sound_path))
                except Exception as e:
                    print(f"Ошибка загрузки звука {sound_path}: {e}")
    return create_synth_sound(fallback_freq, fallback_dur)

sound_shoot = load_sound("shoot", 150, 0.2)
sound_boom = load_sound("boom", 60, 0.5)
sound_pass = load_sound("pass", 400, 0.15)

# --- УМНАЯ ЗАГРУЗКА ИЗОБРАЖЕНИЙ ДРУЗЕЙ (ХОРОШИЕ / ПЛОХИЕ) ---
good_friends_images = []
bad_friends_images = []
all_friends_images = []

friends_dir = BASE_DIR / "friends"

def load_photo(file_path):
    try:
        img = pygame.image.load(str(file_path)).convert_alpha()
        return pygame.transform.scale(img, (180, 240))
    except Exception as e:
        print(f"Ошибка загрузки фото {file_path.name}: {e}")
        return None

if friends_dir.exists():
    # Проверяем подпапки friends/good и friends/bad если они есть
    good_dir = friends_dir / "good"
    bad_dir = friends_dir / "bad"
    
    if good_dir.exists() or bad_dir.exists():
        if good_dir.exists():
            for f in good_dir.iterdir():
                if f.suffix.lower() in [".png", ".jpg", ".jpeg"]:
                    img = load_photo(f)
                    if img: good_friends_images.append(img)
        if bad_dir.exists():
            for f in bad_dir.iterdir():
                if f.suffix.lower() in [".png", ".jpg", ".jpeg"]:
                    img = load_photo(f)
                    if img: bad_friends_images.append(img)
    else:
        # Если подпапок нет, сортируем по имени файла (если есть 'bad' или 'плохой' в названии)
        for f in friends_dir.iterdir():
            if f.suffix.lower() in [".png", ".jpg", ".jpeg"]:
                img = load_photo(f)
                if img:
                    all_friends_images.append(img)
                    name_lower = f.name.lower()
                    if "bad" in name_lower or "плох" in name_lower or "vrag" in name_lower:
                        bad_friends_images.append(img)
                    else:
                        good_friends_images.append(img)

# Функция выбора фото с регулируемой вероятностью (по умолчанию 50 на 50)
def get_friend_photo(is_threat_person=False):
    # Если персонаж нарушитель — отдаем приоритет плохим фото
    # Настройка шансов выпадания: weights=[ШансХорошего, ШансПлохого]
    # Настройки: [50, 50] — ровно пополам; [25, 75] — 75% плохих и 25% хороших
    weights_config = [50, 50] 
    
    if good_friends_images and bad_friends_images:
        chosen_type = random.choices(["good", "bad"], weights=weights_config)[0]
        if chosen_type == "good":
            return random.choice(good_friends_images)
        else:
            return random.choice(bad_friends_images)
    elif all_friends_images:
        return random.choice(all_friends_images)
    elif good_friends_images:
        return random.choice(good_friends_images)
    elif bad_friends_images:
        return random.choice(bad_friends_images)
    return None

# --- ЗАГРУЗКА ПРЕДМЕТОВ ДЛЯ СУМКИ ---
items_images = {}
items_dir = BASE_DIR / "items"

if items_dir.exists():
    for file_path in items_dir.iterdir():
        if file_path.suffix.lower() in [".png", ".jpg", ".jpeg"]:
            try:
                item_name = file_path.stem.strip().lower()
                img = pygame.image.load(str(file_path)).convert_alpha()
                img = pygame.transform.scale(img, (80, 80))
                items_images[item_name] = img
            except Exception as e:
                print(f"Ошибка загрузки предмета {file_path.name}: {e}")

# --- СПИСКИ ДАННЫХ И ПРАВИЛА ---
FRIENDLY_COUNTRIES = ["Россия", "Китай", "КНДР"]
UNFRIENDLY_COUNTRIES = ["США", "Великобритания", "Япония"]

NAMES = ["Алексей", "Иван", "Сергей", "Дмитрий", "Егор", "Максим"]
SAFE_ITEMS_NAMES = ["Вода", "Носки", "Консервы", "Книга"]
BAD_ITEMS_NAMES = ["Бомба", "Запрещенная рация", "Нож"]

GAMES_LIST = ["Brawl Stars", "Subway Surfers", "Roblox", "Minecraft"]
SUSPICIOUS_SEARCH = ["как обойти КПП незаметно", "карта секретных зон", "где купить рацию"]
SAFE_SEARCH = ["погода на завтра", "рецепт блинов", "видео с котиками"]

score = 0
lives = 3
current_screen = "MAIN" 
phone_tab = "DESKTOP"   
passport_open = False

visitor_x = -200.0
target_x = 180.0
is_walking = True
person_rect = pygame.Rect(180, 80, 180, 240)

def generate_visitor():
    global visitor_x, is_walking, passport_open
    visitor_x = -200.0
    is_walking = True
    passport_open = False
    
    # Ровно 50% шанс генерации нарушителя
    is_threat = random.choice([True, False])
    
    name = random.choice(NAMES)
    avatar = get_friend_photo(is_threat_person=is_threat)
    
    if is_threat:
        bad_country = random.choice([True, False])
        bad_item = random.choice([True, False])
        bad_search = random.choice([True, False])
        
        if not (bad_country or bad_item or bad_search):
            bad_country = True

        country = random.choice(UNFRIENDLY_COUNTRIES) if bad_country else random.choice(FRIENDLY_COUNTRIES)
        
        bag = random.sample(SAFE_ITEMS_NAMES, 2)
        if bad_item:
            bag.append(random.choice(BAD_ITEMS_NAMES))

        searches = [
            random.choice(SUSPICIOUS_SEARCH if bad_search else SAFE_SEARCH),
            "погода на завтра"
        ]
    else:
        country = random.choice(FRIENDLY_COUNTRIES)
        bag = random.sample(SAFE_ITEMS_NAMES, 2)
        searches = [random.choice(SAFE_SEARCH), "погода на завтра"]

    # Формируем галерею для телефона
    gallery_source = (good_friends_images + bad_friends_images) or all_friends_images
    gallery_photos = random.sample(gallery_source, min(len(gallery_source), 3)) if gallery_source else []

    return {
        "name": name,
        "country": country,
        "is_threat": is_threat,
        "bag": bag,
        "games": random.sample(GAMES_LIST, 2),
        "searches": searches,
        "gallery": gallery_photos,
        "avatar": avatar
    }

visitor = generate_visitor()
message = "Посетитель подходит к окну КПП..."

# Игровые области и кнопки
btn_allow = pygame.Rect(780, 520, 180, 50)
btn_shoot = pygame.Rect(780, 585, 180, 50)
btn_phone = pygame.Rect(40, 610, 200, 45)
btn_grab_bag = pygame.Rect(260, 610, 200, 45)
btn_back = pygame.Rect(780, 600, 160, 45)

# Паспорт на столе
passport_closed_rect = pygame.Rect(520, 400, 160, 110)
passport_open_rect = pygame.Rect(460, 330, 280, 190)

# Кнопки телефона
btn_phone_home = pygame.Rect(450, 580, 100, 30)
btn_app_browser = pygame.Rect(340, 160, 140, 45)
btn_app_gallery = pygame.Rect(500, 160, 140, 45)

clock = pygame.time.Clock()

while True:
    screen.fill(BLACK)
    dt = clock.tick(60) / 1000.0

    if is_walking:
        visitor_x += (target_x - visitor_x) * 5.0 * dt
        person_rect.x = int(visitor_x)
        if abs(target_x - visitor_x) < 1.0:
            visitor_x = target_x
            person_rect.x = int(target_x)
            is_walking = False
            message = "Нажмите на паспорт на столе, чтобы открыть его."

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            
        if event.type == pygame.MOUSEBUTTONDOWN and not is_walking:
            pos = event.pos
            
            if current_screen == "MAIN":
                if (passport_open_rect.collidepoint(pos) if passport_open else passport_closed_rect.collidepoint(pos)):
                    passport_open = not passport_open

                elif btn_allow.collidepoint(pos):
                    if visitor["is_threat"]:
                        sound_boom.play()
                        lives -= 1
                        message = "ВЗРЫВ! Вы пропустили опасного нарушителя!"
                    else:
                        sound_pass.play()
                        score += 10
                        message = "Гражданин успешно пропущен."
                    visitor = generate_visitor()

                elif btn_shoot.collidepoint(pos):
                    sound_shoot.play()
                    if visitor["is_threat"]:
                        score += 15
                        message = "Нарушитель ликвидирован!"
                    else:
                        score -= 10
                        message = "Ошибка! У человека не было нарушений."
                    visitor = generate_visitor()

                elif btn_phone.collidepoint(pos):
                    current_screen = "PHONE"
                    phone_tab = "DESKTOP"
                elif btn_grab_bag.collidepoint(pos):
                    current_screen = "BAG"

            elif current_screen == "PHONE":
                if btn_back.collidepoint(pos):
                    current_screen = "MAIN"
                elif btn_phone_home.collidepoint(pos):
                    phone_tab = "DESKTOP"
                elif phone_tab == "DESKTOP":
                    if btn_app_browser.collidepoint(pos):
                        phone_tab = "BROWSER"
                    elif btn_app_gallery.collidepoint(pos):
                        phone_tab = "GALLERY"

            elif current_screen == "BAG":
                if btn_back.collidepoint(pos):
                    current_screen = "MAIN"

    # --- ЭКРАН КПП ---
    if current_screen == "MAIN":
        pygame.draw.rect(screen, WINDOW_BG, (100, 40, 360, 290))
        
        if visitor["avatar"]:
            screen.blit(visitor["avatar"], (person_rect.x, person_rect.y))
        else:
            pygame.draw.rect(screen, WHITE, person_rect)
            screen.blit(font.render("2D Фото", True, BLACK), (person_rect.x + 50, person_rect.y + 100))

        pygame.draw.rect(screen, DARK_WALL, (0, 0, WIDTH, HEIGHT))
        pygame.draw.rect(screen, WINDOW_BG, (100, 40, 360, 290))
        if visitor["avatar"]:
            screen.blit(visitor["avatar"], (person_rect.x, person_rect.y))
        else:
            pygame.draw.rect(screen, WHITE, person_rect)
            screen.blit(font.render("2D Фото", True, BLACK), (person_rect.x + 50, person_rect.y + 100))
            
        pygame.draw.rect(screen, BORDER_FRAME, (100, 40, 360, 290), 12)

        pygame.draw.rect(screen, DESK_COLOR, (0, 330, WIDTH, 330))
        pygame.draw.rect(screen, DESK_DARK, (0, 330, WIDTH, 15))

        # Правила КПП
        rule_paper = pygame.Rect(510, 30, 440, 280)
        pygame.draw.rect(screen, PAPER_COLOR, rule_paper)
        pygame.draw.rect(screen, (200, 190, 170), rule_paper, 2)
        pygame.draw.circle(screen, RED, (730, 42), 10)
        pygame.draw.circle(screen, BLACK, (730, 42), 10, 2)
        pygame.draw.circle(screen, WHITE, (728, 40), 3)

        screen.blit(big_font.render("ПРАВИЛА КПП КНДР", True, BLACK), (630, 55))
        screen.blit(font.render("1. Пропускать ТОЛЬКО: Россия, Китай, КНДР.", True, GREEN), (530, 100))
        screen.blit(font.render("2. Граждан США и других стран — СТРЕЛЯТЬ!", True, RED), (530, 135))
        screen.blit(font.render("3. Досматривайте сумку на вещи и оружие.", True, BLACK), (530, 170))
        screen.blit(font.render("4. Проверяйте историю и Галерею в телефоне.", True, BLACK), (530, 205))

        # Паспорт на столе
        if not passport_open:
            pygame.draw.rect(screen, PASSPORT_COVER, passport_closed_rect, border_radius=5)
            pygame.draw.rect(screen, YELLOW, passport_closed_rect, 2, border_radius=5)
            screen.blit(small_font.render("ПАСПОРТ", True, YELLOW), (passport_closed_rect.x + 48, passport_closed_rect.y + 30))
            screen.blit(small_font.render("[ Кликни ]", True, WHITE), (passport_closed_rect.x + 48, passport_closed_rect.y + 65))
        else:
            pygame.draw.rect(screen, PAPER_COLOR, passport_open_rect, border_radius=5)
            pygame.draw.rect(screen, BLACK, passport_open_rect, 2, border_radius=5)
            pygame.draw.line(screen, GRAY, (passport_open_rect.x + 140, passport_open_rect.y), 
                             (passport_open_rect.x + 140, passport_open_rect.y + 190), 2)
            
            pygame.draw.rect(screen, GRAY, (passport_open_rect.x + 20, passport_open_rect.y + 35, 100, 120))
            screen.blit(small_font.render("ФОТО", True, WHITE), (passport_open_rect.x + 50, passport_open_rect.y + 85))

            country_is_bad = visitor["country"] in UNFRIENDLY_COUNTRIES
            country_color = RED if country_is_bad else GREEN
            
            screen.blit(small_font.render(f"Имя: {visitor['name']}", True, BLACK), (passport_open_rect.x + 150, passport_open_rect.y + 40))
            screen.blit(small_font.render("Страна:", True, BLACK), (passport_open_rect.x + 150, passport_open_rect.y + 75))
            screen.blit(big_font.render(visitor['country'], True, country_color), (passport_open_rect.x + 150, passport_open_rect.y + 95))
            screen.blit(small_font.render("[Кликни чтобы закрыть]", True, GRAY), (passport_open_rect.x + 145, passport_open_rect.y + 160))

        pygame.draw.rect(screen, BLUE, btn_phone, border_radius=5)
        pygame.draw.rect(screen, BLUE, btn_grab_bag, border_radius=5)
        screen.blit(font.render("Проверить телефон", True, WHITE), (btn_phone.x + 20, btn_phone.y + 10))
        screen.blit(font.render("Обыскать сумку", True, WHITE), (btn_grab_bag.x + 30, btn_grab_bag.y + 10))

        pygame.draw.rect(screen, GREEN, btn_allow, border_radius=5)
        pygame.draw.rect(screen, RED, btn_shoot, border_radius=5)
        screen.blit(big_font.render("ВПУСТИТЬ", True, WHITE), (btn_allow.x + 40, btn_allow.y + 12))
        screen.blit(big_font.render("СТРЕЛЯТЬ", True, WHITE), (btn_shoot.x + 35, btn_shoot.y + 12))

    # --- ЭКРАН СУМКИ ---
    elif current_screen == "BAG":
        pygame.draw.rect(screen, BROWN, (100, 40, 800, 540))
        screen.blit(big_font.render("Содержимое сумки:", True, WHITE), (130, 60))
        
        x_offset, y_offset = 140, 120
        for item_name in visitor["bag"]:
            item_box = pygame.Rect(x_offset, y_offset, 210, 170)
            is_bad = item_name in BAD_ITEMS_NAMES
            border_color = RED if is_bad else GREEN
            
            pygame.draw.rect(screen, WHITE, item_box)
            pygame.draw.rect(screen, border_color, item_box, 4)
            
            key_name = item_name.strip().lower()
            if key_name in items_images:
                screen.blit(items_images[key_name], (x_offset + 65, y_offset + 20))
            else:
                pygame.draw.rect(screen, GRAY, (x_offset + 50, y_offset + 20, 110, 80))
                screen.blit(font.render("Предмет", True, BLACK), (x_offset + 70, y_offset + 50))
                
            screen.blit(font.render(item_name, True, BLACK), (x_offset + 20, y_offset + 120))
            x_offset += 240

        pygame.draw.rect(screen, DARK_WALL, btn_back, border_radius=5)
        screen.blit(font.render("Назад к КПП", True, WHITE), (btn_back.x + 30, btn_back.y + 10))

    # --- ЭКРАН ТЕЛЕФОНА ---
    elif current_screen == "PHONE":
        pygame.draw.rect(screen, BLACK, (300, 20, 400, 610), border_radius=20)
        pygame.draw.rect(screen, PHONE_BG, (320, 60, 360, 510))
        
        pygame.draw.rect(screen, BLACK, (320, 60, 360, 25))
        screen.blit(font.render("12:45 | 87% [4G]", True, WHITE), (330, 63))

        pygame.draw.rect(screen, GRAY, btn_phone_home, border_radius=5)
        screen.blit(font.render("ДОМОЙ", True, BLACK), (btn_phone_home.x + 22, btn_phone_home.y + 5))

        if phone_tab == "DESKTOP":
            screen.blit(big_font.render("Рабочий стол", True, WHITE), (340, 100))
            
            pygame.draw.rect(screen, GREEN, btn_app_browser, border_radius=8)
            screen.blit(font.render("Браузер", True, WHITE), (btn_app_browser.x + 40, btn_app_browser.y + 12))

            pygame.draw.rect(screen, BLUE, btn_app_gallery, border_radius=8)
            screen.blit(font.render("Галерея", True, WHITE), (btn_app_gallery.x + 40, btn_app_gallery.y + 12))

            screen.blit(font.render("Приложения:", True, YELLOW), (340, 250))
            y_game = 280
            for g in visitor["games"]:
                pygame.draw.rect(screen, DARK_WALL, (340, y_game, 320, 35), border_radius=5)
                screen.blit(font.render(f"[App] {g}", True, WHITE), (350, y_game + 7))
                y_game += 45

        elif phone_tab == "BROWSER":
            screen.blit(big_font.render("История поиска:", True, WHITE), (340, 95))
            y_s = 140
            for s in visitor["searches"]:
                is_bad = s in SUSPICIOUS_SEARCH
                color = RED if is_bad else WHITE
                pygame.draw.rect(screen, DARK_WALL, (330, y_s, 340, 40), border_radius=5)
                screen.blit(font.render(f"Поиск: {s}", True, color), (340, y_s + 10))
                y_s += 50

        elif phone_tab == "GALLERY":
            screen.blit(big_font.render("Галерея:", True, WHITE), (340, 95))
            if visitor["gallery"]:
                x_g = 340
                for img in visitor["gallery"]:
                    small_img = pygame.transform.scale(img, (90, 120))
                    screen.blit(small_img, (x_g, 140))
                    pygame.draw.rect(screen, WHITE, (x_g, 140, 90, 120), 2)
                    x_g += 105
            else:
                screen.blit(font.render("Папка с фото пуста", True, GRAY), (340, 140))

        pygame.draw.rect(screen, DARK_WALL, btn_back, border_radius=5)
        screen.blit(font.render("Назад к КПП", True, WHITE), (btn_back.x + 30, btn_back.y + 10))

    pygame.draw.rect(screen, BLACK, (0, 660, WIDTH, 40))
    screen.blit(big_font.render(f"Очки: {score}   Жизни: {lives}", True, WHITE), (20, 668))
    screen.blit(font.render(message, True, RED if "ВЗРЫВ" in message or "Ошибка" in message else YELLOW), (300, 670))

    pygame.display.flip()
    clock.tick(60)