93 lines
2.3 KiB
Python
93 lines
2.3 KiB
Python
"""
|
|
This module offers a small place to start building game clients from.
|
|
|
|
You can use this for:
|
|
|
|
- Learning how the system works.
|
|
- Debugging a game server.
|
|
- Debugging a game that behaves weirdly.
|
|
|
|
This module lets you host a game, let online servers participate in it,
|
|
and then analyze the outcome.
|
|
|
|
|
|
You can build several things with this:
|
|
|
|
1. You can build an AI trainer that trains on existing players.
|
|
2. You can build an ELO evaluator that compares the performance of various
|
|
strategies.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import pyclient
|
|
|
|
from pyclient import Agent, PyClient
|
|
from pyclient.games import TicTacToe
|
|
|
|
def main() -> int:
|
|
"""
|
|
Start a client, then use it to analyze one or more matches.
|
|
|
|
:return: Exit code
|
|
:rtype: int
|
|
"""
|
|
c = PyClient(debug=False)
|
|
|
|
players : list[Agent] = [
|
|
Agent.from_url(url="https://bmt001.noordstar.me/"),
|
|
Agent.from_url(url="https://bmt001.noordstar.me/"),
|
|
]
|
|
|
|
out = c.play_game(
|
|
players=players,
|
|
start=TicTacToe.empty(),
|
|
)
|
|
|
|
inspect_game(out)
|
|
|
|
return 0
|
|
|
|
def inspect_game(game : pyclient.GameReplay) -> None:
|
|
"""
|
|
Print a diagnostic of a played game to the terminal.
|
|
|
|
:param game: The results of a played game.
|
|
:type game: pyclient.GameReplay
|
|
"""
|
|
max_width = 40
|
|
hbar = max_width * '%'
|
|
|
|
def title(s : str) -> None:
|
|
"""
|
|
Show a title nice and clean in the middle
|
|
|
|
:param s: The title to display
|
|
:type s: str
|
|
"""
|
|
w = (max_width - len(s)) // 2
|
|
|
|
print(hbar)
|
|
print((w * ' ') + s.upper() + (w * ' '))
|
|
print(hbar)
|
|
|
|
# Show all moves made throughout the game
|
|
title("Turns taken")
|
|
for turn in game.turns:
|
|
print(f"Player {turn.player} : " + json.dumps(turn.action)[:max_width-12])
|
|
|
|
# Show all remaining variables in the finishing state of the game
|
|
title("Final state")
|
|
final_state = game.turns[-1].state
|
|
for k, v in final_state.to_dict().items():
|
|
print(f"{k} => {json.dumps(v)}")
|
|
|
|
# Some final (usually the most relevant) statistics
|
|
title("Result")
|
|
print(f"Total turns taken: {len(game.turns)}")
|
|
print(f"Result: {final_state.winner()}")
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|