Bot-Man-Toe/pyclient/client.py

73 lines
2.3 KiB
Python

"""
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)),
)