Spaces:
Running
Running
File size: 4,043 Bytes
641f13e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | import gradio as gr
INTRO_MD = """
# π΅οΈ Codenames LLM Challenge
Welcome! This is a coding challenge where you build a **guesser bot** for the board game
[Codenames](https://en.wikipedia.org/wiki/Codenames_(board_game)).
An LLM-powered **spymaster** will give you one-word clues. Your job is to write the
**guesser** that picks the right words on the board.
---
## How the game works
The board has **25 words** split into hidden roles:
| Role | Count | Meaning |
|------|-------|---------|
| π₯ RED | 9 | Your team's words β guess these! |
| π¦ BLUE | 8 | Opponent words β avoid these |
| π ASSASSIN | 8 | Instant loss if revealed |
Each round:
1. The **spymaster** gives a one-word clue + a number (e.g. `"ocean 3"`)
2. Your **guesser** can make up to `number + 1` guesses
3. A round ends when you reveal a BLUE word, reach the max guesses, or return `None`
4. The game ends when **all RED words are found** (win) or the **assassin is revealed** (loss)
Your score is based on the number of rounds needed β fewer is better.
---
## Two steps to participate
"""
STEP1_MD = """
## Step 1 β Clone the repository
Open a terminal and run:
```bash
git clone https://huggingface.co/spaces/LLM-course/codenames
cd codenames
```
Then set up the Python environment:
```bash
uv venv
source .venv/bin/activate # on Windows: .venv\\Scripts\\activate
uv pip install -r requirements.txt
```
*(Optional but recommended)* Pre-build the embedding cache so runs are faster:
```bash
python -m codenames.cli init-cache
```
"""
STEP2_MD = """
## Step 2 β Implement `my_guesser.py`
Open `my_guesser.py` and fill in the `guesser` function:
```python
# my_guesser.py
from codenames.embedder import EmbeddingIndex
from codenames.dictionary import load_dictionary
_dictionary = load_dictionary()
_index = EmbeddingIndex(_dictionary)
def guesser(clue: str, board_state: list[str]) -> str | None:
\"\"\"
Args:
clue: The spymaster's one-word clue (always from the 420-word dictionary)
board_state: List of unrevealed words currently on the board
Returns:
A word from board_state to guess, or None to stop guessing this round.
\"\"\"
# TODO: replace this with your smart logic!
return board_state[0]
```
### Tips
- Use **embedding similarity** between the clue and board words β `_index.vector(word)`
returns a numpy vector for any dictionary word.
- Return `None` when you're not confident: it's safer than hitting a BLUE or ASSASSIN word.
- The clue is always a word from the shared 420-word dictionary (case-insensitive).
### Test your guesser
```bash
python -m codenames.cli challenge my_guesser.py --seed 42 --output log.json
```
Options:
- `--seed` β fix the board for reproducibility
- `--max-rounds` β limit rounds (default 10)
- `--output` β save a detailed JSON log with clues, guesses and the final result
The JSON log is useful for inspecting mistakes and improving your strategy.
"""
RULES_MD = """
## Full rules summary
- Board: 25 words, 9 RED / 8 BLUE / 8 ASSASSIN (challenge / single-team mode)
- Clue + number are given each round by the LLM spymaster
- Guesser may guess up to `number + 1` times per round
- Revealing a BLUE word ends the round immediately
- Revealing the ASSASSIN ends the game immediately (loss)
- **Goal:** reveal all 9 RED words in as few rounds as possible
## Dictionary
All clue words and board words are drawn from a **fixed list of 420 Codenames words**
(see `codenames/data/codenames_dict.txt`). Your guesser receives words from this list
and must return a word from the current `board_state`.
"""
with gr.Blocks(title="Codenames LLM Challenge") as demo:
gr.Markdown(INTRO_MD)
with gr.Tabs():
with gr.TabItem("π οΈ Step 1 β Clone"):
gr.Markdown(STEP1_MD)
with gr.TabItem("π‘ Step 2 β Implement"):
gr.Markdown(STEP2_MD)
with gr.TabItem("π Full Rules"):
gr.Markdown(RULES_MD)
if __name__ == "__main__":
demo.launch()
|