""" This module hosts the PyClient class. You can use this class to simulate games among mulltiple agents. """ from __future__ import annotations from .agent import Agent from .games import Game from .replay import GameReplay, Turn from dataclasses import dataclass from typing import Any, Generator @dataclass(frozen=True) class PyClient: """ Host games among multiple agents. """ debug : bool def gen_game(self, players : list[Agent], start : Game) -> Generator[Turn, None, None]: """ Generate a game by polling the players. :param players: All players that wish to participate. :type players: list[Agent] :param start: The start state of the game. :type start: Game :return: A generator that yields turns. :rtype: Generator[Turn, None, None] """ current_state = start while current_state.winner() is None: player = current_state.player_to_move() if len(players) < player: # Player not found! Make a default move. current_state = current_state.move_default() yield Turn(action={}, player=player, state=current_state) else: agent = players[player - 1] payload = agent.poll( game=current_state.game_name(), payload=current_state.as_seen_by(player=player), ) # Calculate move current_state = current_state.move(payload=payload) yield Turn(action=payload, player=player, state=current_state) def play_game(self, players : list[Agent], start : Game) -> GameReplay: """ Generate a game by polling the players. Collect all moves in a summary. :param players: All players that wish to participate. :type players: list[Agent] :param start: The start state of the game. :type start: Game :return: Summary describing how the game went. :rtype: GameReplay """ return GameReplay( game_name=start.game_name(), start=start, turns=list(self.gen_game(players=players, start=start)), )