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


import pygame
import sys
import os
import random

# Инициализация Pygame
pygame.init()
pygame.font.init()
pygame.mixer.init(frequency=44100, size=-16, channels=2, buffer=512)

# --- АВТООПРЕДЕЛЕНИЕ ПУТЕЙ ДЛЯ .EXE ---
def get_path(relative_path):
    if getattr(sys, 'frozen', False):
        base_path = os.path.dirname(sys.executable)
    else:
        base_path = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(base_path, relative_path)

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

# Цвета
BG_COLOR = (35, 39, 42)
DESK_COLOR = (60, 42, 33)
TEXT_COLOR = (255, 255, 255)
BTN_GREEN = (46, 139, 87)
BTN_RED = (178, 34, 34)
BTN_BLUE = (41, 128, 185)
OVERLAY_BG = (20, 20, 20, 220)

# Шрифты
font_main = pygame.font.SysFont("Arial", 15)
font_bold = pygame.font.SysFont("Arial", 17, bold=True)
font_large = pygame.font.SysFont("Arial", 22, bold=True)

# Загрузка звуков
sounds = {}
def load_sounds():
    sound_files = {'allow': 'allow.wav', 'deny': 'deny.wav', 'click': 'click.wav'}
    for name, file in sound_files.items():
        path = get_path(os.path.join('sounds', file))
        if os.path.exists(path):
            try:
                sounds[name] = pygame.mixer.Sound(path)
            except Exception as e:
                print(f"Ошибка загрузки звука {file}: {e}")
                sounds[name] = None
        else:
            sounds[name] = None

def play_sound(name):
    if name in sounds and sounds[name]:
        sounds[name].play()

load_sounds()

# Состояние игры
score = 0
lives = 3
current_npc = None

# Экраны досмотра
active_screen = None # None, 'phone', 'bag'

VALID_COUNTRIES = ["Россия", "Китай", "КНДР"]
INVALID_COUNTRIES = ["США", "Великобритания", "Германия", "Япония"]

def load_image_files(folder_path):
    path = get_path(folder_path)
    if not os.path.exists(path):
        os.makedirs(path, exist_ok=True)
        return []
    valid_exts = ('.png', '.jpg', '.jpeg', '.bmp')
    return [os.path.join(path, f) for f in os.listdir(path) if f.lower().endswith(valid_exts)]

def load_and_scale(image_path, size):
    try:
        img = pygame.image.load(image_path).convert_alpha()
        return pygame.transform.scale(img, size)
    except Exception:
        return create_placeholder(size, "Ошибка")

def create_placeholder(size, text):
    surf = pygame.Surface(size)
    surf.fill((180, 180, 180))
    pygame.draw.rect(surf, (80, 80, 80), surf.get_rect(), 2)
    txt_surf = font_main.render(text, True, (40, 40, 40))
    rect = txt_surf.get_rect(center=(size[0]//2, size[1]//2))
    surf.blit(txt_surf, rect)
    return surf

class NPC:
    def __init__(self):
        self.is_threat = random.random() < 0.60
        
        if self.is_threat and random.random() < 0.5:
            self.country = random.choice(INVALID_COUNTRIES)
        else:
            self.country = random.choice(VALID_COUNTRIES)

        self.passport_valid = (self.country in VALID_COUNTRIES)
        self.name = random.choice(["Иван", "Ли", "Ким", "Алексей", "Чжан", "Пак"]) + " " + random.choice(["Иванов", "Вэй", "Мин", "Петров"])
        self.doc_id = str(random.randint(100000, 999999))

        # Персонаж
        friends_files = load_image_files('friends')
        if friends_files:
            avatar_path = random.choice(friends_files)
            self.avatar = load_and_scale(avatar_path, (220, 260))
            self.pass_avatar = load_and_scale(avatar_path, (100, 120))
        else:
            self.avatar = create_placeholder((220, 260), "Нет фото")
            self.pass_avatar = create_placeholder((100, 120), "Нет фото")

        # Фото в телефоне (показываем все сразу)
        good_photos = load_image_files(os.path.join('phone_photos', 'good'))
        bad_photos = load_image_files(os.path.join('phone_photos', 'bad'))

        self.phone_photos = []
        if good_photos:
            sample_g = random.sample(good_photos, min(len(good_photos), 3))
            for p in sample_g:
                self.phone_photos.append(load_and_scale(p, (130, 130)))

        if self.is_threat and bad_photos:
            bad_p = random.choice(bad_photos)
            self.phone_photos.append(load_and_scale(bad_p, (130, 130)))

        random.shuffle(self.phone_photos)

        # Предметы в сумке
        items_files = load_image_files('items')
        self.items = []
        if items_files:
            selected = random.sample(items_files, min(len(items_files), 4))
            for path in selected:
                fname = os.path.splitext(os.path.basename(path))[0]
                if fname.lower() == "запрещенная рация":
                    fname = "Рация"
                self.items.append((fname, load_and_scale(path, (80, 80))))

    def check_verdict(self, player_action):
        should_deny = self.is_threat or (not self.passport_valid)
        if player_action == 'allow':
            return not should_deny
        else:
            return should_deny

def spawn_npc():
    global current_npc, active_screen
    current_npc = NPC()
    active_screen = None

def draw_ui():
    screen.fill(BG_COLOR)
    
    # Стол
    pygame.draw.rect(screen, DESK_COLOR, (0, 320, WIDTH, HEIGHT - 320))

    # Окно персонажа
    pygame.draw.rect(screen, (15, 15, 15), (40, 25, 320, 280), border_radius=8)
    if current_npc:
        screen.blit(current_npc.avatar, (90, 35))

    # Лист правил
    rule_rect = pygame.Rect(390, 25, 520, 160)
    pygame.draw.rect(screen, (245, 235, 210), rule_rect, border_radius=5)
    pygame.draw.rect(screen, (100, 80, 50), rule_rect, 3, border_radius=5)
    
    rules = [
        "ПРАВИЛА КПП КНДР",
        "1. Разрешенные страны: Россия, Китай, КНДР",
        "2. Граждан США и других стран — СТРЕЛЯТЬ!",
        "3. Обыскивайте телефон и сумку на наличие угроз."
    ]
    for i, line in enumerate(rules):
        color = (180, 0, 0) if "СТРЕЛЯТЬ" in line else (0, 0, 0)
        txt = (font_bold if i==0 else font_main).render(line, True, color)
        screen.blit(txt, (405, 35 + i * 35))

    # --- ПАСПОРТ НА СТОЛЕ (Большой и понятный) ---
    passport_rect = pygame.Rect(40, 350, 480, 200)
    pygame.draw.rect(screen, (240, 230, 210), passport_rect, border_radius=10)
    pygame.draw.rect(screen, (100, 80, 50), passport_rect, 4, border_radius=10)
    
    if current_npc:
        screen.blit(current_npc.pass_avatar, (60, 390))
        t_title = font_large.render("ПАСПОРТ ГРАЖДАНИНА", True, (100, 30, 30))
        t1 = font_bold.render(f"Имя: {current_npc.name}", True, (0, 0, 0))
        t2 = font_large.render(f"Страна: {current_npc.country}", True, (0, 0, 0))
        t3 = font_main.render(f"Документ №: {current_npc.doc_id}", True, (60, 60, 60))
        
        screen.blit(t_title, (180, 365))
        screen.blit(t1, (180, 405))
        screen.blit(t2, (180, 440))
        screen.blit(t3, (180, 485))

    # Кнопки действия (ВПУСТИТЬ / СТРЕЛЯТЬ)
    btn_allow = pygame.Rect(650, 360, 260, 70)
    btn_deny = pygame.Rect(650, 460, 260, 70)
    pygame.draw.rect(screen, BTN_GREEN, btn_allow, border_radius=10)
    pygame.draw.rect(screen, BTN_RED, btn_deny, border_radius=10)

    txt_allow = font_large.render("ВПУСТИТЬ", True, TEXT_COLOR)
    txt_deny = font_large.render("СТРЕЛЯТЬ", True, TEXT_COLOR)
    screen.blit(txt_allow, txt_allow.get_rect(center=btn_allow.center))
    screen.blit(txt_deny, txt_deny.get_rect(center=btn_deny.center))

    # Кнопки вызова экранов
    btn_phone = pygame.Rect(40, 580, 230, 50)
    btn_bag = pygame.Rect(290, 580, 230, 50)
    pygame.draw.rect(screen, BTN_BLUE, btn_phone, border_radius=8)
    pygame.draw.rect(screen, BTN_BLUE, btn_bag, border_radius=8)

    txt_phone = font_bold.render("Открыть Телефон", True, TEXT_COLOR)
    txt_bag = font_bold.render("Обыскать Сумку", True, TEXT_COLOR)
    screen.blit(txt_phone, txt_phone.get_rect(center=btn_phone.center))
    screen.blit(txt_bag, txt_bag.get_rect(center=btn_bag.center))

    # Очки
    stat_txt = font_large.render(f"Очки: {score}   Жизни: {lives}", True, TEXT_COLOR)
    screen.blit(stat_txt, (650, 590))

    # --- ОТДЕЛЬНЫЕ ЭКРАНЫ ДОСМОТРА ---
    btn_close = None

    if active_screen in ['phone', 'bag']:
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        screen.blit(overlay, (0, 0))

        box = pygame.Rect(150, 80, 650, 500)
        pygame.draw.rect(screen, (230, 230, 230), box, border_radius=12)
        pygame.draw.rect(screen, (50, 50, 50), box, 4, border_radius=12)

        btn_close = pygame.Rect(730, 95, 55, 45)
        pygame.draw.rect(screen, BTN_RED, btn_close, border_radius=8)
        c_txt = font_bold.render("X", True, TEXT_COLOR)
        screen.blit(c_txt, c_txt.get_rect(center=btn_close.center))

        if active_screen == 'phone':
            title = font_large.render("ГАЛЕРЕЯ ТЕЛЕФОНА (ВСЕ ФОТО)", True, (0, 0, 0))
            screen.blit(title, (180, 105))

            if current_npc and current_npc.phone_photos:
                for idx, img in enumerate(current_npc.phone_photos):
                    x = 190 + (idx % 4) * 140
                    y = 180 + (idx // 4) * 140
                    screen.blit(img, (x, y))
                    pygame.draw.rect(screen, (0, 0, 0), (x, y, 130, 130), 2)
            else:
                empty = font_large.render("Галерея пуста", True, (100, 100, 100))
                screen.blit(empty, (380, 280))

        elif active_screen == 'bag':
            title = font_large.render("СОДЕРЖИМОЕ СУМКИ", True, (0, 0, 0))
            screen.blit(title, (180, 105))

            if current_npc and current_npc.items:
                for idx, (iname, img) in enumerate(current_npc.items):
                    x = 190 + (idx % 2) * 290
                    y = 170 + (idx // 2) * 120
                    screen.blit(img, (x, y))
                    lbl = font_large.render(iname, True, (0, 0, 0))
                    screen.blit(lbl, (x + 95, y + 25))
            else:
                empty = font_large.render("Сумка пуста", True, (100, 100, 100))
                screen.blit(empty, (380, 280))

    return btn_allow, btn_deny, btn_phone, btn_bag, btn_close

# Главный цикл
spawn_npc()
clock = pygame.time.Clock()

while True:
    btn_allow, btn_deny, btn_phone, btn_bag, btn_close = draw_ui()
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            mpos = event.pos

            if btn_close and btn_close.collidepoint(mpos):
                play_sound('click')
                active_screen = None

            elif not active_screen:
                if btn_phone.collidepoint(mpos):
                    play_sound('click')
                    active_screen = 'phone'
                elif btn_bag.collidepoint(mpos):
                    play_sound('click')
                    active_screen = 'bag'
                elif btn_allow.collidepoint(mpos):
                    if current_npc.check_verdict('allow'):
                        play_sound('allow')
                        score += 100
                    else:
                        play_sound('deny')
                        lives -= 1
                    spawn_npc()
                elif btn_deny.collidepoint(mpos):
                    if current_npc.check_verdict('deny'):
                        play_sound('deny')
                        score += 100
                    else:
                        play_sound('allow')
                        lives -= 1
                    spawn_npc()

    if lives <= 0:
        score = 0
        lives = 3
        spawn_npc()

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