""" 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])) }