tangled-agent 1.0.1
A package for tangled-agent
Requires Python: <4.0,>=3.8


# README for Building Your Own Agents

Version: 1.0.1

## Overview
This README provides instructions for building your own agents and testing them in a game using the provided example code.

## Getting Started
1. Install the tangled-agent package
```bash 
pip install tangled-agent
```
2. Generate a sample agent `agent-example.py`
```bash
python -m tangled_agent --generate-agent
```

## File Overview
### agent-example.py

```python

from __future__ import annotations

from typing import Tuple
from tangled_agent import GameAgentBase, Game, Vertex, Edge

class ExampleAgent(GameAgentBase):
    """
    Example agent class for playing the Snowdrop Quantum Tangled game.
    Implement the make_move method to make a move in the game.
    Use the game object to get the current game state and legal moves.
    Generate a move as a tuple of (move_type, move_index, move_state).
        move_type (int): The type of move to make (e.g. Game.MoveType.EDGE.value).
        move_index (int): The index of the move to make (e.g. the edge index).
        move_state (int): The state of the move to make (e.g. Game.Edge.State.FM).
    Valid move_type:
        Game.MoveType.EDGE.value: Set the state of an edge.
        Game.MoveType.VERTEX.value: Claim a vertex (once per player per game)
        Game.MoveType.QUIT.value: Quit the game.
    Valid move_state:
        For Game.MoveType.EDGE move:
            Game.Edge.State.NEITHER.value: Set the edge to have no preferred state.
            Game.Edge.State.FM.value: Set the edge to prefer a feromagnetic state.
            Game.Edge.State.NFM.value: Set the edge to prefer a non-feromagnetic state.
        For Game.MoveType.VERTEX move:
            Game.Vertex.State.P1.value: Claim the vertex for player 1.
            Game.Vertex.State.P2.value: Claim the vertex for player 2.
    """

    def make_move(self, game: Game) -> Tuple[int, int, int]:
        """
        Make a random legal move in the game.
        """
        import random

        legal_moves = game.get_legal_moves(self.id)

        # Look at the details and state of the game.
        state = game.get_game_state()

        if not legal_moves or (len(legal_moves) == 1 and legal_moves[0][0] == Game.MoveType.QUIT.value):
            print("No legal moves available. Game must be over.")
            return None

        while True:
            move = random.choice(legal_moves)
            if move[0] != Game.MoveType.QUIT.value:
                break

        return move
    
```
This file defines a simple agent that randomly chooses a move from all legal moves.

Rename this file and the class within it, and use it as a template to start building your own agent.

#### Key Components:
- `GameAgentBase`: The base class for all agents.
- `Game`: Represents the state of the game. Agents interrogate the game state from here to make decisions. This is read-only and shouldn't be changed.

#### Implementing Your Agent:
1. Inherit from `GameAgentBase`.
2. Implement the `def make_move(self, game: Game) -> Tuple[int, int, int]:` function. It must return a valid and legal move, which you can check against the list `game.get_legal_moves(self.id)` to validate. If your move isn't in this list, it's not valid.

#### Running the Game:
- To run a local game:
```bash
python -m tangled_agent --agent-class your_agent_file.YourAgentClass [--agent-class-2 your_other_agent_file.YourOtherAgentClass]
```
- To run a remote game, provide the game ID, host URL and player ID (and optionally force a regeneration of new credentials if you want to change identities):
```bash
python -m tangled_agent --game_id <game_id> --host <host_url> --agent your_agent_file.YourAgentClass [--agent-name <user-agent-id>] [--new-credentials] [--config <config-file>]
```
- Get a list of all parameters
```bash
python -m tangled_agent --help
```

Note that credentials are stored in a local file to cache them to avoid constant regeneration. If you want to use a different identity to play a game, you'll need to force `--new-credentials` to regenerate them. Credentials are generated by launching a browser window where you can log into the account you want to play the game with.

The optional `--agent-name` parameter is used to specify a specific agent-id to play the game as. Registered users can create a list of agent-ids in their account such that they can track win/loss/draw records for specific agents they wish to test. If not specified, it will use the `default` agent-id, which every user has.

Arguments can also be stored in a `.ini` file (default: `config.ini`) that will be used to populate the command line parameters if none are given, or `--config <config-file-name>`.

Example `config.ini`:
```
[DEFAULT]
game-id = "4c28f626-f585-44e5-98b5-ad244f9dcfec"
host = "http://localhost:9090"
agent-name = "my-random-agent"
```


## Testing Your Agent
1. Run the module with either or both agents set as your agent locally.
2. If you only specify one agent, the local game will play against a RandomRandy agent, which picks a random move each turn.

## Conclusion
Use this template to build and test your own agents. Experiment with different strategies and game setups to enhance your agent's performance. Please send me any suggestions for changes to make.