A Streamlit app for scoring 3CB (Three Card Blind) deck matchups with Google Sheets integration. Multiple scorers can contribute, with automatic discrepancy detection and Nash equilibrium calculation.
- Score deck matchups with WIN/TIE/LOSS buttons
- Automatic card image display via Scryfall API
- Google Sheets integration for collaborative scoring
- Multiple scorer support with consensus tracking
- Discrepancy detection between scorers
- Nash equilibrium calculation for optimal deck selection
- Filter views: all matchups, unscored, accepted, or discrepancies
- Python 3.10 or higher
- uv (recommended) or pip
-
Clone the repository:
git clone https://github.com/yourusername/3cb-gauntlet-builder.git cd 3cb-gauntlet-builder -
Install dependencies:
# Using uv (recommended) uv sync # Or using pip pip install -e .
-
Set up Google Sheets API credentials (see below)
-
Run the app:
# Using uv uv run streamlit run app.py # Or directly streamlit run app.py
- Go to the Google Cloud Console
- Create a new project
- Enable the Google Sheets API and Google Drive API
- Go to APIs & Services > Credentials
- Click Create Credentials > Service Account
- Fill in the service account details
- Click on the created service account
- Go to Keys > Add Key > Create new key
- Select JSON format
- Save the downloaded file as
credentials.jsonin the app directory
Create a Google Sheet with the following tabs:
| Tab Name | Purpose |
|---|---|
Decks |
List deck names in column A (format: Card1 | Card2 | Card3) |
Results |
Auto-populated with matchup results |
Matrix_OnPlay |
Auto-populated win/loss matrix (on play) |
Matrix_OnDraw |
Auto-populated win/loss matrix (on draw) |
Game_Matrix |
Combined payoff matrix |
Nash |
Nash equilibrium weights |
Share your Google Sheet with the service account email (found in credentials.json under client_email). Give it Editor access.
- Start the app and enter your Google Sheet URL
- Enter your name (creates a scorer column)
- Click Connect to Sheet
- Navigate through matchups and score them as WIN/TIE/LOSS
- Use filters to focus on unscored or disputed matchups
- Click Calculate Nash to compute optimal deck weights
- Refresh Data: Sync with Google Sheet and normalize deck names
- Update Matrices: Rebuild win/loss matrices from results
- Calculate Nash: Compute Nash equilibrium deck weights
- Initialize Results Sheet: Set up matchup grid for new decks
3cb-gauntlet-builder/
├── app.py # Main Streamlit application
├── sheets_integration.py # Google Sheets API integration
├── nash.py # Nash equilibrium calculation
├── pyproject.toml # Project dependencies
├── credentials.json # Google API credentials (not in repo)
├── data/ # Optional data files
│ └── history.csv # Historical matchup results
└── screenshots/ # App screenshots
- 2 = WIN: Deck on play wins the matchup
- 1 = TIE: Matchup is a draw
- 0 = LOSS: Deck on play loses the matchup
Scores are from the perspective of the deck on play.
MIT License
