This commit is contained in:
Auric Vente 2024-07-19 00:33:51 -06:00
parent 8355b3dc9a
commit 95bc45af8b
4 changed files with 79 additions and 29 deletions

View File

@ -7,6 +7,8 @@ from .config import Config
from .utils import Utils from .utils import Utils
from .storage import Storage from .storage import Storage
from .window import Window
class Ant: class Ant:
def __init__(self) -> None: def __init__(self) -> None:
@ -61,15 +63,15 @@ class Ants:
Ants.get_ants() Ants.get_ants()
@staticmethod @staticmethod
def hatch() -> None: def hatch(num: int = 1) -> None:
from .game import Game from .game import Game
if len(Ants.ants) >= Config.max_ants: if len(Ants.ants) >= Config.max_ants:
Utils.print("Too many ants")
return return
now = Utils.now() now = Utils.now()
for _ in range(num):
ant = Ant() ant = Ant()
ant.created = now ant.created = now
ant.updated = now ant.updated = now
@ -77,11 +79,18 @@ class Ants:
ant.color = Utils.random_color() ant.color = Utils.random_color()
Ants.ants.append(ant) Ants.ants.append(ant)
Ants.save()
image_path = Config.hatched_image_path image_path = Config.hatched_image_path
Game.add_message("Hatched", f"{ant.name} is born", image_path) Game.add_message("Hatched", f"{ant.name} is born", image_path)
if len(Ants.ants) >= Config.max_ants:
break
Ants.save()
@staticmethod
def hatch_burst() -> None:
Ants.hatch(Config.hatch_burst)
@staticmethod @staticmethod
def terminate() -> None: def terminate() -> None:
from .game import Game from .game import Game
@ -96,6 +105,15 @@ class Ants:
image_path = Config.terminated_image_path image_path = Config.terminated_image_path
Game.add_message("Terminated", f"{ant.name} is gone", image_path) Game.add_message("Terminated", f"{ant.name} is gone", image_path)
@staticmethod
def terminate_all() -> None:
def action() -> None:
Ants.ants = []
Ants.save()
Window.clear_view()
Window.confirm("Terminate all ants?", action)
@staticmethod @staticmethod
def get_random_ant() -> Ant: def get_random_ant() -> Ant:
return random.choice(Ants.ants) return random.choice(Ants.ants)

View File

@ -25,6 +25,7 @@ class Config:
loop_delay_fast: int = 3_000 loop_delay_fast: int = 3_000
loop_delay_normal: int = 20_000 loop_delay_normal: int = 20_000
loop_delay_slow: int = 60_000 loop_delay_slow: int = 60_000
hatch_burst: int = 3
@staticmethod @staticmethod
def prepare() -> None: def prepare() -> None:

View File

@ -38,6 +38,7 @@ select = [
ignore = [ ignore = [
"W292", "W292",
"N802", "N802",
"N815",
] ]
exclude = [ exclude = [

View File

@ -1,5 +1,8 @@
from __future__ import annotations from __future__ import annotations
from typing import Any
from collections.abc import Callable
from PySide6.QtWidgets import QApplication # type: ignore from PySide6.QtWidgets import QApplication # type: ignore
from PySide6.QtWidgets import QMainWindow from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QWidget from PySide6.QtWidgets import QWidget
@ -11,12 +14,25 @@ from PySide6.QtWidgets import QScrollArea
from PySide6.QtWidgets import QComboBox from PySide6.QtWidgets import QComboBox
from PySide6.QtWidgets import QLayout from PySide6.QtWidgets import QLayout
from PySide6.QtWidgets import QSizePolicy from PySide6.QtWidgets import QSizePolicy
from PySide6.QtGui import QIcon # type: ignore from PySide6.QtWidgets import QMessageBox
from PySide6.QtGui import QMouseEvent # type: ignore
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt # type: ignore from PySide6.QtCore import Qt # type: ignore
from PySide6.QtCore import Signal
from .config import Config from .config import Config
class SpecialButton(QPushButton): # type: ignore
middleClicked = Signal()
def mousePressEvent(self, e: QMouseEvent) -> None:
if e.button() == Qt.MouseButton.MiddleButton:
self.middleClicked.emit()
else:
super().mousePressEvent(e)
class Window: class Window:
app: QApplication app: QApplication
window: QMainWindow window: QMainWindow
@ -51,21 +67,23 @@ class Window:
@staticmethod @staticmethod
def add_buttons() -> None: def add_buttons() -> None:
from .ants import Ants
from .game import Game from .game import Game
btn_hatch = QPushButton("Hatch") btn_hatch = SpecialButton("Hatch")
btn_terminate = QPushButton("Terminate") btn_hatch.clicked.connect(lambda e: Ants.hatch())
btn_hatch.middleClicked.connect(lambda: Ants.hatch_burst())
btn_close = QPushButton("Close") btn_terminate = SpecialButton("Terminate")
btn_terminate.clicked.connect(lambda e: Ants.terminate())
btn_hatch.clicked.connect(Window.hatch) btn_terminate.middleClicked.connect(lambda: Ants.terminate_all())
btn_terminate.clicked.connect(Window.terminate)
Window.speed = QComboBox() Window.speed = QComboBox()
Window.speed.addItems(["Fast", "Normal", "Slow"]) Window.speed.addItems(["Fast", "Normal", "Slow"])
Window.speed.setCurrentIndex(1) Window.speed.setCurrentIndex(1)
Window.speed.currentIndexChanged.connect(Game.update_speed) Window.speed.currentIndexChanged.connect(Game.update_speed)
btn_close = QPushButton("Close")
btn_close.clicked.connect(Window.close) btn_close.clicked.connect(Window.close)
layout = QHBoxLayout() layout = QHBoxLayout()
@ -90,18 +108,6 @@ class Window:
scroll_area.setWidget(container) scroll_area.setWidget(container)
Window.root.addWidget(scroll_area) Window.root.addWidget(scroll_area)
@staticmethod
def hatch() -> None:
from .ants import Ants
Ants.hatch()
@staticmethod
def terminate() -> None:
from .ants import Ants
Ants.terminate()
@staticmethod @staticmethod
def start() -> None: def start() -> None:
Window.window.show() Window.window.show()
@ -125,3 +131,27 @@ class Window:
@staticmethod @staticmethod
def expand(widget: QWidget) -> None: def expand(widget: QWidget) -> None:
widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
@staticmethod
def confirm(message: str, action: Callable[..., Any]) -> None:
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Icon.Question)
msg_box.setWindowTitle("Confirm")
msg_box.setText(message)
msg_box.setStandardButtons(
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
msg_box.setDefaultButton(QMessageBox.StandardButton.No)
msg_box.button(QMessageBox.StandardButton.Yes).clicked.connect(action)
msg_box.exec()
@staticmethod
def clear_view() -> None:
while Window.view.count():
item = Window.view.takeAt(0)
if item.widget():
item.widget().deleteLater()
elif item.layout():
Window.delete_layout(item.layout())