From 2121944ad24da3abb701c7d928f5bbcb5247ec4d Mon Sep 17 00:00:00 2001 From: Auric Vente Date: Sun, 21 Jul 2024 00:27:44 -0600 Subject: [PATCH] Mods --- README.md | 2 + cromulant/ants.py | 84 +++++++++++++++++++++++++++++++++++---- cromulant/config.py | 2 +- cromulant/data/names.json | 6 +-- cromulant/game.py | 13 +++--- cromulant/utils.py | 22 ++++++++++ cromulant/window.py | 5 ++- 7 files changed, 114 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 1342796..88cd258 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ You watch who gets the most triumphs or the most hits. The ant with the highest score is shown in the footer. +You can also merge 2 ants into one, combining their names and score. + ## Usage Just open it, hatch some ants, and place it somewhere in your monitor. diff --git a/cromulant/ants.py b/cromulant/ants.py index 508b42e..081fdac 100644 --- a/cromulant/ants.py +++ b/cromulant/ants.py @@ -1,5 +1,6 @@ from __future__ import annotations +import re import random from typing import ClassVar, Any @@ -124,11 +125,16 @@ class Ants: Window.confirm("Terminate all ants?", action) @staticmethod - def random_ant() -> Ant | None: + def random_ant(ignore: list[Ant] | None = None) -> Ant | None: if Ants.empty(): return None - return random.choice(Ants.ants) + if ignore: + ants = [a for a in Ants.ants if a not in ignore] + else: + ants = Ants.ants + + return random.choice(ants) @staticmethod def get_names() -> list[str]: @@ -182,11 +188,6 @@ class Ants: Game.add_status(ant) Ants.save() - @staticmethod - def get_other(ant: Ant) -> Ant: - ants = [a for a in Ants.ants if a.name != ant.name] - return random.choice(ants) - @staticmethod def get_ants() -> None: objs = Storage.get_ants() @@ -231,3 +232,72 @@ class Ants: return None return top, top_score + + @staticmethod + def merge() -> None: + from .game import Game + + if len(Ants.ants) < 2: + return + + def split(ant: Ant) -> list[str]: + return re.split(r"[ -]", ant.name) + + def fill(words: list[str]) -> list[str]: + if len(words) < 2: + words.extend(Utils.random_word(2 - len(words))) + + words = [ + word if word.lower() != "of" else Utils.random_word()[0] for word in words + ] + + words = [Utils.capitalize(word) for word in words] + return [word.lower() if word == "de" else word for word in words] + + ant_1 = Ants.random_ant() + + if not ant_1: + return + + ant_2 = Ants.random_ant([ant_1]) + + if not ant_2: + return + + words_1 = split(ant_1) + words_2 = split(ant_2) + + words_1 = fill(words_1) + words_2 = fill(words_2) + + name = "" + + for _ in range(12): + name = f"{random.choice(words_1)} {random.choice(words_2)}" + + if (name == ant_1.name) or (name == ant_2.name): + continue + + if name in Utils.names: + continue + + if not name: + return + + Ants.ants.remove(ant_1) + Ants.ants.remove(ant_2) + now = Utils.now() + + ant = Ant() + ant.name = name + ant.created = now + ant.updated = now + ant.triumph = ant_1.triumph + ant_2.triumph + ant.hits = ant_1.hits + ant_2.hits + + Ants.ants.append(ant) + Ants.save() + + image_path = Config.hatched_image_path + Game.add_message("Merged", f"{ant.name} is born", image_path) + Game.update_info() diff --git a/cromulant/config.py b/cromulant/config.py index 2c5a14a..2254e1b 100644 --- a/cromulant/config.py +++ b/cromulant/config.py @@ -22,7 +22,7 @@ class Config: text_color: str = "#ffffff" image_size: int = 80 space_1: int = 20 - max_messages: int = 200 + max_updates: int = 250 loop_delay_fast: int = 1000 * 5 loop_delay_normal: int = 1000 * 60 * 1 loop_delay_slow: int = 1000 * 60 * 5 diff --git a/cromulant/data/names.json b/cromulant/data/names.json index ec3bc4f..7649ada 100644 --- a/cromulant/data/names.json +++ b/cromulant/data/names.json @@ -269,7 +269,7 @@ "Alfred Nobel", "Queen of Sheba", "Marcus Junius Brutus", - "Donatien Alphonse François de Sade, Marquis de Sade", + "Donatien Alphonse François de Sade", "Romulus Augustus", "Demosthenes", "James Joyce", @@ -793,7 +793,7 @@ "Dio Cassius", "Louis XVIII of France", "Martin of Tours", - "Bernard Montgomery, 1st Viscount Montgomery of Alamein", + "Bernard Montgomery", "Valens", "Malcolm X", "Anthony Hopkins", @@ -844,7 +844,7 @@ "Quintillus", "Søren Kierkegaard", "Sitting Bull", - "Robert Baden-Powell, 1st Baron Baden-Powell", + "Robert Baden-Powell", "Philip the Apostle", "Sergei Rachmaninoff", "Eva Perón", diff --git a/cromulant/game.py b/cromulant/game.py index 9ccbef3..c6086ac 100644 --- a/cromulant/game.py +++ b/cromulant/game.py @@ -11,8 +11,6 @@ from PySide6.QtWidgets import QWidget from PySide6.QtGui import QPixmap # type: ignore from PySide6.QtCore import QTimer -from wonderwords import RandomSentence # type: ignore - from .config import Config from .utils import Utils from .ants import Ant @@ -87,7 +85,7 @@ class Game: root.setLayout(container) Window.view.insertWidget(0, root) - while Window.view.count() > Config.max_messages: + while Window.view.count() > Config.max_updates: item = Window.view.takeAt(Window.view.count() - 1) if item.widget(): @@ -169,7 +167,6 @@ class Game: return num = random.randint(1, 10) - s = RandomSentence() status = "" method = "normal" @@ -183,11 +180,11 @@ class Game: status = Utils.random_name([]) method = "thinking" elif num == 4: - status = s.simple_sentence() + status = Utils.rand_sentence.simple_sentence() elif num == 5: - status = s.bare_bone_sentence() + status = Utils.rand_sentence.bare_bone_sentence() elif num == 6: - status = s.bare_bone_with_adjective() + status = Utils.rand_sentence.bare_bone_with_adjective() elif num == 7: status = Utils.random_emoji(3) method = "thinking" @@ -195,7 +192,7 @@ class Game: status = Utils.random_country([]) method = "travel" else: - status = s.sentence() + status = Utils.rand_sentence.sentence() Ants.set_status(ant, status, method) diff --git a/cromulant/utils.py b/cromulant/utils.py index 287bae0..8aa72a8 100644 --- a/cromulant/utils.py +++ b/cromulant/utils.py @@ -6,6 +6,7 @@ import time from datetime import datetime from typing import ClassVar +from wonderwords import RandomWord, RandomSentence # type: ignore from fontTools.ttLib import TTFont # type: ignore from .config import Config @@ -15,11 +16,15 @@ from .storage import Storage class Utils: names: ClassVar[list[str]] = [] countries: ClassVar[list[str]] = [] + rand_word: RandomWord + rand_sentence: RandomSentence @staticmethod def prepare() -> None: Utils.names = Storage.get_names() Utils.countries = Storage.get_countries() + Utils.rand_word = RandomWord() + Utils.rand_sentence = RandomSentence() @staticmethod def now() -> float: @@ -139,3 +144,20 @@ class Utils: def random_country(ignore: list[str]) -> str: filtered = [country for country in Utils.countries if country not in ignore] return random.choice(filtered) + + @staticmethod + def random_word(num: int = 1) -> list[str]: + words = [] + + for _ in range(num): + word = Utils.rand_word.word( + include_parts_of_speech=["nouns", "adjectives"], word_max_length=8 + ) + + words.append(word) + + return words + + @staticmethod + def capitalize(word: str) -> str: + return word[0].upper() + word[1:] \ No newline at end of file diff --git a/cromulant/window.py b/cromulant/window.py index 6ef0908..95c57b1 100644 --- a/cromulant/window.py +++ b/cromulant/window.py @@ -198,7 +198,8 @@ class Window: btn_hatch.clicked.connect(lambda e: Ants.hatch()) btn_hatch.middleClicked.connect(lambda: Ants.hatch_burst()) - btn_terminate = SpecialButton("Terminate") + btn_terminate = SpecialButton("Term") + btn_merge = SpecialButton("Merge") btn_terminate.setToolTip( "Terminate a random ant\nMiddle Click to terminate all" @@ -206,6 +207,7 @@ class Window: btn_terminate.clicked.connect(lambda e: Ants.terminate()) btn_terminate.middleClicked.connect(lambda: Ants.terminate_all()) + btn_merge.clicked.connect(lambda e: Ants.merge()) Window.speed = QComboBox() tooltip = "The speed of the updates\n" @@ -225,6 +227,7 @@ class Window: container.addWidget(btn_hatch) container.addWidget(btn_terminate) + container.addWidget(btn_merge) container.addWidget(Window.speed) container.addWidget(Window.filter)