This commit is contained in:
Auric Vente 2024-07-18 21:08:11 -06:00
parent fa1f5301ae
commit c95dab8e57
9 changed files with 120 additions and 48 deletions

0
cromulant/__init__.py Normal file
View File

View File

@ -1,4 +1,6 @@
from __future__ import annotations
import random
from typing import ClassVar, Any
from .config import Config
@ -76,7 +78,7 @@ class Ants:
ant.color = Utils.random_color()
Ants.ants.append(ant)
Storage.save_ants(Ants.ants)
Ants.save()
Utils.print(f"Ant hatched: {ant.name}")
@staticmethod
@ -85,4 +87,17 @@ class Ants:
@staticmethod
def get_names() -> list[str]:
return [ant.name for ant in Ants.ants]
return [ant.name for ant in Ants.ants]
@staticmethod
def save() -> None:
Storage.save_ants(Ants.ants)
@staticmethod
def get_lazy() -> Ant:
return min(Ants.ants, key=lambda ant: ant.updated)
@staticmethod
def get_other(ant: Ant) -> Ant:
ants = [a for a in Ants.ants if a.name != ant.name]
return random.choice(ants)

View File

@ -1,20 +1,21 @@
from __future__ import annotations
from pathlib import Path
import appdirs # type: ignore
class Config:
title = "Cromulant"
width = 800
height = 600
max_ants = 100
here: str
title: str = "Cromulant"
width: int = 800
height: int = 600
max_ants: int = 100
here: Path
ants_json: Path
icon_path: Path
image_path: Path
names_json: Path
@staticmethod
def prepare() -> None:
Config.here = Path(__file__).parent
@ -26,4 +27,4 @@ class Config:
Config.icon_path = Config.here / "img" / "icon_4.jpg"
Config.image_path = Config.here / "img" / "icon_7.jpg"
Config.names_json = Config.here / "data" / "names.json"
Config.names_json = Config.here / "data" / "names.json"

View File

@ -1,21 +1,30 @@
from PySide6.QtWidgets import QWidget
from PySide6.QtGui import QColor
from __future__ import annotations
import random
from PySide6.QtWidgets import QWidget # type: ignore
from PySide6.QtGui import QColor # type: ignore
from PySide6.QtGui import QPainter
from PySide6.QtCore import Qt
from PySide6.QtCore import Qt # type: ignore
from PySide6.QtWidgets import QHBoxLayout
from PySide6.QtWidgets import QLabel
from PySide6.QtGui import QPaintEvent
from wonderwords import RandomSentence # type: ignore
from .ants import Ant
from .ants import Ants
from .window import Window
class CircleWidget(QWidget):
def __init__(self, color, parent=None):
super().__init__(parent)
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):
def paintEvent(self, event: QPaintEvent) -> None:
print(type(event))
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setBrush(self.color)
@ -25,16 +34,38 @@ class CircleWidget(QWidget):
class Game:
@staticmethod
def update_view() -> None:
for ant in Ants.ants:
container = QHBoxLayout()
circle = CircleWidget(ant.color)
text = QLabel(ant.status)
container.addWidget(circle)
container.addWidget(text)
Window.view.addLayout(container)
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)
@staticmethod
def log(message: str) -> None:
Window.log.append(message)
Window.log.append(message)
@staticmethod
def get_status() -> None:
ant = Ants.get_lazy()
num = random.randint(1, 10)
if num == 1:
ant.hits += 1
ant.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):
other = Ants.get_other(ant)
ant.status = f"Is thinking about {other.name}"
else:
s = RandomSentence()
ant.status = s.bare_bone_with_adjective()
Game.add_status(ant)
Ants.save()

View File

@ -35,6 +35,11 @@ select = [
"PLR1711",
]
ignore = [
"W292",
"N802",
]
exclude = [
"pyperclip.py",
"tests.py",

View File

@ -1,5 +1,7 @@
from __future__ import annotations
import json
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any
from .config import Config
@ -9,18 +11,18 @@ if TYPE_CHECKING:
class Storage:
@staticmethod
def get_ants() -> None:
def get_ants() -> Any:
with Config.ants_json.open() as file:
return json.load(file)
@staticmethod
def save_ants(ants: list["Ant"]) -> None:
def save_ants(ants: list[Ant]) -> None:
objs = [ant.to_dict() for ant in ants]
with Config.ants_json.open("w") as file:
json.dump(objs, file)
@staticmethod
def get_names() -> None:
def get_names() -> Any:
with Config.names_json.open() as file:
return json.load(file)
return json.load(file)

View File

@ -1,11 +1,15 @@
from __future__ import annotations
import random
import colorsys
import time
from typing import ClassVar
from .storage import Storage
class Utils:
names: list[str] = []
names: ClassVar[list[str]] = []
@staticmethod
def prepare() -> None:
@ -64,9 +68,14 @@ class Utils:
print(text) # noqa: T201
@staticmethod
def random_color() -> str:
h,s,l = random.random(), 0.5 + random.random()/2.0, 0.4 + random.random()/5.0
r, g, b = [int(256*i) for i in colorsys.hls_to_rgb(h,l,s)]
def random_color() -> tuple[int, int, int]:
h, s, l = (
random.random(),
0.5 + random.random() / 2.0,
0.4 + random.random() / 5.0,
)
r, g, b = (int(256 * i) for i in colorsys.hls_to_rgb(h, l, s))
return r, g, b
@staticmethod
@ -75,4 +84,4 @@ class Utils:
used = Ants.get_names()
filtered = [name for name in Utils.names if name not in used]
return random.choice(filtered)
return random.choice(filtered)

View File

@ -10,9 +10,10 @@ 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
from PySide6.QtGui import QPixmap # type: ignore
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt
from PySide6.QtCore import Qt # type: ignore
from PySide6.QtCore import QTimer
from .config import Config
@ -24,6 +25,7 @@ class Window:
view: QGraphicsView
view_scene: QGraphicsScene
log: QTextEdit
timer: QTimer
@staticmethod
def prepare() -> None:
@ -31,6 +33,7 @@ class Window:
Window.add_buttons()
Window.add_view()
Window.add_log()
Window.start_timer()
Window.start()
@staticmethod
@ -51,18 +54,15 @@ class Window:
def add_buttons() -> None:
btn_hatch = QPushButton("Hatch")
btn_terminate = QPushButton("Terminate")
btn_update = QPushButton("Update")
btn_close = QPushButton("Close")
btn_hatch.clicked.connect(Window.hatch)
btn_terminate.clicked.connect(Window.terminate)
btn_update.clicked.connect(Window.update_view)
btn_close.clicked.connect(Window.close)
layout = QHBoxLayout()
layout.addWidget(btn_hatch)
layout.addWidget(btn_terminate)
layout.addWidget(btn_update)
layout.addWidget(btn_close)
Window.root.addLayout(layout)
@ -78,7 +78,9 @@ class Window:
image_label = QLabel()
pixmap = QPixmap(str(Config.image_path))
scaled_pixmap = pixmap.scaled(100, pixmap.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
scaled_pixmap = pixmap.scaled(
100, pixmap.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation
)
image_label.setPixmap(scaled_pixmap)
image_label.setFixedWidth(100)
container.addWidget(image_label)
@ -90,21 +92,27 @@ class Window:
Window.root.addLayout(container)
@staticmethod
def update_view() -> None:
from .game import Game
Game.update_view()
@staticmethod
def hatch() -> None:
from .ants import Ants
Ants.hatch()
@staticmethod
def terminate() -> None:
from .ants import Ants
Ants.terminate()
@staticmethod
def start_timer() -> None:
from .game import Game
interval_ms = 3_000
Window.timer = QTimer()
Window.timer.timeout.connect(Game.get_status)
Window.timer.start(interval_ms)
@staticmethod
def start() -> None:
Window.window.show()

View File

@ -1,2 +1,3 @@
PySide6 == 6.7.2
appdirs == 1.4.4
appdirs == 1.4.4
wonderwords == 2.2.0