This commit is contained in:
Auric Vente 2024-07-18 22:55:49 -06:00
parent c95dab8e57
commit 6cb5fdc8ec
5 changed files with 125 additions and 71 deletions

View File

@ -65,6 +65,8 @@ class Ants:
@staticmethod @staticmethod
def hatch() -> None: def hatch() -> None:
from .game import Game
if len(Ants.ants) >= Config.max_ants: if len(Ants.ants) >= Config.max_ants:
Utils.print("Too many ants") Utils.print("Too many ants")
return return
@ -79,11 +81,27 @@ class Ants:
Ants.ants.append(ant) Ants.ants.append(ant)
Ants.save() 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 @staticmethod
def terminate() -> None: 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 @staticmethod
def get_names() -> list[str]: def get_names() -> list[str]:
@ -97,7 +115,19 @@ class Ants:
def get_lazy() -> Ant: def get_lazy() -> Ant:
return min(Ants.ants, key=lambda ant: ant.updated) 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: def get_other(ant: Ant) -> Ant:
ants = [a for a in Ants.ants if a.name != ant.name] ants = [a for a in Ants.ants if a.name != ant.name]
return random.choice(ants) return random.choice(ants)

View File

@ -7,14 +7,20 @@ import appdirs # type: ignore
class Config: class Config:
title: str = "Cromulant" title: str = "Cromulant"
width: int = 800 width: int = 1000
height: int = 600 height: int = 800
max_ants: int = 100 max_ants: int = 100
here: Path here: Path
ants_json: Path ants_json: Path
icon_path: Path icon_path: Path
image_path: Path status_image_path: Path
hatched_image_path: Path
terminated_image_path: Path
names_json: Path names_json: Path
background_color: str = "#2c2c2c"
text_color: str = "#ffffff"
image_size: int = 50
space_1: int = 25
@staticmethod @staticmethod
def prepare() -> None: def prepare() -> None:
@ -26,5 +32,7 @@ class Config:
Config.ants_json.write_text("[]") Config.ants_json.write_text("[]")
Config.icon_path = Config.here / "img" / "icon_4.jpg" 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" Config.names_json = Config.here / "data" / "names.json"

View File

@ -1,71 +1,93 @@
from __future__ import annotations from __future__ import annotations
import random 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.QtCore import Qt # type: ignore
from PySide6.QtWidgets import QHBoxLayout from PySide6.QtWidgets import QHBoxLayout
from PySide6.QtWidgets import QLabel from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QPaintEvent from PySide6.QtGui import QPixmap # type: ignore
from wonderwords import RandomSentence # type: ignore from wonderwords import RandomSentence # type: ignore
from .config import Config
from .utils import Utils
from .ants import Ant from .ants import Ant
from .ants import Ants from .ants import Ants
from .window import Window 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: class Game:
@staticmethod @staticmethod
def add_status(ant: Ant) -> None: def add_status(ant: Ant) -> None:
container = QHBoxLayout() container = QHBoxLayout()
circle = CircleWidget(ant.color) image_label = Game.get_image(Config.status_image_path, ant.color)
text = QLabel(ant.status) name = QLabel(ant.name)
container.addWidget(circle) status = QLabel(ant.status)
container.addWidget(text)
Window.view.addLayout(container) 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 @staticmethod
def log(message: str) -> None: def add_message(message: str, image_path: Path) -> None:
Window.log.append(message) 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 @staticmethod
def get_status() -> None: def get_status() -> None:
num_ants = len(Ants.ants)
if not num_ants:
return
ant = Ants.get_lazy() ant = Ants.get_lazy()
num = random.randint(1, 10) num = random.randint(1, 10)
s = RandomSentence()
status = ""
if num == 1: if num == 1:
ant.hits += 1 ant.hits += 1
ant.status = f"Took a hit ({ant.hits} total)" status = f"Took a hit ({ant.hits} total)"
elif num == 2: elif num == 2:
ant.triumph += 1 ant.triumph += 1
ant.status = f"Scored a triumph ({ant.triumph} total)" status = f"Scored a triumph ({ant.triumph} total)"
elif num == 3: elif (num == 3) and (num_ants > 1):
s = RandomSentence()
ant.status = s.simple_sentence()
elif (num == 4) and (len(Ants.ants) > 1):
other = Ants.get_other(ant) 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: else:
s = RandomSentence() status = s.sentence()
ant.status = s.bare_bone_with_adjective()
Game.add_status(ant) Ants.set_status(ant, status)
Ants.save()

View File

@ -85,3 +85,7 @@ class Utils:
used = Ants.get_names() used = Ants.get_names()
filtered = [name for name in Utils.names if name not in used] filtered = [name for name in Utils.names if name not in used]
return random.choice(filtered) return random.choice(filtered)
@staticmethod
def get_rgb(color: tuple[int, int, int]) -> str:
return f"rgb{color}"

View File

@ -8,9 +8,7 @@ from PySide6.QtWidgets import QGraphicsScene
from PySide6.QtWidgets import QVBoxLayout from PySide6.QtWidgets import QVBoxLayout
from PySide6.QtWidgets import QPushButton from PySide6.QtWidgets import QPushButton
from PySide6.QtWidgets import QHBoxLayout from PySide6.QtWidgets import QHBoxLayout
from PySide6.QtWidgets import QTextEdit from PySide6.QtWidgets import QScrollArea
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QPixmap # type: ignore
from PySide6.QtGui import QIcon from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt # type: ignore from PySide6.QtCore import Qt # type: ignore
from PySide6.QtCore import QTimer from PySide6.QtCore import QTimer
@ -24,7 +22,6 @@ class Window:
root: QHBoxLayout root: QHBoxLayout
view: QGraphicsView view: QGraphicsView
view_scene: QGraphicsScene view_scene: QGraphicsScene
log: QTextEdit
timer: QTimer timer: QTimer
@staticmethod @staticmethod
@ -32,7 +29,6 @@ class Window:
Window.make() Window.make()
Window.add_buttons() Window.add_buttons()
Window.add_view() Window.add_view()
Window.add_log()
Window.start_timer() Window.start_timer()
Window.start() Window.start()
@ -46,9 +42,14 @@ class Window:
central_widget = QWidget() central_widget = QWidget()
Window.root = QVBoxLayout() Window.root = QVBoxLayout()
central_widget.setLayout(Window.root) central_widget.setLayout(Window.root)
Window.root.setAlignment(Qt.AlignTop)
Window.window.setCentralWidget(central_widget) Window.window.setCentralWidget(central_widget)
Window.window.setWindowIcon(QIcon(str(Config.icon_path))) 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 @staticmethod
def add_buttons() -> None: def add_buttons() -> None:
@ -69,28 +70,17 @@ class Window:
@staticmethod @staticmethod
def add_view() -> None: def add_view() -> None:
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
container = QWidget()
parent = QVBoxLayout(container)
Window.view = QVBoxLayout() Window.view = QVBoxLayout()
Window.root.addLayout(Window.view) parent.addLayout(Window.view)
@staticmethod Window.view.setAlignment(Qt.AlignTop)
def add_log() -> None: scroll_area.setWidget(container)
container = QHBoxLayout() Window.root.addWidget(scroll_area)
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)
@staticmethod @staticmethod
def hatch() -> None: def hatch() -> None: