import pygame import random # --- Константы --- WIDTH, HEIGHT = 1000, 750 WHITE = (240, 240, 240) BLACK = (20, 20, 20) PANEL_COLOR = (44, 62, 80) ACCENT = (52, 152, 219) DISABLED = (127, 140, 141) DANGER = (231, 76, 60) SUCCESS = (46, 204, 113) GOLD = (241, 196, 15) PURPLE = (155, 89, 182) class FloatingText: def __init__(self, text, x, y, color): self.text = text self.x = x self.y = y self.color = color self.alpha = 255 self.life = 60 def update(self): self.y -= 1 self.alpha -= 4 self.life -= 1 def draw(self, screen, font): if self.life > 0: surf = font.render(self.text, True, self.color) surf.set_alpha(max(0, self.alpha)) screen.blit(surf, (self.x, self.y)) class UltimateAdminGame: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Администратор: Высшая Лига 2.0") self.clock = pygame.time.Clock() # Шрифты self.font_main = pygame.font.SysFont('Segoe UI', 19) self.font_bold = pygame.font.SysFont('Segoe UI', 24, bold=True) self.font_title = pygame.font.SysFont('Segoe UI', 32, bold=True) # Состояние игры self.reset_game() def reset_game(self): """Полный сброс всех параметров (для кнопки R)""" self.day = 1 self.hour = 9 self.week = 1 self.stats = {"Репутация": 70, "Бюджет": 200, "Стресс": 0} self.display_stats = {k: float(v) for k, v in self.stats.items()} # Новинка: Система навыков (случайный бонус при старте) self.perk = random.choice(["Экономный", "Стрессоустойчивый", "Любимчик"]) if self.perk == "Экономный": self.stats["Бюджет"] += 50 if self.perk == "Любимчик": self.stats["Репутация"] += 30 self.logs = [f"Старт: Ваша особенность — '{self.perk}'", "Понедельник. Пора разгребать завалы."] self.floating_texts = [] self.current_event = None self.game_over = False self.victory = False # Расширенный пул событий self.events_pool = [ {"title": "Кофемашина взорвалась", "desc": ["Весь пол в липком латте.", "Сотрудники в панике без кофеина."], "options": [{"text": "Вызвать мастера (-25 Бюджет, -1ч)", "cost": 25, "mod": (5, -25, -5), "time": 1}, {"text": "Купить растворимый кофе (-5 Бюджет, -1ч)", "cost": 5, "mod": (-10, -5, 5), "time": 1}, {"text": "Заставить всех работать так (-2ч)", "cost": 0, "mod": (-15, 0, 20), "time": 2}]}, {"title": "Вирусная атака", "desc": ["Бухгалтерия открыла письмо 'Ваш выигрыш'.", "Шифровальщик заблокировал сеть!"], "options": [{"text": "Заплатить хакерам (-60 Бюджет, -1ч)", "cost": 60, "mod": (0, -60, 15), "time": 1}, {"text": "Откатить систему (-4ч)", "cost": 0, "mod": (25, 0, 35), "time": 4}, {"text": "Изолировать сервер (-2ч)", "cost": 0, "mod": (-10, 0, 20), "time": 2}]}, {"title": "Визит инвестора", "desc": ["Важный гость приехал без предупреждения.", "Нужно произвести впечатление."], "options": [{"text": "Устроить фуршет (-40 Бюджет, -2ч)", "cost": 40, "mod": (35, -40, 10), "time": 2}, {"text": "Провести презентацию (-3ч)", "cost": 0, "mod": (20, 0, 45), "time": 3}, {"text": "Делегировать помощнику (-1ч)", "cost": 0, "mod": (5, 0, -5), "time": 1}]}, {"title": "Налоговая проверка", "desc": ["Инспектор требует документы за прошлый год.", "Кажется, мы что-то потеряли."], "options": [{"text": "Договориться на месте (-50 Бюджет)", "cost": 50, "mod": (-10, -50, 15), "time": 1}, {"text": "Искать архивы всю ночь (+40 Стресс)", "cost": 0, "mod": (30, 0, 40), "time": 4}, {"text": "Свалить на бухгалтера (-20 Репутация)", "cost": 0, "mod": (-20, 0, 10), "time": 2}]}, {"title": "Корпоратив", "desc": ["Пятница! Команда хочет расслабиться.", "От этого зависит климат в офисе."], "options": [{"text": "Заказать пиццу (-15 Бюджет)", "cost": 15, "mod": (10, -15, -10), "time": 1}, {"text": "Снять караоке-бар (-45 Бюджет)", "cost": 45, "mod": (35, -45, -30), "time": 3}, {"text": "Работать сверхурочно (+30 Стресс)", "cost": 0, "mod": (-20, 10, 30), "time": 2}]}, {"title": "Протечка крыши", "desc": ["Вода капает прямо на серверную стойку!", "Срочно нужны тазы или ремонт."], "options": [{"text": "Вызвать кровельщиков (-35 Бюджет)", "cost": 35, "mod": (10, -35, 5), "time": 1}, {"text": "Героически спасать железо (-4ч)", "cost": 0, "mod": (20, 0, 45), "time": 4}, {"text": "Ничего не делать (Риск!)", "cost": 0, "mod": (-40, -50, 20), "time": 2}]} ] self.pick_event() def pick_event(self): if not self.game_over and not self.victory: self.current_event = random.choice(self.events_pool) def create_floating(self, mod): r, b, s = mod pos_y = [180, 260, 340] changes = [r, b, s] for i, val in enumerate(changes): if val != 0: color = SUCCESS if val > 0 else DANGER if i == 2: color = DANGER if val > 0 else SUCCESS # Для стресса наоборот sign = "+" if val > 0 else "" self.floating_texts.append(FloatingText(f"{sign}{val}", 220, pos_y[i], color)) def handle_choice(self, option): if self.stats["Бюджет"] >= option["cost"]: # Применение перков s_mod = option["mod"][2] if self.perk == "Стрессоустойчивый" and s_mod > 0: s_mod = int(s_mod * 0.7) self.create_floating((option["mod"][0], option["mod"][1], s_mod)) self.stats["Репутация"] += option["mod"][0] self.stats["Бюджет"] += option["mod"][1] self.stats["Стресс"] += s_mod self.hour += option["time"] self.logs.append(f"{self.hour-option['time']}:00 - {option['text'].split(' (')[0]}") if self.hour >= 18: self.day += 1 self.hour = 9 self.stats["Стресс"] = max(0, self.stats["Стресс"] - 30) self.logs.append(f"--- День {self.day}. Ночной отдых -30 Стресс ---") if self.day > 5: # Конец рабочей недели self.day = 1 self.week += 1 self.stats["Бюджет"] += 150 self.logs.append(f"*** Неделя {self.week}! Получен бюджет +150 ***") if self.week > 4: self.victory = True self.pick_event() self.check_game_over() def check_game_over(self): if self.stats["Репутация"] <= 0 or self.stats["Бюджет"] <= 0 or self.stats["Стресс"] >= 180: self.game_over = True def update_animations(self): for key in self.stats: diff = self.stats[key] - self.display_stats[key] self.display_stats[key] += diff * 0.1 for ft in self.floating_texts[:]: ft.update() if ft.life <= 0: self.floating_texts.remove(ft) def draw_ui(self): self.screen.fill(WHITE) # Боковая панель pygame.draw.rect(self.screen, PANEL_COLOR, (0, 0, 260, HEIGHT)) self.draw_text(f"НЕДЕЛЯ {self.week}", 130, 45, GOLD, True, self.font_bold) self.draw_text(f"ДЕНЬ {self.day} | {self.hour}:00", 130, 90, WHITE, True, self.font_main) self.draw_text(f"Перк: {self.perk}", 130, 130, PURPLE, True, self.font_main) y = 200 for key in ["Репутация", "Бюджет", "Стресс"]: val = self.display_stats[key] real_val = self.stats[key] color = SUCCESS if (key != "Стресс" and real_val > 40) or (key == "Стресс" and real_val < 100) else DANGER self.draw_text(f"{key}: {int(real_val)}", 35, y, WHITE, False, self.font_main) pygame.draw.rect(self.screen, (60, 80, 100), (35, y + 30, 190, 10), border_radius=5) pygame.draw.rect(self.screen, color, (35, y + 30, max(0, min(val, 190)), 10), border_radius=5) y += 80 for ft in self.floating_texts: ft.draw(self.screen, self.font_bold) # Логи pygame.draw.rect(self.screen, (230, 230, 230), (280, 560, 700, 170), border_radius=15) for i, log in enumerate(self.logs[-5:]): self.draw_text(log, 300, 575 + (i*30), (100, 100, 100) if i < 4 else BLACK) # Событие if not self.game_over and not self.victory: pygame.draw.rect(self.screen, (255, 255, 255), (280, 20, 700, 520), border_radius=15) self.draw_text(self.current_event["title"], 630, 70, PANEL_COLOR, True, self.font_title) for i, line in enumerate(self.current_event["desc"]): self.draw_text(line, 630, 140 + (i*30), (80, 80, 80), True) for i, opt in enumerate(self.current_event["options"]): self.button(opt, 300 + (i*80)) elif self.game_over: self.overlay("ВЫ УВОЛЕНЫ", DANGER) elif self.victory: self.overlay("ВЫ - ГЕНИЙ УПРАВЛЕНИЯ", SUCCESS) def overlay(self, txt, color): pygame.draw.rect(self.screen, WHITE, (350, 250, 550, 250), border_radius=20) self.draw_text(txt, 625, 330, color, True, self.font_title) self.draw_text("R - Начать заново | ESC - Выход", 625, 400, BLACK, True, self.font_main) def draw_text(self, text, x, y, color=BLACK, center=False, font=None): f = font if font else self.font_main surf = f.render(str(text), True, color) rect = surf.get_rect(center=(x, y) if center else (x, y)) if not center: rect.topleft = (x, y) self.screen.blit(surf, rect) def button(self, option, y): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() rect = pygame.Rect(355, y, 550, 65) afford = self.stats["Бюджет"] >= option["cost"] hover = rect.collidepoint(mouse) and afford color = ACCENT if hover else (DISABLED if not afford else (100, 110, 120)) pygame.draw.rect(self.screen, color, rect, border_radius=12) self.draw_text(option["text"], rect.centerx, rect.centery, WHITE, True, self.font_bold) if hover and click[0]: pygame.time.delay(200) self.handle_choice(option) def run(self): running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False if event.key == pygame.K_r: self.reset_game() self.update_animations() self.draw_ui() pygame.display.flip() self.clock.tick(60) pygame.quit() if __name__ == "__main__": UltimateAdminGame().run()