From 48cf21a1fdf064a34ea89c077f5e2c5ac7745fb6 Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Thu, 2 Jul 2026 00:11:05 +0200 Subject: [PATCH] Create Greedy agent --- agents/greedy.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++ server.py | 4 +- 2 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 agents/greedy.py diff --git a/agents/greedy.py b/agents/greedy.py new file mode 100644 index 0000000..f5115e3 --- /dev/null +++ b/agents/greedy.py @@ -0,0 +1,106 @@ +""" + This module contains a greedy agent that has little respect for risks and + downsides. All they care about is trying to win as fast as possible! +""" + +from __future__ import annotations + +import random + +from .agent import Agent, Payload + +class GreedyAgent(Agent): + """ + The greedy agent attempts the quickest way to win a game. + They do not care for risks. + """ + + def __init__(self) -> None: + """ + The greedy agent attempts the quickest way to win. In some games, + they act extremely aggressive, with little care for protection. + """ + + super().__init__( + name="Greedy agent", + author="Bram", + version="1.0.0", + profile={}, + ) + + self.add_tic_tac_toe(on_move=self.play_tic_tac_toe, profile={}) + self.add_royal_game_of_ur(on_move=self.play_royal_game_of_ur, profile={}) + + @staticmethod + def play_tic_tac_toe(payload : Payload) -> Payload: + """ + Play a game of tic-tac-toe. + + The board is arranged as follows: + + 1 | 2 | 3 + ---+---+--- + 4 | 5 | 6 + ---+---+--- + 7 | 8 | 9 + + :param payload: The incoming JSON that contains the game state. + :type payload: dict[str, Any] + :return: The move you wish to take. + :rtype: dict[str, Any] + """ + lines = [ + [ 1, 2, 3, ], + [ 4, 5, 6, ], + [ 7, 8, 9, ], + + [ 1, 4, 7, ], + [ 2, 5, 8, ], + [ 3, 6, 9, ], + + [ 1, 5, 9, ], + [ 3, 5, 7, ], + + ] + + lines_0 = set() + lines_1 = set() + lines_2 = set() + + for i in range(1, 10): + if payload.get(str(i), "") != "": + continue + + lines_0.add(i) + + for line in lines: + if i not in line: + continue + items = [ str(payload.get(str(l), "")) for l in line ] + + match items.count(payload.get("your_token", "X")): + case 1: + lines_1.add(i) + case 2: + lines_2.add(i) + + # If you can create 3 in a row, take it + if len(lines_2) > 0: + return { "move": random.choice(list(lines_2)) } + + # If you can create 2 in a row, take it + elif len(lines_1) > 0: + return { "move": random.choice(list(lines_1)) } + + # Otherwise, just pick something random + return { "move": random.choice(list(lines_0)) } + + @staticmethod + def play_royal_game_of_ur(payload : Payload) -> Payload: + """ + Play a game of Royal Game of Ur. + + In this game, we always care about moving the piece forward that + is already closest to the finish. + """ + return { "move": max(payload.get("valid_moves", [0])) } diff --git a/server.py b/server.py index a3c7c5b..a1231de 100644 --- a/server.py +++ b/server.py @@ -4,7 +4,7 @@ from __future__ import annotations -import agents +import agents.greedy from pyserver import PyServer @@ -15,7 +15,7 @@ def main() -> int: :return: Exit code :rtype: int """ - player = PyServer(agents.AgentOfChaos()) + player = PyServer(agents.greedy.GreedyAgent()) # Start listening for games player.start(