diff --git a/cromulant/ants.py b/cromulant/ants.py index d606248..d3a1e54 100644 --- a/cromulant/ants.py +++ b/cromulant/ants.py @@ -167,20 +167,27 @@ class Ants: if changed: Ants.save() - @staticmethod - def most_hits() -> Ant | None: - if not len(Ants.ants): - return None - - return max(Ants.ants, key=lambda a: a.hits) - - @staticmethod - def most_triumph() -> Ant | None: - if not len(Ants.ants): - return None - - return max(Ants.ants, key=lambda a: a.triumph) - @staticmethod def random_name() -> str: return Utils.random_name(Ants.get_names()) + + @staticmethod + def get_top_ant() -> tuple[Ant, int] | None: + if not len(Ants.ants): + return None + + top = None + top_score = 0 + + # This could be a one-liner but I might expand the algorithm later + for ant in Ants.ants: + score = max(0, ant.triumph - ant.hits) + + if (not top) or (score > top_score): + top = ant + top_score = score + + if not top: + return None + + return top, top_score diff --git a/cromulant/game.py b/cromulant/game.py index cc6fe32..5e4fd29 100644 --- a/cromulant/game.py +++ b/cromulant/game.py @@ -172,7 +172,7 @@ class Game: elif num == 6: status = s.bare_bone_with_adjective() elif num == 7: - status = Utils.get_random_emoji(3) + status = Utils.random_emoji(3) method = "thinking" else: status = s.sentence() @@ -221,10 +221,12 @@ class Game: text.append("Hatch some ants") else: text.append(f"Ants:{nb}{len(Ants.ants)}") - triumph = Ants.most_triumph() + top = Ants.get_top_ant() - if triumph: - text.append(f"Top:{nb}{triumph.name} ({triumph.triumph})") + if top: + ant = top[0] + score = top[1] + text.append(f"Top:{nb}{ant.name} ({score})") Window.info.setText(Config.info_separator.join(text)) Window.info.adjustSize() diff --git a/cromulant/utils.py b/cromulant/utils.py index 5730b45..6e1db18 100644 --- a/cromulant/utils.py +++ b/cromulant/utils.py @@ -95,17 +95,23 @@ class Utils: return f"rgb{color}" @staticmethod - def get_random_character(font_path: str, num: int) -> str: + def 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) + + for _ in range(10): # Try up to 10 times + selected = random.sample(characters, num) + + if all((char.isprintable() and not char.isspace()) for char in selected): + return " ".join(selected) + + return "" @staticmethod - def get_random_emoji(num: int) -> str: - return Utils.get_random_character(str(Config.emoji_font_path), num) + def random_emoji(num: int) -> str: + return Utils.random_character(str(Config.emoji_font_path), num) @staticmethod def to_date(timestamp: float) -> str: