High-performance card library for ML and RL applications.
Project description
⚡ Toulouse: High-Performance Card Library for Machine Learning & Reinforcement Learning
Toulouse is a modern, lightning-fast Python library for representing, manipulating, and vectorizing card games—designed for the needs of the ML and RL community.
- 🚀 Blazing Fast: O(1) card lookup, object pooling, and pre-allocated numpy buffers
- 🧩 Extensible: Easily add new card systems (Italian, Spanish, custom...)
- 🧑💻 ML/RL Ready: One-hot numpy state vectors for cards and decks
- 🌍 Multilingual: Card names in multiple languages (EN, IT, ES)
- 🧪 Tested & Typed: Robust, well-typed, and ready for research or production
Installation
pip install toulouse
or
uv add toulouse
Quick Start
from toulouse import Card, Deck, get_card
# Create a new Italian 40-card deck (sorted)
deck = Deck.new_deck(card_system_key="italian_40")
print(deck) # Deck of 40 cards (italian_40)
# Draw a card
drawn = deck.draw(1)[0]
print(drawn) # Ace of Denari
# Check if a card is in the deck
card = get_card(value=1, suit=0) # Ace of Denari
print(deck.contains(card)) # False (if just drawn)
# Get the deck state as a numpy vector (for ML/RL)
print(deck.state.shape) # (40,)
# Reset and shuffle the deck
deck.reset()
deck.shuffle()
Supported Card Systems
- italian_40: Denari, Coppe, Spade, Bastoni
- spanish_40: Oros, Copas, Espadas, Bastos
- Add your own system easily (see below)
API Reference
Card
from toulouse import Card, get_card
card = get_card(value=7, suit=2, card_system_key="italian_40")
print(card) # Seven of Spade
print(card.to_index()) # Unique index in the deck
print(card.state) # One-hot numpy array (length deck_size)
Card(value, suit, card_system_key="italian_40"): Immutable, hashable card instance.to_index(): Returns unique index for the card in its system.state: One-hot numpy array (length = deck size)__str__,__repr__: Human-readable
Deck
from toulouse import Deck
deck = Deck.new_deck(card_system_key="spanish_40", sorted_deck=False)
print(len(deck)) # 40
hand = deck.draw(3) # Draw 3 cards
print(deck.state) # Numpy binary vector (remaining cards)
deck.append(hand[0]) # Add a card back
deck.shuffle() # Shuffle the deck
deck.sort() # Sort the deck
deck.reset() # Restore to full deck
Deck.new_deck(card_system_key="italian_40", language="en", sorted_deck=True): Create a new deck.draw(n): Draw n cards (removes from deck).append(card): Add a card.remove(card): Remove a card.contains(card): O(1) check for card presence.reset(): Restore to full deck.shuffle(),.sort(): Shuffle or sort.state: Numpy binary vector (length = deck size).pretty_print(): Grouped by suit, human-readable.move_card_to(card, other_deck): Move card between decks
Card System Management
from toulouse import register_card_system, get_card_system
my_system = {
"suits": ["Red", "Blue"],
"values": [1, 2, 3],
"deck_size": 6,
}
register_card_system("mini_6", my_system)
print(get_card_system("mini_6"))
register_card_system(key, config): Add a new card systemget_card_system(key): Retrieve system config
Machine Learning & RL Integration
- Card state:
card.stateis a one-hot numpy array (length = deck size) - Deck state:
deck.stateis a binary numpy array (1 if card present) - Fast vectorization: Pre-allocated, cached numpy buffers for speed
Example:
from toulouse import Deck
deck = Deck.new_deck()
obs = deck.state # Use as RL agent observation
Performance
Toulouse is engineered for speed. Here are real benchmark results from the test suite (Apple Silicon, Python 3.11):
Deck creation (1000x): 0.0062 seconds
Shuffle+draw+reset (1000x): 0.0099 seconds
Card lookup (10000x): 0.0006 seconds
State vectorization (deck+card, 10000x): 0.0042 seconds
- Creating 1000 decks takes less than 7 milliseconds
- 10,000 card lookups in under 1 millisecond
- Deck and card state vectorization is nearly instantaneous
This makes Toulouse ideal for RL/ML environments where speed is critical.
Extending Toulouse
Add new card systems for custom games:
from toulouse import register_card_system, Deck
register_card_system("custom_8", {
"suits": ["Alpha", "Beta"],
"values": [1, 2, 3, 4],
"deck_size": 8,
})
deck = Deck.new_deck(card_system_key="custom_8")
print(deck)
Testing
Run the test suite with pytest:
pytest tests/
License
MIT — Use, modify, and share freely.
Project details
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 toulouse-1.0.0.tar.gz.
File metadata
- Download URL: toulouse-1.0.0.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed79cb0a3d5ce9397da5094caf3483182418829c1a25a7d197e0753f65c37c01
|
|
| MD5 |
02eddbf1281bf06819d43fdf3328a980
|
|
| BLAKE2b-256 |
090eaa34c30d1621310dff90cc4832728583d25f7ac05890617f5ee8a0684f47
|
File details
Details for the file toulouse-1.0.0-py3-none-any.whl.
File metadata
- Download URL: toulouse-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d382e70e965e28cf7d4be866b5d801481c1843e1fb3d84357e29cdb8e5af7cec
|
|
| MD5 |
99b5d580c257fd692a028bfacc1c68bc
|
|
| BLAKE2b-256 |
5226dd63857b2a2cafcff327c4ca84460ecbafb66cddfdbbd05cd41e0e2fc167
|