From 6cb5fdc8ec15d1b3dbb0a264b004d5ea026cdd26 Mon Sep 17 00:00:00 2001 From: Auric Vente Date: Thu, 18 Jul 2024 22:55:49 -0600 Subject: [PATCH] Mods --- cromulant/ants.py | 38 ++++++++++++++++-- cromulant/config.py | 16 ++++++-- cromulant/game.py | 96 ++++++++++++++++++++++++++++----------------- cromulant/utils.py | 4 ++ cromulant/window.py | 42 ++++++++------------ 5 files changed, 125 insertions(+), 71 deletions(-) diff --git a/cromulant/ants.py b/cromulant/ants.py index a51dc95..459e9f8 100644 --- a/cromulant/ants.py +++ b/cromulant/ants.py @@ -65,6 +65,8 @@ class Ants: @staticmethod def hatch() -> None: + from .game import Game + if len(Ants.ants) >= Config.max_ants: Utils.print("Too many ants") return @@ -79,11 +81,27 @@ class Ants: Ants.ants.append(ant) Ants.save() - Utils.print(f"Ant hatched: {ant.name}") + + image_path = Config.hatched_image_path + Game.add_message(f"{ant.name} is born", image_path) @staticmethod def terminate() -> None: - pass + from .game import Game + + if not len(Ants.ants): + return + + ant = Ants.get_random_ant() + Ants.ants.remove(ant) + Ants.save() + + image_path = Config.terminated_image_path + Game.add_message(f"{ant.name} was terminated", image_path) + + @staticmethod + def get_random_ant() -> Ant: + return random.choice(Ants.ants) @staticmethod def get_names() -> list[str]: @@ -97,7 +115,19 @@ class Ants: def get_lazy() -> Ant: return min(Ants.ants, key=lambda ant: ant.updated) - @staticmethod + def set_status(ant: Ant, status: str) -> None: + from .game import Game + + status = status.strip() + + if not status: + return + + ant.status = status + ant.updated = Utils.now() + Game.add_status(ant) + Ants.save() + def get_other(ant: Ant) -> Ant: ants = [a for a in Ants.ants if a.name != ant.name] - return random.choice(ants) + return random.choice(ants) \ No newline at end of file diff --git a/cromulant/config.py b/cromulant/config.py index a24f718..1aefaab 100644 --- a/cromulant/config.py +++ b/cromulant/config.py @@ -7,14 +7,20 @@ import appdirs # type: ignore class Config: title: str = "Cromulant" - width: int = 800 - height: int = 600 + width: int = 1000 + height: int = 800 max_ants: int = 100 here: Path ants_json: Path icon_path: Path - image_path: Path + status_image_path: Path + hatched_image_path: Path + terminated_image_path: Path names_json: Path + background_color: str = "#2c2c2c" + text_color: str = "#ffffff" + image_size: int = 50 + space_1: int = 25 @staticmethod def prepare() -> None: @@ -26,5 +32,7 @@ class Config: Config.ants_json.write_text("[]") Config.icon_path = Config.here / "img" / "icon_4.jpg" - Config.image_path = Config.here / "img" / "icon_7.jpg" + Config.status_image_path = Config.here / "img" / "icon_5.jpg" + Config.hatched_image_path = Config.here / "img" / "icon_7.jpg" + Config.terminated_image_path = Config.here / "img" / "icon_6.jpg" Config.names_json = Config.here / "data" / "names.json" diff --git a/cromulant/game.py b/cromulant/game.py index 9a7f06f..e24a227 100644 --- a/cromulant/game.py +++ b/cromulant/game.py @@ -1,71 +1,93 @@ from __future__ import annotations import random +from pathlib import Path -from PySide6.QtWidgets import QWidget # type: ignore -from PySide6.QtGui import QColor # type: ignore -from PySide6.QtGui import QPainter from PySide6.QtCore import Qt # type: ignore from PySide6.QtWidgets import QHBoxLayout from PySide6.QtWidgets import QLabel -from PySide6.QtGui import QPaintEvent +from PySide6.QtGui import QPixmap # type: ignore from wonderwords import RandomSentence # type: ignore +from .config import Config +from .utils import Utils from .ants import Ant from .ants import Ants from .window import Window -class CircleWidget(QWidget): # type: ignore - def __init__(self, color: tuple[int, int, int]) -> None: - super().__init__(None) - self.color = QColor(*color) - self.setFixedSize(20, 20) - - def paintEvent(self, event: QPaintEvent) -> None: - print(type(event)) - painter = QPainter(self) - painter.setRenderHint(QPainter.Antialiasing) - painter.setBrush(self.color) - painter.setPen(Qt.NoPen) - painter.drawEllipse(0, 0, self.width(), self.height()) - - class Game: @staticmethod def add_status(ant: Ant) -> None: container = QHBoxLayout() - circle = CircleWidget(ant.color) - text = QLabel(ant.status) - container.addWidget(circle) - container.addWidget(text) - Window.view.addLayout(container) + image_label = Game.get_image(Config.status_image_path, ant.color) + name = QLabel(ant.name) + status = QLabel(ant.status) + + container.addWidget(image_label) + container.addSpacing(Config.space_1) + container.addWidget(name) + container.addSpacing(Config.space_1) + container.addWidget(status) + + Window.view.insertLayout(0, container) @staticmethod - def log(message: str) -> None: - Window.log.append(message) + def add_message(message: str, image_path: Path) -> None: + container = QHBoxLayout() + image_label = Game.get_image(image_path, (255, 255, 255)) + message_label = QLabel(message) + + container.addWidget(image_label) + container.addSpacing(Config.space_1) + container.addWidget(message_label) + + Window.view.insertLayout(0, container) + + @staticmethod + def get_image(image_path: Path, border_color: tuple[int, int, int]) -> QLabel: + image_label = QLabel() + pixmap = QPixmap(str(image_path)) + + scaled_pixmap = pixmap.scaled( + Config.image_size, pixmap.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation + ) + + image_label.setPixmap(scaled_pixmap) + image_label.setFixedSize(scaled_pixmap.size()) # Set QLabel size to match QPixmap size + border_rgb = Utils.get_rgb(border_color) + image_label.setStyleSheet(f"bpyside6. how do i make this start at the top. top alignedorder: 2px solid {border_rgb};") + return image_label @staticmethod def get_status() -> None: + num_ants = len(Ants.ants) + + if not num_ants: + return + ant = Ants.get_lazy() num = random.randint(1, 10) + s = RandomSentence() + status = "" if num == 1: ant.hits += 1 - ant.status = f"Took a hit ({ant.hits} total)" + status = f"Took a hit ({ant.hits} total)" elif num == 2: ant.triumph += 1 - ant.status = f"Scored a triumph ({ant.triumph} total)" - elif num == 3: - s = RandomSentence() - ant.status = s.simple_sentence() - elif (num == 4) and (len(Ants.ants) > 1): + status = f"Scored a triumph ({ant.triumph} total)" + elif (num == 3) and (num_ants > 1): other = Ants.get_other(ant) - ant.status = f"Is thinking about {other.name}" + status = f"Is thinking about {other.name}" + elif num == 4: + status = s.simple_sentence() + elif num == 5: + status = s.bare_bone_sentence() + elif num == 6: + status = s.bare_bone_with_adjective() else: - s = RandomSentence() - ant.status = s.bare_bone_with_adjective() + status = s.sentence() - Game.add_status(ant) - Ants.save() + Ants.set_status(ant, status) diff --git a/cromulant/utils.py b/cromulant/utils.py index e33a444..058a426 100644 --- a/cromulant/utils.py +++ b/cromulant/utils.py @@ -85,3 +85,7 @@ class Utils: used = Ants.get_names() filtered = [name for name in Utils.names if name not in used] return random.choice(filtered) + + @staticmethod + def get_rgb(color: tuple[int, int, int]) -> str: + return f"rgb{color}" \ No newline at end of file diff --git a/cromulant/window.py b/cromulant/window.py index 659b01e..7234c52 100644 --- a/cromulant/window.py +++ b/cromulant/window.py @@ -8,9 +8,7 @@ from PySide6.QtWidgets import QGraphicsScene from PySide6.QtWidgets import QVBoxLayout from PySide6.QtWidgets import QPushButton from PySide6.QtWidgets import QHBoxLayout -from PySide6.QtWidgets import QTextEdit -from PySide6.QtWidgets import QLabel -from PySide6.QtGui import QPixmap # type: ignore +from PySide6.QtWidgets import QScrollArea from PySide6.QtGui import QIcon from PySide6.QtCore import Qt # type: ignore from PySide6.QtCore import QTimer @@ -24,7 +22,6 @@ class Window: root: QHBoxLayout view: QGraphicsView view_scene: QGraphicsScene - log: QTextEdit timer: QTimer @staticmethod @@ -32,7 +29,6 @@ class Window: Window.make() Window.add_buttons() Window.add_view() - Window.add_log() Window.start_timer() Window.start() @@ -46,9 +42,14 @@ class Window: central_widget = QWidget() Window.root = QVBoxLayout() central_widget.setLayout(Window.root) + Window.root.setAlignment(Qt.AlignTop) Window.window.setCentralWidget(central_widget) Window.window.setWindowIcon(QIcon(str(Config.icon_path))) - Window.app.setStyleSheet("QWidget { background-color: #3c3681; color: #FFF; }") + + style = f"QWidget {{ background-color: {Config.background_color}; \ + color: {Config.text_color}; font-size: 20px}}" + + Window.app.setStyleSheet(style) @staticmethod def add_buttons() -> None: @@ -69,28 +70,17 @@ class Window: @staticmethod def add_view() -> None: + scroll_area = QScrollArea() + scroll_area.setWidgetResizable(True) + + container = QWidget() + parent = QVBoxLayout(container) Window.view = QVBoxLayout() - Window.root.addLayout(Window.view) + parent.addLayout(Window.view) - @staticmethod - def add_log() -> None: - container = QHBoxLayout() - - image_label = QLabel() - pixmap = QPixmap(str(Config.image_path)) - scaled_pixmap = pixmap.scaled( - 100, pixmap.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation - ) - image_label.setPixmap(scaled_pixmap) - image_label.setFixedWidth(100) - container.addWidget(image_label) - - Window.log = QTextEdit() - Window.log.setReadOnly(True) - Window.log.setFixedHeight(100) - container.addWidget(Window.log) - - Window.root.addLayout(container) + Window.view.setAlignment(Qt.AlignTop) + scroll_area.setWidget(container) + Window.root.addWidget(scroll_area) @staticmethod def hatch() -> None: