Code infrastructure and player algorithms (solvers) for the Codenames board game.
This is the active fork of mkali-personal/codenames.
The solvers module contains a multiple agent implementations, based on different strategies.
It is built above the codenames package (which contains the basic game models
and logic definition), and serves as the brain
for the-spymaster-bot.
Given the board:
+-------------+------------+----------+--------------+----------------+
| ⬜ money | 🟦 drama | ⬜ proof | 🟥 baseball | 🟥 imagination |
+-------------+------------+----------+--------------+----------------+
| 🟦 steel | 🟥 trail | ⬜ giant | 🟦 smell | ⬜ peace |
+-------------+------------+----------+--------------+----------------+
| ⬜ right | ⬜ pure | 🟥 loud | 💀 afternoon | 🟥 constant |
+-------------+------------+----------+--------------+----------------+
| 🟥 fabric | ⬜ violent | 🟥 style | 🟦 musical | 🟦 commitment |
+-------------+------------+----------+--------------+----------------+
| 🟦 teaching | 🟦 africa | 🟦 palm | 🟦 series | 🟥 bear |
+-------------+------------+----------+--------------+----------------+
A NaiveSpymaster playing for the blue team will output "role", 4.
From the logs:
Creating proposals for group size [4]...
Creating proposals for group size [3]...
Creating proposals for group size [2]...
Creating proposals for group size [1]...
Got 49 proposals.
Best 5 proposals:
('drama', 'musical', 'commitment', 'series') = ('role', 9.34)
('drama', 'musical', 'series') = ('films', 8.09)
('drama', 'musical', 'series') = ('comic', 8.04)
('drama', 'commitment', 'teaching') = ('focuses', 7.88)
('musical', 'commitment', 'teaching') = ('educational', 7.87)
Spymaster: [role] 4 card(s)
Some extra data from the solver about the picked hint:
{
"word_group": ["drama", "musical", "commitment", "series"],
"hint_word": "role",
"hint_word_frequency": 0.999,
"distance_group": 0.194,
"distance_gray": 0.207,
"distance_opponent": 0.23,
"distance_black": 0.383,
"grade": 9.337,
"board_distances": {
"drama": 0.151,
"musical": 0.166,
"commitment": 0.189,
"series": 0.194,
"peace": 0.207,
...
"trail": 0.425,
"smell": 0.451,
"palm": 0.487
}
}
Find usage examples in the playground directory.
Based on Google's word2vec embedding.
Clue generation:
- For each card subset
groupof size{4, 3, 2, 1}from my unrevealed cards, collect hint proposal:- Find the mean of
group's word embeddings. - Find the closest word to this mean (this will be the
hint). - Calculate the distance from
hintto all other unrevealed cards on the board. - Ensure the inspected
groupis the closest to the proposedhint. - Ensure opponent cards, gray cards, and black card distance to
hintare greater than a specified threshold. - Grade the
hintproposal (based on the number of cards ingroupand the distances fromhintto the different word groups).
- Find the mean of
- After collecting all hint proposals:
- If no legal proposal was found, repeat step
1.without filtering minimal distances (collect "dangerous" hints that might be confused with opponent cards). - Otherwise, pick the proposal with the highest grade.
- If no legal proposal was found, repeat step
Guess generation:
- Given a
hintand number of cards, calculate the distance betweenhintand all unrevealed cards on the board. - Iterate on number of cards:
- Pick the closest card to
hint.
- Pick the closest card to
- Skip the extra guess.
Based on OpenAI's ChatGPT API. Doesn't work very well.
Clone this repository: git clone https://github.com/asaf-kali/codenames-solvers.
- Make sure you have Poetry installed on your machine.
- Create a virtual environment (Python >= 3.9).
- Install dependencies using
make install(or run the commands from theMakefile). - Get a language model: TODO.
- Inside the
playgrounddirectory, you will find different examples of how to use the solvers.
Currently, this project is not published on PyPI.
From your project virtual env, install the package with pip install -e <path_to_this_repo>.
This needs to be updated.
- Download the zip file.
- Extract the
GoogleNews-vectors-negative300.binfile into thelanguage_data/folder and rename it toenglish.bin.
Look in the GitHub repo.
Run in terminal: make video-render.
If that didn't work: try python -m manim videos/explanation.py KalirmozExplanation -pql\h.