A minimal SDK for authoring Rock-Paper-Scissors strategies compatible with the RPS Arena backend.
Project description
rpsa-sdk
A minimal, easy-to-use SDK for building Rock-Paper-Scissors strategies in Python. It provides:
- A base
Strategyinterface you can subclass to ensure correct method signatures. - Utility helper functions for common patterns (random play, countering, frequency analysis).
- Optional ML-model integration so you can plug in your own predictive model.
Table of Contents
- Installation
- Getting Started
- Core Interface:
Strategy - Utility Helpers
- Writing Your Own Strategy
- Example:
FrequencyStrategy - Running in a Contest
Installation
Install directly from PyPI:
pip install rpsa-sdk
Getting Started
Import the SDK components you need:
from rpsa_sdk.strategy import Strategy
from rpsa_sdk.helpers import random_move, counter_move, most_common
-
Strategy
An abstract base class. Subclass this and implement two methods:play(): Decide and return your next move ("rock","paper", or"scissors").handle_moves(): Update your internal state after each round, given your own move and the opponent’s move.
-
Helpers
Utility functions to speed up development:random_move()— returns a uniformly random choice of rock, paper, or scissors.counter_move(x)— returns the move that defeats the given movex.most_common(history, idx)— from a list of(own_move, opponent_move)tuples, finds the most frequent move at positionidx(use 0 or 1).
Core Interface: Strategy
All custom strategies must subclass Strategy:
class Strategy(ABC):
"""
Base class for RPS strategies.
Attributes:
name: ClassVar[str] # Unique strategy identifier
model: Any # Optional ML artifact
"""
name: ClassVar[str]
model: Any
def __init__(self, model: Any = None):
self.model = model
@abstractmethod
def play(self) -> Literal["rock", "paper", "scissors"]:
"""Return the next move."""
...
@abstractmethod
def handle_moves(self, own_move: OPTIONS, opponent_move: OPTIONS) -> None:
"""Update internal state after each round."""
...
Why?
- Enforces a consistent API for contest runners.
- Guarantees your strategy will be called in the expected way.
Utility Helpers
Located in rpsa_sdk/helpers.py, these functions speed up development:
| Function | Description |
|---|---|
random_move() |
Returns a uniformly random choice of "rock", "paper", or "scissors". |
counter_move(x) |
Returns the move that defeats the given move x. |
most_common(history, idx) |
From a list of (own_move, opponent_move) tuples, finds the most frequent move at position idx. |
from rpsa_sdk.helpers import random_move, counter_move, most_common
Use these helpers to quickly prototype or augment your own strategy logic.
Writing Your Own Strategy
- Subclass
Strategyand give your class a uniquenameto identify it.
class MyStrategy(Strategy):
name = "MyUniqueStrategy_v1"
...
- Implement the required methods:
play(): decide and return your next move.handle_moves(): update internal state after each round based on your and the opponent’s moves.
- Add optional parameters in your constructor (for example, history size or custom settings).
- Expose your strategy by assigning your class to a top-level
strategyvariable so the contest harness can import and instantiate it.
strategy = MyStrategy
Full Example: FrequencyStrategy
A ready-to-use strategy that counters the opponent’s most frequent recent move:
from rpsa_sdk.strategy import Strategy
from rpsa_sdk.helpers import counter_move, most_common
class FrequencyStrategy(Strategy):
name = "FrequencyStrategy_v1"
def __init__(self, model=None, max_history=50):
super().__init__(model)
self.history = []
self.max_history = max_history
def play(self):
if not self.history:
return "rock"
mc = most_common(self.history, idx=1)
return counter_move(mc)
def handle_moves(self, own_move, opponent_move):
self.history.append((own_move, opponent_move))
if len(self.history) > self.max_history:
self.history.pop(0)
# The contest runner will import this:
strategy = FrequencyStrategy
Running in a Contest
-
Place your strategy file into the code mirror.
-
Ensure it exposes a top-level
strategyvariable pointing to your class. -
Upload you ML model (if there are any), and use it in your
modelvariable -
The contest harness will:
-
Instantiate with
model=None(or load your uploaded model). -
Call
play()each round and thenhandle_moves(...).
-
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rpsa_sdk-0.1.2.tar.gz.
File metadata
- Download URL: rpsa_sdk-0.1.2.tar.gz
- Upload date:
- Size: 4.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.11.1 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3768df18dae0f771d32da68aecbe43120dc16ea1322d32dacf558adc4d0df248
|
|
| MD5 |
0b74eda8ebb838abb3b19a74d495d988
|
|
| BLAKE2b-256 |
9041e3aefb59d86e6d35116cff308ee5e6c03ff69d1a542d8e4905b5345957fe
|
File details
Details for the file rpsa_sdk-0.1.2-py3-none-any.whl.
File metadata
- Download URL: rpsa_sdk-0.1.2-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.11.1 Windows/10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
139006cb534b653dc42275ecadf38bcd6843c98e6ae696857566bbbabcd06d1a
|
|
| MD5 |
15029d43fb5fa92a5495c36d3b5848a3
|
|
| BLAKE2b-256 |
a6f3a3492d685ecc87726472a907cc31163c8e82a04c2542d9f5d82ac7fe713c
|