This commit is contained in:
Auric Vente 2024-07-19 05:28:49 -06:00
parent a8be025870
commit 91040eb390
6 changed files with 82 additions and 35 deletions

View File

@ -17,9 +17,9 @@ class Ant:
self.updated = now
self.name = ""
self.status = ""
self.method = "normal"
self.triumph = 0
self.hits = 0
self.color: tuple[int, int, int]
def to_dict(self) -> dict[str, Any]:
return {
@ -27,9 +27,9 @@ class Ant:
"updated": self.updated,
"name": self.name,
"status": self.status,
"method": self.method,
"hits": self.hits,
"triumph": self.triumph,
"color": self.color,
}
def from_dict(self, data: dict[str, Any]) -> None:
@ -37,12 +37,10 @@ class Ant:
self.updated = data["updated"]
self.name = data["name"]
self.status = data["status"]
self.method = data["method"]
self.hits = data["hits"]
self.triumph = data["triumph"]
c = data["color"]
self.color = (c[0], c[1], c[2])
def get_name(self) -> str:
return self.name or "Nameless"
@ -76,7 +74,6 @@ class Ants:
ant.created = now
ant.updated = now
ant.name = Utils.random_name()
ant.color = Utils.random_color(ant.name)
Ants.ants.append(ant)
image_path = Config.hatched_image_path
@ -136,16 +133,14 @@ class Ants:
return min(Ants.ants, key=lambda ant: ant.updated)
@staticmethod
def set_status(ant: Ant, status: str) -> None:
def set_status(ant: Ant, status: str, method: str) -> None:
from .game import Game
status = status.strip()
if not status:
return
ant.status = status
ant.method = method
ant.updated = Utils.now()
Game.add_status(ant)
Ants.save()

View File

@ -23,13 +23,19 @@ class Config:
space_1: int = 20
max_messages: int = 200
loop_delay_fast: int = 3_000
loop_delay_normal: int = 30_000
loop_delay_slow: int = 60_000
loop_delay_normal: int = 60_000
loop_delay_slow: int = 120_000
hatch_burst: int = 3
font_size: int = 20
info_separator: str = " - "
font_path: Path
emoji_font_path: Path
triumph_color: tuple[int, int, int] = (255, 255, 0)
hit_color: tuple[int, int, int] = (255, 0, 77)
triumph_icon: str = "😀"
hit_icon: str = "🎃"
triumph_message: str = "Scored a triumph"
hit_message: str = "Took a hit"
@staticmethod
def prepare() -> None:

View File

@ -31,8 +31,22 @@ class Game:
@staticmethod
def add_status(ant: Ant) -> None:
container = QHBoxLayout()
image_label = Game.get_image(Config.status_image_path, ant.color)
right_container = Game.make_right_container(ant.name, ant.status)
status = ant.status
color = None
if ant.method == "triumph":
total = f"({ant.triumph} total)"
status = f"{Config.triumph_icon} {Config.triumph_message} {total}"
color = Config.triumph_color
elif ant.method == "hit":
total = f"({ant.hits} total)"
status = f"{Config.hit_icon} {Config.hit_message} {total}"
color = Config.hit_color
elif ant.method == "thinking":
status = f"Thinking about {status}"
image_label = Game.get_image(Config.status_image_path, color)
right_container = Game.make_right_container(ant.name, status)
container.addWidget(image_label)
container.addSpacing(Config.space_1)
@ -40,9 +54,14 @@ class Game:
Game.add_view_container(container)
@staticmethod
def add_message(title: str, message: str, image_path: Path) -> None:
def add_message(
title: str,
message: str,
image_path: Path,
color: tuple[int, int, int] = (255, 255, 255),
) -> None:
container = QHBoxLayout()
image_label = Game.get_image(image_path, (255, 255, 255))
image_label = Game.get_image(image_path, color)
right_container = Game.make_right_container(title, message)
container.addWidget(image_label)
@ -65,7 +84,7 @@ class Game:
def make_right_container(title: str, message: str) -> QWidget:
root = QWidget()
container = QVBoxLayout()
container.setAlignment(Qt.AlignmentFlag.AlignTop)
container.setAlignment(Qt.AlignTop)
title_label = QLabel(title)
title_label.setStyleSheet("font-weight: bold;")
@ -83,24 +102,25 @@ class Game:
return root
@staticmethod
def get_image(image_path: Path, border_color: tuple[int, int, int]) -> QLabel:
def get_image(
image_path: Path, color: tuple[int, int, int] | None = None
) -> QLabel:
image_label = QLabel()
pixmap = QPixmap(str(image_path))
scaled_pixmap = pixmap.scaled(
Config.image_size,
pixmap.height(),
Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation,
Qt.KeepAspectRatio,
Qt.SmoothTransformation,
)
image_label.setPixmap(scaled_pixmap)
image_label.setFixedSize(scaled_pixmap.size())
border_rgb = Utils.get_rgb(border_color)
image_label.setStyleSheet(
f"border: 2px solid {border_rgb};"
)
if color:
rgb = Utils.get_rgb(color)
image_label.setStyleSheet(f"border: 2px solid {rgb};")
return image_label
@ -115,26 +135,31 @@ class Game:
num = random.randint(1, 10)
s = RandomSentence()
status = ""
method = "normal"
if num == 1:
ant.triumph += 1
status = f"😀 Scored a triumph ({ant.triumph} total)"
method = "triumph"
elif num == 2:
ant.hits += 1
status = f"🎃 Took a hit ({ant.hits} total)"
method = "hit"
elif (num == 3) and (num_ants > 1):
other = Ants.get_other(ant)
status = f"🫠 Is thinking about {other.name}"
status = other.name
method = "thinking"
elif num == 4:
status = s.simple_sentence()
elif num == 5:
status = s.bare_bone_sentence()
elif num == 6:
status = s.bare_bone_with_adjective()
elif num == 7:
status = Utils.get_random_emoji(3)
method = "thinking"
else:
status = s.sentence()
Ants.set_status(ant, status)
Ants.set_status(ant, status, method)
@staticmethod
def initial_fill() -> None:

View File

@ -1,10 +1,13 @@
from __future__ import annotations
import random
import colorsys
import time
from typing import ClassVar
from fontTools.ttLib import TTFont # type: ignore
from .config import Config
from .storage import Storage
@ -92,3 +95,16 @@ class Utils:
@staticmethod
def get_rgb(color: tuple[int, int, int]) -> str:
return f"rgb{color}"
@staticmethod
def get_random_character(font_path: str, num: int) -> str:
font = TTFont(font_path)
cmap = font["cmap"]
unicode_map = cmap.getBestCmap()
characters = [chr(code_point) for code_point in unicode_map]
selected = random.sample(characters, num)
return " ".join(selected)
@staticmethod
def get_random_emoji(num: int) -> str:
return Utils.get_random_character(str(Config.emoji_font_path), num)

View File

@ -29,7 +29,7 @@ class SpecialButton(QPushButton): # type: ignore
middleClicked = Signal()
def mousePressEvent(self, e: QMouseEvent) -> None:
if e.button() == Qt.MouseButton.MiddleButton:
if e.button() == Qt.MiddleButton:
self.middleClicked.emit()
else:
super().mousePressEvent(e)
@ -63,7 +63,7 @@ class Window:
central_widget = QWidget()
Window.root = QVBoxLayout()
central_widget.setLayout(Window.root)
Window.root.setAlignment(Qt.AlignmentFlag.AlignTop)
Window.root.setAlignment(Qt.AlignTop)
Window.window.setCentralWidget(central_widget)
Window.window.setWindowIcon(QIcon(str(Config.icon_path)))
@ -102,7 +102,9 @@ class Window:
btn_hatch.middleClicked.connect(lambda: Ants.hatch_burst())
btn_terminate = SpecialButton("Terminate")
btn_terminate.setToolTip("Terminate a random ant\nMiddle Click to terminate all")
btn_terminate.setToolTip(
"Terminate a random ant\nMiddle Click to terminate all"
)
btn_terminate.clicked.connect(lambda e: Ants.terminate())
btn_terminate.middleClicked.connect(lambda: Ants.terminate_all())
@ -135,7 +137,7 @@ class Window:
Window.view = QVBoxLayout()
parent.addLayout(Window.view)
Window.view.setAlignment(Qt.AlignmentFlag.AlignTop)
Window.view.setAlignment(Qt.AlignTop)
Window.scroll_area.setWidget(container)
Window.root.addWidget(Window.scroll_area)
@ -204,7 +206,9 @@ class Window:
root.setContentsMargins(0, 0, 0, 0)
container = QHBoxLayout()
Window.info = SpecialButton("---")
Window.info.setToolTip("Scroll to the bottom\nMiddle Click to scroll to the top")
Window.info.setToolTip(
"Scroll to the bottom\nMiddle Click to scroll to the top"
)
Window.info.clicked.connect(Window.to_bottom)
Window.info.middleClicked.connect(Window.to_top)
Window.info.setMinimumSize(35, 35)

View File

@ -1,3 +1,4 @@
PySide6 == 6.7.2
appdirs == 1.4.4
wonderwords == 2.2.0
fonttools == 4.53.1