Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructure the project layout and improving package usage #71

Merged
merged 17 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ venv/
# vscode settings
.vscode

#databases
*.db
59 changes: 21 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,34 @@
# Willkommen zum Teamprojekt "Competition Server for Reinforcement Agents"!
# COMPRL

In diesem Github Repository wird ein großer Teil Eurer Arbeit stattfinden.
Bitte stellt sicher, dass Ihr
## Description
**COMPRL** is a versatile Python package designed for hosting game-like competitions among multiple remote clients. It's designed for easy and fast integration of new game types.

> [Anforderungen im Teamprojekt](COURSE-DESCRIPTION.md)
## Table of Contents

lest.
- [Getting Started](#getting-started)
- [Examples](#examples)

## GitHub Tour

- In [Issues](../../issues) könnt Ihr entdeckte Fehler (Bugs), User Stories und andere
Tickets festhalten, damit ihr nicht vergesst diese zu bearbeiten.
## Getting Started

- [Pull Requests](../../pulls) sind spezielle Issues, die dazu verwendet werden, um Code
Reviews durchzuführen.
### Server

- In [Projects](../../projects) könnt Ihr Euch ein Sprint Board anlegen, um die nächste
Iteration zu planen und Euren Fortschritt nachzuvollziehen. Eine Vorlage kann
[hier](https://github.com/se-tuebingen/teamprojekt-vorlage/projects/1) gefunden
werden.
To host your competition, implement a new game by inheriting from the `IGame` class provided by the `comprl.server.interfaces` module. Once your game is fully implemented, use a configuration file or command-line arguments to start the server with the desired configuration.

- Das [Wiki](../../wiki) kann genutzt werden, um zum Beispiel weitere inhaltliche
Anforderungen zu erfassen, die Definition-of-Done zu dokumentieren oder Protokolle und
Entscheidungen des Teams festzuhalten.
```sh
#display all possible command line arguments
python -m comprl.server --h

- [Actions](../../actions) erlauben Euch Continuous Integration (CI) und automatisiertes
Testen für jeden Pull Request und jedes Release einzurichten.
#run server by providing a config file
python -m comprl.server --config="path/to/config.toml"
```

# General
To run the server use:
```
python -m comprl.server.main
```
To run the client use:
```
python -m comprl.client.main
```
### Client

## Naming-Conventions
This project follows the [Google-Styleguide](https://google.github.io/styleguide/)
For implementing a new client, utilize the `comprl.client` package. Here, you can directly instantiate an `Agent` object or inherit from it. The only required implementation is the `get_step()` function, which is called with the corresponding action. Additionally, override other functions to receive and handle data about games being played or handle any errors that may occur. The flexibility provided by COMPRL allows you to tailor the client to your specific needs.

## External-Librarys
- [Twisted](https://twisted.org): We are using th AMP-Protocol
- [docs1](https://amp-protocol.net/), [docs2](https://twisted.org/documents/13.1.0/api/twisted.protocols.amp.html),
- [Developer Guide](https://docs.twisted.org/en/twisted-18.4.0/core/howto/amp.html)
- [API Documentation](https://docs.twisted.org/en/twisted-18.4.0/core/howto/amp.html)
- [AMP Exampels](https://docs.twisted.org/en/twisted-18.4.0/core/examples/index.html#amp-server-client-variants)
- [Gymnasium](https://gymnasium.farama.org) (maybe?)
## Examples


### Simple

This is a very simple game which checks is the sum of all received actions is greater than 10, if so the game ends.
5 changes: 5 additions & 0 deletions comprl/client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""
This module initializes the client package for the competition server.
"""

from .agent import Agent # noqa: F401
59 changes: 42 additions & 17 deletions comprl/client/agent.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
"""base class for agent"""
"""
This module contains the Agent class, used by the end-user connecting to the server.
"""

from typing import final
from .client import COMPClient


class COMPAgent:
"""agent interface"""
from comprl.client.interfaces import IAgent
from comprl.client import networking


class Agent(IAgent):
"""Agent used by the end-user connecting to the server.

This class represents an agent that interacts with the server. It provides methods
for registering event handlers and connecting to the server.
"""

def __init__(self) -> None:
self.client = COMPClient(agent=self)
pass
super().__init__()

def step(self, obv: list[float]) -> list[float]:
"""this is an abstract method for one step that the
agent makes and should be overwritten
@final
def event(self, func):
"""Decorator to register a function as an event handler.

Args:
obv (_type_): current environment
func (function): The function to be registered as an event handler.

Returns:
function: The registered event handler function.

Raises:
NotImplementedError: this method should be overwritten
"""
raise NotImplementedError()
setattr(self, func.__name__, func)
return func

@final
def run(self, token: str):
"""connects and authenticate the agent over the client with the server
def run(self, token: str, host: str = "localhost", port: int = 65335) -> None:
"""Connects the client to the server.

This method connects the client to the server using the specified token, host,
and port. It internally calls the `run` method of the base class to establish
the connection.

Args:
token (String): Token to verify the client
token (str): The token used for authentication.
host (str): The host address of the server. Defaults to "localhost".
port (int): The port number of the server. Defaults to 65335.

Returns:
None

"""
self.client.connect_client(token=token)
super().run(token)
networking.connect_agent(self, host, port)

def on_error(self, msg):
"""Called if an error occurred on the server side."""
print(f"Error: {msg}")
25 changes: 0 additions & 25 deletions comprl/client/client.py

This file was deleted.

106 changes: 0 additions & 106 deletions comprl/client/client_protocol.py

This file was deleted.

80 changes: 80 additions & 0 deletions comprl/client/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
This module contains the interface for the agent.
"""


class IAgent:
"""agent interface which could be used by the end-user"""

def run(self, token: str):
Cari1111 marked this conversation as resolved.
Show resolved Hide resolved
"""
Runs the agent with the specified token.

Args:
token (str): The token used for authentication.
"""
self.token = token

def auth(self) -> str:
"""
Returns the authentication token.

Returns:
str: The authentication token.
"""
return self.token

def is_ready(self) -> bool:
"""
Returns if the agent is ready to play.

Returns:
bool: True if the agent is ready to play, False otherwise.
"""
return True

def on_start_game(self, game_id: int) -> None:
"""
Called when a new game starts.

Args:
game_id (int): The ID of the new game.

Returns:
bool: True if the agent is ready to play, False otherwise.
"""
pass

def get_step(self, obv: list[float]) -> list[float]:
"""
Requests the agent's action based on the current observation.

Args:
obv (list[float]): The current observation.

Returns:
list[float]: The agent's action.
"""
raise NotImplementedError("step function not implemented")

def on_end_game(self, result, stats) -> None:
"""
Called when a game ends.

Args:
result: The result of the game.
stats: The statistics of the game.

Returns:
bool: True if the agent handled the end of the game, False otherwise.
"""
pass

def on_error(self, msg):
"""
Called when an error occurs.

Args:
msg: The error message.
"""
pass
17 changes: 0 additions & 17 deletions comprl/client/main.py

This file was deleted.

Loading
Loading