Skip to main content

Overview

The GameState class manages the complete state of a Codenames game, including turn management, word reveals, win condition checking, and game history. It works with a Board instance to track game progression.

Constructor

GameState(board)

Initialize game state with a board.
board
Board
required
The Board instance for this game. The starting team is determined from board.config.STARTING_TEAM.
from game import Board, GameState

words = ["apple", "banana", "car", ...]  # 25 words
board = Board(words, seed=42)
game = GameState(board)

print(game.current_team)  # Team.BLUE or Team.RED
print(game.turn_number)   # 0

Properties

board

Get the game board.
return
Board
The Board instance associated with this game.
board = game.board
all_words = board.all_words

current_team

Get the team whose turn it is.
return
Team
The Team enum value (Team.RED or Team.BLUE).
team = game.current_team
print(f"It's {team.value}'s turn")  # "It's blue's turn"

revealed_words

Get set of revealed words.
return
Set[str]
Immutable copy of revealed words set.
revealed = game.revealed_words
print(f"{len(revealed)} words have been revealed")

unrevealed_words

Get list of unrevealed words.
return
List[str]
List of words that haven’t been revealed yet.
available_words = game.unrevealed_words
print(f"{len(available_words)} words remaining on board")

turn_history

Get history of all completed turns.
return
List[Turn]
Copy of the turn history list.
for turn in game.turn_history:
    print(f"Turn {turn.turn_number}: {turn.hint_word} ({turn.hint_count})")
    for guess in turn.guesses:
        print(f"  - {guess.word}: {guess.correct}")

game_outcome

Get current game outcome.
return
GameOutcome
GameOutcome enum value (IN_PROGRESS, RED_WIN, or BLUE_WIN).
from game import GameOutcome

if game.game_outcome == GameOutcome.BLUE_WIN:
    print("Blue team wins!")
elif game.game_outcome == GameOutcome.RED_WIN:
    print("Red team wins!")
else:
    print("Game in progress...")

is_game_over

Check if game is over.
return
bool
True if game has ended, False if still in progress.
if game.is_game_over:
    print(f"Game ended: {game.game_outcome.value}")
else:
    print("Game still in progress")

turn_number

Get current turn number.
return
int
The current turn number (starts at 0, increments when turn starts).
print(f"Turn {game.turn_number}")

Turn Management Methods

start_turn(hint_word, hint_count)

Start a new turn with a hint from the spymaster.
hint_word
str
required
The hint word given by the spymaster (will be normalized to lowercase).
hint_count
int
required
Number of words the hint relates to.
raises
ValueError
Raised if game is over or if a turn is already in progress.
# Spymaster gives hint
game.start_turn("fruit", 2)
print(f"Hint: fruit (2)")

make_guess(word)

Make a guess for the current team.
word
str
required
The word being guessed (case-insensitive).
return
TurnResult
TurnResult object containing word, color, correctness, and bomb status.
raises
ValueError
Raised if no turn is in progress, word is not on board, or word is already revealed.
# Make guesses
result = game.make_guess("apple")
if result.correct:
    print(f"Correct! {result.word} is {result.color.value}")
elif result.hit_bomb:
    print(f"BOMB! Game over.")
else:
    print(f"Wrong. {result.word} is {result.color.value}")

# Check game state after guess
if game.is_game_over:
    print(f"Game ended: {game.game_outcome.value}")

end_turn()

End the current turn and switch teams.
raises
ValueError
Raised if no turn is in progress.
# End turn after guesses
game.end_turn()
print(f"Now it's {game.current_team.value}'s turn")

cancel_turn()

Cancel the current turn without adding it to history. Used when a turn needs to be discarded due to errors during retry logic. This resets the turn state so start_turn() can be called again.
try:
    game.start_turn("invalid", 1)
    # Something goes wrong...
    game.cancel_turn()  # Reset and try again
except Exception as e:
    game.cancel_turn()
    print(f"Turn cancelled due to error: {e}")

record_invalid_guess(word, reason)

Record an invalid guess for the current turn.
word
str
required
The invalid guess word.
reason
str
required
Reason why the guess was invalid (e.g., “off-board”, “already revealed”).
raises
ValueError
Raised if no turn is in progress.
# Record invalid guess attempt
game.record_invalid_guess("notaword", "word not on board")

Query Methods

get_remaining_words(team)

Get remaining unrevealed words for a team.
team
Team
required
The team to get remaining words for (Team.RED or Team.BLUE).
return
List[str]
List of unrevealed words belonging to the specified team.
from game import Team

blue_remaining = game.get_remaining_words(Team.BLUE)
red_remaining = game.get_remaining_words(Team.RED)

print(f"Blue has {len(blue_remaining)} words left")
print(f"Red has {len(red_remaining)} words left")

get_team_scores()

Get remaining word counts for both teams.
return
Tuple[int, int]
Tuple of (blue_remaining, red_remaining) word counts.
blue_score, red_score = game.get_team_scores()
print(f"Score - Blue: {blue_score}, Red: {red_score}")

get_snapshot()

Get JSON-serializable snapshot of game state.
return
dict
Dictionary containing complete game state including turn history, revealed words, scores, and outcome.
import json

snapshot = game.get_snapshot()
print(json.dumps(snapshot, indent=2))

# Snapshot structure:
# {
#   "turn_number": 3,
#   "current_team": "blue",
#   "revealed_words": ["apple", "banana", ...],
#   "game_outcome": "in_progress",
#   "team_scores": [7, 6],
#   "turn_history": [
#     {
#       "team": "blue",
#       "turn_number": 1,
#       "hint_word": "fruit",
#       "hint_count": 2,
#       "guesses": [...],
#       "invalid_guess_word": null,
#       "invalid_guess_reason": null
#     },
#     ...
#   ]
# }
Log current game status to console.
game.print_status()
# Outputs:
# ============================================================
# GAME STATUS - Turn 3
# ============================================================
# Current Team: BLUE
# Blue Remaining: 7 | Red Remaining: 6
# Outcome: in_progress
# Revealed: 12/25 words
# ...

Complete Game Example

from game import Board, GameState, Team, GameOutcome, CardColor

# Setup
words = ["apple", "banana", "car", ...]  # 25 words
board = Board(words, seed=42)
game = GameState(board)

# Turn 1: Blue team
game.start_turn("fruit", 2)
result = game.make_guess("apple")
if result.correct:
    print(f"Correct! {result.word}")

result = game.make_guess("banana")
if result.correct:
    print(f"Correct! {result.word}")

# Optional: make one more guess
result = game.make_guess("grape")
if not result.correct:
    print(f"Wrong! {result.word} is {result.color.value}")

game.end_turn()

# Turn 2: Red team
print(f"Now {game.current_team.value}'s turn")
game.start_turn("vehicle", 1)
result = game.make_guess("car")

if result.hit_bomb:
    print("BOMB! Game over!")
    print(f"Winner: {game.game_outcome.value}")
else:
    game.end_turn()

# Check progress
blue_score, red_score = game.get_team_scores()
print(f"Score - Blue: {blue_score}, Red: {red_score}")

# Game loop continues until game is over
while not game.is_game_over:
    # ... continue gameplay
    pass

print(f"Final outcome: {game.game_outcome.value}")

Build docs developers (and LLMs) love