Spaces:
Running
Running
| 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() | |