Bot-Man-Toe/server.py

72 lines
2.1 KiB
Python

"""
This implementation describes the Agent of chaos. This agent mostly uses
randomness to determine which action to take.
In most games, the Agent of chaos makes two considerations:
1. Which moves are valid? Since invalid moves fallback to "default" moves,
this can destabilize the probability distribution, making some moves
more likely to be chosen than others. As a result, we refrain from
"invalid" moves and take the effort to filter them out.
2. What's a reasonable probability distribution? Sometimes, a uniform
distribution across all options doesn't make a lot of sense. For
example, imagine asking the agent every turn whether they want to
use their super duper special single-use ability, and leaving that to
a 50/50 call every turn. It feels much more random if such an ability
is more randomly used throughout the GAME, than to have every choice
be a uniformly distributed decision.
"""
from __future__ import annotations
import random
from pyserver import PyServer
from typing import Any
def main() -> int:
"""
Start a server.
:return: Exit code
:rtype: int
"""
player = PyServer(
name="Agent of chaos",
profile={
"me.noordstar.peanuts.author": "Bram",
"me.noordstar.peanuts.containerized": True,
},
import_name=__name__,
)
player.add_tic_tac_toe(on_move=play_tic_tac_toe, profile={})
player.start(
host="0.0.0.0",
port=5000,
)
return 0
def play_tic_tac_toe(payload : dict[str, Any]) -> dict[str, Any]:
"""
In tic-tac-toe, the agent of chaos makes uniformly distributed choices
on unclaimed tiles.
:param payload: The incoming game state.
:type payload: dict[str, Any]
:return: The agent of chaos' random choice
:rtype: dict[str, Any]
"""
options = [
int(k)
for k, v in dict(payload).items()
if k in "0123456789" and v == ""
]
return { "move": random.choice(options) }
if __name__ == "__main__":
raise SystemExit(main())