Spaces:
Paused
Paused
| """Word interaction definitions for complex semantic relationships in Codenames. | |
| Defines thematic clusters, polysemes, false friends, and semantic traps | |
| to increase game complexity. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| from typing import Any | |
| class WordRelation: | |
| """Represents a semantic relationship between words.""" | |
| word: str | |
| related_words: list[str] = field(default_factory=list) | |
| relation_type: str = "semantic" # semantic, thematic, homonym, false_friend, trap | |
| domains: list[str] = field(default_factory=list) # e.g., ["finance", "nature"] | |
| trap_level: int = 0 # 0=none, 1=mild, 2=moderate, 3=dangerous | |
| class ThematicCluster: | |
| """A group of words sharing a hidden theme.""" | |
| theme: str | |
| words: list[str] | |
| secondary_themes: list[str] = field(default_factory=list) | |
| class WordInteractions: | |
| """Container for all word interactions on a board.""" | |
| words: list[str] | |
| relations: dict[str, WordRelation] = field(default_factory=dict) | |
| clusters: list[ThematicCluster] = field(default_factory=list) | |
| polysemes: list[str] = field(default_factory=list) # Words with multiple meanings | |
| false_friends: list[tuple[str, str]] = field(default_factory=list) # Pairs that seem related but aren't | |
| assassin_traps: list[str] = field(default_factory=list) # Words semantically close to assassin | |
| def get_related_words(self, word: str) -> list[str]: | |
| """Get all words related to the given word.""" | |
| if word in self.relations: | |
| return self.relations[word].related_words | |
| return [] | |
| def get_trap_level(self, word: str) -> int: | |
| """Get the trap level for a word (how close to assassin).""" | |
| if word in self.relations: | |
| return self.relations[word].trap_level | |
| return 0 | |
| def get_word_domains(self, word: str) -> list[str]: | |
| """Get the semantic domains for a word.""" | |
| if word in self.relations: | |
| return self.relations[word].domains | |
| return [] | |
| def to_dict(self) -> dict[str, Any]: | |
| """Serialize to dictionary for JSON output.""" | |
| return { | |
| "words": self.words, | |
| "relations": { | |
| w: { | |
| "related_words": r.related_words, | |
| "relation_type": r.relation_type, | |
| "domains": r.domains, | |
| "trap_level": r.trap_level, | |
| } | |
| for w, r in self.relations.items() | |
| }, | |
| "clusters": [ | |
| {"theme": c.theme, "words": c.words, "secondary_themes": c.secondary_themes} | |
| for c in self.clusters | |
| ], | |
| "polysemes": self.polysemes, | |
| "false_friends": self.false_friends, | |
| "assassin_traps": self.assassin_traps, | |
| } | |
| def from_dict(cls, data: dict[str, Any]) -> "WordInteractions": | |
| """Deserialize from dictionary.""" | |
| interactions = cls(words=data.get("words", [])) | |
| for word, rel_data in data.get("relations", {}).items(): | |
| interactions.relations[word] = WordRelation( | |
| word=word, | |
| related_words=rel_data.get("related_words", []), | |
| relation_type=rel_data.get("relation_type", "semantic"), | |
| domains=rel_data.get("domains", []), | |
| trap_level=rel_data.get("trap_level", 0), | |
| ) | |
| for cluster_data in data.get("clusters", []): | |
| interactions.clusters.append(ThematicCluster( | |
| theme=cluster_data.get("theme", ""), | |
| words=cluster_data.get("words", []), | |
| secondary_themes=cluster_data.get("secondary_themes", []), | |
| )) | |
| interactions.polysemes = data.get("polysemes", []) | |
| interactions.false_friends = [tuple(pair) for pair in data.get("false_friends", [])] | |
| interactions.assassin_traps = data.get("assassin_traps", []) | |
| return interactions | |