Bladeren bron

Обновить 'game.py'

u23-27goev 1 maand geleden
bovenliggende
commit
9f98898f37
1 gewijzigde bestanden met toevoegingen van 217 en 255 verwijderingen
  1. 217 255
      game.py

+ 217 - 255
game.py

@@ -1,257 +1,219 @@
-import tkinter as tk
-from tkinter import messagebox
-from PIL import Image, ImageTk
-
-class AdminGameGUI:
-    def __init__(self, root):
-        self.root = root
-        self.root.title("Административный персонал - Игра")
-        self.root.geometry("700x600")
-
-        # Ресурсы
-        self.reputation = 100
-        self.budget = 100
-        self.stress = 0
-
-        # Верхняя панель (ресурсы)
-        self.top_frame = tk.Frame(root)
-        self.top_frame.pack(pady=10)
-
-        self.reputation_label = tk.Label(self.top_frame, font=('Arial', 12))
-        self.reputation_label.pack()
-
-        self.budget_label = tk.Label(self.top_frame, font=('Arial', 12))
-        self.budget_label.pack()
-
-        self.stress_label = tk.Label(self.top_frame, font=('Arial', 12))
-        self.stress_label.pack()
-
-        # Картинка сцены
-        self.image_label = tk.Label(root)
-        self.image_label.pack(pady=10)
-
-        # Текст сцены
-        self.text_label = tk.Label(root, font=('Arial', 12), wraplength=600, justify="center")
-        self.text_label.pack(pady=10)
-
-        # Кнопки
-        self.button_frame = tk.Frame(root)
-        self.button_frame.pack(pady=20)
-
-        self.update_labels()
-        self.scene_1()
-
-    # ================= UI =================
-
-    def update_labels(self):
-        self.reputation_label.config(text=f"Репутация: {self.reputation}")
-        self.budget_label.config(text=f"Бюджет: {self.budget}")
-        self.stress_label.config(text=f"Стресс: {self.stress}")
-
-    def show_text(self, text):
-        self.text_label.config(text=text)
-
-    def create_buttons(self, choices):
-        self.clear_buttons()
-        for text, command in choices:
-            btn = tk.Button(self.button_frame, text=text, width=50, command=command)
-            btn.pack(pady=5)
-
-    def clear_buttons(self):
-        for widget in self.button_frame.winfo_children():
-            widget.destroy()
-
-    def load_image(self, path):
-        """
-        🔴 ВАЖНО: ВСТАВКА КАРТИНОК ЗДЕСЬ
-        Просто замени путь:
-        "images/scene1.jpg"
-        на свой файл
-        """
-        try:
-            img = Image.open(path)
-            img = img.resize((400, 250))
-            self.tk_img = ImageTk.PhotoImage(img)
-            self.image_label.config(image=self.tk_img)
-        except:
-            self.image_label.config(image="", text="(Нет изображения)")
+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.reputation <= 0:
-            self.end_game("Репутация упала до нуля. Компания закрылась.")
-            return True
-        if self.budget <= 0:
-            self.end_game("Бюджет исчерпан. Компания обанкротилась.")
-            return True
-        if self.stress >= 100:
-            self.end_game("Вы перегорели и уволились.")
-            return True
-        return False
-
-    # ================= СЦЕНЫ =================
-
-    def scene_1(self):
-        self.update_labels()
-        self.load_image("D:/grouppe2025-26 - 36/goev/xxxxx/images/scene1.jpg")  # 👉 КАРТИНКА СЦЕНЫ 1
-
-        self.show_text("Утро администратора. Что сделать первым?")
-
-        self.create_buttons([
-            ("Планировать встречи", self.s1_plan),
-            ("Финансовая отчетность", self.s1_finance),
-            ("Ответить на звонки", self.s1_calls),
-        ])
-
-    def s1_plan(self):
-        self.reputation += 10
-        self.stress += 5
-        if not self.check_game_over():
-            self.scene_2()
-
-    def s1_finance(self):
-        self.budget += 5
-        self.stress += 10
-        if not self.check_game_over():
-            self.scene_2()
-
-    def s1_calls(self):
-        self.reputation += 5
-        self.stress += 15
-        if not self.check_game_over():
-            self.scene_2()
-
-    # ---------
-
-    def scene_2(self):
-        self.update_labels()
-        self.load_image("D:/grouppe2025-26 - 36/goev/xxxxx/images/scene2.jpg")  # 👉 КАРТИНКА СЦЕНЫ 2
-
-        self.show_text("Отдел просит дорогое оборудование. Что делать?")
-
-        self.create_buttons([
-            ("Договориться о дешевом варианте", self.s2_soft),
-            ("Одобрить и перераспределить бюджет", self.s2_spend),
-            ("Жестко отказать", self.s2_refuse),
-        ])
-
-    def s2_soft(self):
-        self.budget -= 10
-        self.reputation += 10
-        if not self.check_game_over():
-            self.scene_3()
-
-    def s2_spend(self):
-        self.budget -= 25
-        self.stress += 10
-        if not self.check_game_over():
-            self.scene_3()
-
-    def s2_refuse(self):
-        self.reputation -= 10
-        self.stress += 5
-        if not self.check_game_over():
-            self.scene_3()
-
-    # ---------
-
-    def scene_3(self):
-        self.update_labels()
-        self.load_image("D:/grouppe2025-26 - 36/goev/xxxxx/images/scene3.png")  # 👉 КАРТИНКА СЦЕНЫ 3
-
-        self.show_text("Клиент жалуется. Как реагировать?")
-
-        self.create_buttons([
-            ("Проявить эмпатию", self.s3_empathy),
-            ("Дать четкий ответ", self.s3_clear),
-            ("Формальный отказ", self.s3_refuse),
-        ])
-
-    def s3_empathy(self):
-        self.reputation += 15
-        self.stress += 5
-        if not self.check_game_over():
-            self.scene_4()
-
-    def s3_clear(self):
-        self.reputation += 5
-        self.stress += 10
-        if not self.check_game_over():
-            self.scene_4()
-
-    def s3_refuse(self):
-        self.reputation -= 15
-        self.stress += 5
-        if not self.check_game_over():
-            self.scene_4()
-
-    # ---------
-
-    def scene_4(self):
-        self.update_labels()
-        self.load_image("D:/grouppe2025-26 - 36/goev/xxxxx/images/scene4.jpg")  # 👉 КАРТИНКА СЦЕНЫ 4
-
-        self.show_text("Как улучшить процессы?")
-
-        self.create_buttons([
-            ("Внедрить CRM", self.s4_crm),
-            ("Нанять сотрудника", self.s4_hire),
-            ("Ничего не делать", self.s4_skip),
-        ])
-
-    def s4_crm(self):
-        self.budget -= 30
-        self.stress -= 15
-        if not self.check_game_over():
-            self.scene_5()
-
-    def s4_hire(self):
-        self.budget -= 50
-        self.stress += 20
-        if not self.check_game_over():
-            self.scene_5()
-
-    def s4_skip(self):
-        self.stress += 15
-        if not self.check_game_over():
-            self.scene_5()
-
-    # ---------
-
-    def scene_5(self):
-        self.update_labels()
-        self.load_image("D:/grouppe2025-26 - 36/goev/xxxxx/images/scene5.jpg")  # 👉 КАРТИНКА СЦЕНЫ 5
-
-        result = "Итог:\n"
-
-        if self.reputation > 70:
-            result += "Отличная работа с клиентами\n"
-        else:
-            result += "Нужно улучшить коммуникацию\n"
-
-        if self.budget > 50:
-            result += "Хорошее управление бюджетом\n"
-        else:
-            result += "Слабый финансовый контроль\n"
-
-        if self.stress < 50:
-            result += "Вы стрессоустойчивы\n"
-        else:
-            result += "Высокий уровень стресса\n"
-
-        self.show_text(result)
-        self.clear_buttons()
-
-        tk.Button(self.button_frame, text="Выход", command=self.root.quit).pack(pady=10)
-
-    # ---------
-
-    def end_game(self, text):
-        self.show_text(text)
-        self.clear_buttons()
-        tk.Button(self.button_frame, text="Выход", command=self.root.quit).pack()
-
-
-# Запуск
-root = tk.Tk()
-game = AdminGameGUI(root)
-root.mainloop()
+        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()