import pygame import os import sys # ================= ИНИЦИАЛИЗАЦИЯ ================= pygame.init() WIDTH, HEIGHT = 1024, 768 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Симулятор: Административный персонал") clock = pygame.time.Clock() FONT = pygame.font.SysFont("Arial", 20) BIG_FONT = pygame.font.SysFont("Arial", 26) ASSET_DIR = r"C:\VVV" # Цвета WHITE = (255, 255, 255) BLACK = (0, 0, 0) GRAY = (210, 210, 210) DARK_GRAY = (100, 100, 100) BLUE = (40, 100, 180) GREEN = (40, 150, 40) RED = (180, 40, 40) ORANGE = (230, 160, 40) # ================= УТИЛИТЫ ================= def load_asset(filename, fallback_color=GRAY, w=100, h=80): path = os.path.join(ASSET_DIR, filename) if os.path.exists(path): try: img = pygame.image.load(path).convert_alpha() return img except: pass surf = pygame.Surface((w, h), pygame.SRCALPHA) surf.fill(fallback_color) txt = FONT.render(filename, True, BLACK) surf.blit(txt, (5, h//2-10)) return surf def draw_text(text, x, y, font=FONT, color=BLACK, center=False): surf = font.render(text, True, color) rect = surf.get_rect(center=(x, y)) if center else surf.get_rect(topleft=(x, y)) screen.blit(surf, rect) class Button: def __init__(self, x, y, w, h, text, callback, color=BLUE, hover_color=(60, 120, 200)): self.rect = pygame.Rect(x, y, w, h) self.text = text self.callback = callback self.color = color self.hover_color = hover_color self.hovered = False self.selected = False def draw(self): c = self.hover_color if self.hovered else self.color if self.selected: c = GREEN pygame.draw.rect(screen, c, self.rect, border_radius=6) pygame.draw.rect(screen, BLACK, self.rect, 2, border_radius=6) draw_text(self.text, self.rect.centerx, self.rect.centery, color=WHITE, font=FONT) def handle(self, event): if event.type == pygame.MOUSEMOTION: self.hovered = self.rect.collidepoint(event.pos) elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if self.hovered: if self.callback: self.callback() return True return False # ================= ИГРОВОЙ КЛАСС ================= class Game: def __init__(self): self.scene = 0 self.running = True self.message = "" self.msg_timer = 0 self.buttons = [] self.state = {} self.setup_scene() def show_msg(self, text, duration=2500): self.message = text self.msg_timer = duration def progress(self): self.scene += 1 self.buttons = [] self.state = {} self.message = "" if self.scene >= 5: self.show_msg("🎉 Поздравляем! Вы успешно прошли все этапы обучения!", 99999) else: self.setup_scene() def reset_scene(self): self.show_msg("❌ Задача не выполнена. Перезапуск сцены...", 2000) self.buttons = [] self.state = {} self.setup_scene() def setup_scene(self): self.buttons = [] if self.scene == 0: self.init_scene1() elif self.scene == 1: self.init_scene2() elif self.scene == 2: self.init_scene3() elif self.scene == 3: self.init_scene4() elif self.scene == 4: self.init_scene5() # ---------- СЦЕНА 1: Звонок ---------- def init_scene1(self): self.state = {"phone_clicked": False, "answered": False} self.phone_img = load_asset("phone.png", ORANGE, 120, 120) self.buttons.append(Button(400, 220, 220, 80, "📞 Принять звонок", self.click_phone, GRAY)) self.buttons.append(Button(80, 400, 280, 60, "Конечно, расскажите подробнее", lambda: self.check_call(0))) self.buttons.append(Button(380, 400, 280, 60, "Это не в нашей компетенции", lambda: self.check_call(1))) self.buttons.append(Button(680, 400, 280, 60, "Не можем помочь сейчас", lambda: self.check_call(2))) def click_phone(self): self.state["phone_clicked"] = True def check_call(self, idx): if not self.state["phone_clicked"]: return if idx == 0: self.progress() else: self.reset_scene() # ---------- СЦЕНА 2: Рабочий процесс ---------- def init_scene2(self): self.state = {"cal_clicked": False, "selected_doc": None, "docs_sorted": 0, "meetings_ok": 0} self.docs = [ {"id": 0, "name": "Отчет_Q1", "cat": "Отчеты", "sorted": False}, {"id": 1, "name": "Договор_А", "cat": "Договоры", "sorted": False}, {"id": 2, "name": "Запрос_Клиента", "cat": "Запросы", "sorted": False} ] self.meetings = [{"id": 0, "time": "10:00", "handled": False}, {"id": 1, "time": "15:00", "handled": False}] self.buttons.append(Button(350, 100, 300, 60, "📅 Календарь", self.click_cal, GRAY)) def click_cal(self): self.state["cal_clicked"] = True for i, d in enumerate(self.docs): cb = Button(150 + i*250, 250, 180, 50, d["name"], lambda i=i: self.select_doc(i), DARK_GRAY) cb.is_doc = True; cb.doc_id = i self.buttons.append(cb) for i, name in enumerate(["Отчеты", "Договоры", "Запросы"]): self.buttons.append(Button(100 + i*300, 450, 180, 50, f"📁 {name}", lambda c=name: self.sort_doc(c))) for i, m in enumerate(self.meetings): self.buttons.append(Button(200, 580, 180, 40, f"Встреча {m['time']}", lambda i=i: self.handle_meeting(i))) def select_doc(self, idx): if self.docs[idx]["sorted"]: return self.state["selected_doc"] = idx self.show_msg(f"Выбран: {self.docs[idx]['name']}. Кликните на папку.") def sort_doc(self, cat): sel = self.state["selected_doc"] if sel is None: return if self.docs[sel]["cat"] == cat: self.docs[sel]["sorted"] = True self.state["docs_sorted"] += 1 self.state["selected_doc"] = None self.show_msg("✅ Документ разложен верно!") else: self.show_msg("❌ Неверная категория!") self.check_scene2_win() def handle_meeting(self, idx): if not self.meetings[idx]["handled"]: self.meetings[idx]["handled"] = True self.state["meetings_ok"] += 1 self.show_msg("✅ Запрос на встречу обработан.") self.check_scene2_win() def check_scene2_win(self): if self.state["docs_sorted"] == 3 and self.state["meetings_ok"] == 2: self.progress() # ---------- СЦЕНА 3: Жалоба по Email ---------- def init_scene3(self): self.state = {"mail_open": False, "template": -1} self.templates = [ {"text": "Приносим извинения за неудобства. Решим проблему в течение 24ч.", "correct": True}, {"text": "Жалоба принята. Гарантий не даем.", "correct": False}, {"text": "Мы не можем повлиять на ситуацию.", "correct": False} ] self.buttons.append(Button(400, 150, 220, 60, "📧 Открыть почту", self.open_mail, GRAY)) for i, t in enumerate(self.templates): btn = Button(100, 350 + i*70, 824, 60, t["text"], lambda i=i: self.pick_template(i)) btn.is_template = True; btn.tpl_idx = i self.buttons.append(btn) self.buttons.append(Button(400, 600, 200, 50, "📤 Отправить", self.send_mail, GREEN)) self.email_text = "Здравствуйте! Получил заказ с браком. Требую замены или возврата." def open_mail(self): self.state["mail_open"] = True def pick_template(self, idx): self.state["template"] = idx for b in self.buttons: if hasattr(b, 'is_template'): b.selected = (b.tpl_idx == idx) def send_mail(self): if not self.state["mail_open"]: return if self.state["template"] != -1 and self.templates[self.state["template"]]["correct"]: self.progress() else: self.show_msg("❌ Клиент недоволен ответом. Попробуйте другой шаблон.") # ---------- СЦЕНА 4: Продажа по телефону ---------- def init_scene4(self): self.state = {"call_started": False, "chosen": -1} self.need = "Консультация + Скидка на первый заказ" self.offers = [ {"text": "Базовая консультация без бонусов.", "match": False}, {"text": "Персональная консультация + 10% скидка на первую покупку.", "match": True}, {"text": "Отправим каталог на email. Консультации нет.", "match": False} ] self.buttons.append(Button(400, 150, 220, 60, "📞 Принять звонок", self.start_call, GRAY)) for i, o in enumerate(self.offers): btn = Button(100, 350 + i*80, 824, 60, o["text"], lambda i=i: self.pick_offer(i)) btn.is_offer = True; btn.offer_idx = i self.buttons.append(btn) self.client_query = "Добрый день! Интересует ваш продукт. Хотелось бы получить консультацию и узнать про скидки." def start_call(self): self.state["call_started"] = True def pick_offer(self, idx): self.state["chosen"] = idx for b in self.buttons: if hasattr(b, 'is_offer'): b.selected = (b.offer_idx == idx) if self.offers[idx]["match"]: self.show_msg("✅ Отличная продажа! Клиент согласился.") self.progress() else: self.show_msg("❌ Предложение не подошло. Клиент отказался. Перезапуск...") self.reset_scene() # ---------- СЦЕНА 5: CRM-система ---------- def init_scene5(self): self.state = {"tasks_done": 0, "db_updated": False} self.tasks = [ {"id": 0, "desc": "Добавить контакт Иванова И.И.", "done": False}, {"id": 1, "desc": "Обновить статус заказа #482", "done": False}, {"id": 2, "desc": "Назначить встречу с ООО 'Вектор'", "done": False} ] for i, t in enumerate(self.tasks): btn = Button(150, 200 + i*90, 450, 60, f"☐ {t['desc']}", lambda i=i: self.complete_task(i), DARK_GRAY) btn.is_task = True btn.task_id = i self.buttons.append(btn) self.buttons.append(Button(700, 350, 200, 60, "💾 Обновить БД", self.update_db, BLUE)) def complete_task(self, idx): if self.tasks[idx]["done"]: return self.tasks[idx]["done"] = True self.state["tasks_done"] += 1 # Безопасное обновление кнопки без синтаксических ошибок for b in self.buttons: if hasattr(b, 'task_id') and b.task_id == idx: b.text = f"✅ {self.tasks[idx]['desc']}" b.color = GREEN self.show_msg("✅ Задача выполнена. Не забудьте обновить базу данных.") if self.state["tasks_done"] == 3 and self.state["db_updated"]: self.progress() def update_db(self): self.state["db_updated"] = True self.show_msg("✅ База данных обновлена.") if self.state["tasks_done"] == 3: self.progress() # ================= ГЛАВНЫЙ ЦИКЛ ================= def run(self): while self.running: dt = clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = False for btn in self.buttons: btn.handle(event) if self.msg_timer > 0: self.msg_timer -= dt if self.msg_timer <= 0: self.message = "" screen.fill(WHITE) draw_text(f"СЦЕНА {self.scene + 1} из 5", 20, 20, BIG_FONT, BLUE) if self.scene < 5: if self.scene == 0: screen.blit(self.phone_img, (450, 80)) if self.state.get("phone_clicked"): draw_text("Клиент: Здравствуйте, у меня возникла проблема с заказом, можете помочь?", 100, 350, BIG_FONT) else: draw_text("Кликните на телефон, чтобы принять звонок.", 300, 150, FONT, DARK_GRAY) elif self.scene == 1: if self.state.get("cal_clicked"): draw_text("Расписание открыто. Кликайте на документы -> папки. Подтвердите встречи.", 100, 180, FONT, GREEN) else: draw_text("Откройте календарь для начала работы.", 350, 200, FONT, DARK_GRAY) elif self.scene == 2: if self.state.get("mail_open"): draw_text(f"📩 ЖАЛОБА: {self.email_text}", 50, 250, BIG_FONT, RED) draw_text("Выберите шаблон ответа и нажмите 'Отправить'.", 100, 320, FONT, DARK_GRAY) else: draw_text("Нажмите на иконку почты, чтобы проверить входящие.", 250, 250, FONT, DARK_GRAY) elif self.scene == 3: if self.state.get("call_started"): draw_text(f"🗣 Клиент: {self.client_query}", 50, 250, BIG_FONT) draw_text(f"🎯 Потребность: {self.need}", 50, 300, FONT, ORANGE) else: draw_text("Примите звонок, чтобы начать диалог.", 350, 250, FONT, DARK_GRAY) elif self.scene == 4: draw_text("🖥 CRM-СИСТЕМА", 400, 100, BIG_FONT, BLUE) draw_text("Выполните задачи и обновите данные в базе.", 250, 150, FONT, DARK_GRAY) if self.state["db_updated"]: draw_text("✅ Базы обновлены", 700, 450, FONT, GREEN) if self.message: pygame.draw.rect(screen, (50, 50, 50, 230), (50, HEIGHT//2 - 40, WIDTH - 100, 80), border_radius=8) draw_text(self.message, WIDTH//2, HEIGHT//2, BIG_FONT, WHITE, True) for btn in self.buttons: btn.draw() pygame.display.flip() pygame.quit() sys.exit() if __name__ == "__main__": game = Game() game.run()