# Dictionnaire francais simplifie (mots de 2 a 10 lettres)
# Chaque cle = longueur du mot. Tous les mots sont verifies.
DICTIONARY = {
2: ['DE', 'LE', 'LA', 'UN', 'ET', 'EN', 'OU', 'NE', 'CE', 'SE', 'IL', 'AU', 'DU', 'SA', 'MA'],
3: ['LES', 'DES', 'UNE', 'PAS', 'SUR', 'PAR', 'EUR', 'ELS', 'MER', 'TER', 'AIR', 'EAU', 'FEU', 'NUI', 'OUI', 'ROI', 'LOI', 'VOI', 'FIN', 'BON'],
4: ['DANS', 'SOUS', 'PRES', 'LOIN', 'TOUS', 'DEUX', 'VRAI', 'FAUX', 'BIEN', 'AIME', 'DONC', 'VOTE', 'LIRE', 'NOIR', 'BLAN', 'VERT', 'ROUG', 'BLEU', 'GRIS', 'JAUN'],
5: ['TOUTE', 'AUTRE', 'VOTRE', 'NOIRE', 'GRAND', 'PETIT', 'FORTS', 'MAJOR', 'SAINT', 'VALOR', 'NOBLE', 'HONTE', 'NUAGE', 'ROUTE', 'FEUVE', 'ORAGE', 'LIMBE', 'ARBRE', 'ECRAN', 'BLANC'],
6: ['MOMENT', 'SYSTEM', 'FOREST', 'FONDER', 'NATURE', 'ANIMAL', 'OBJECT', 'SOIREE', 'VOYAGE', 'ETOILE', 'PORTER', 'SAVANT', 'DANGER', 'REGLER', 'COUPER', 'PLIANT', 'JARDIN', 'FLEURS', 'LIVRES', 'COULEU'],
7: ['SYSTEME', 'PROJETS', 'DOMAINE', 'LEURREZ', 'FAUCHER', 'LIAISON', 'PAROLES', 'SENTIER', 'ETOILER', 'DAUPHIN', 'HISTOIR', 'SAVANTE', 'JALOUSI', 'CREUSER', 'NATUREL', 'POURSUI', 'BROUILL', 'SOUFFLE', 'RUISSEA', 'CHANTER'],
8: ['PROGRAMM', 'VARIABLE', 'FONCTION', 'PROBLEME', 'SOLUTION', 'NATURELS', 'GRANDISS', 'CREATIFS', 'COMPLETE', 'PAROISIE', 'DEFINISS', 'CARACTER', 'LONGUEUR', 'OPPOSANT', 'SAVANTES', 'ELEVATIO', 'MONTAGNE', 'INFORMAT', 'REPERTOI', 'STRUCTUR'],
9: ['ALGORITHM', 'VARIABLES', 'SOLUTIONS', 'SQUELETTE', 'NATURELLE', 'COMPLETER', 'HARMONIES', 'PAROISSIE', 'REPERTOIR', 'EVOLUTION', 'LANGAGIER', 'COMPLEXES', 'DIFFICILE', 'SECONDAIR'],
10: ['PROGRAMMAT', 'SQUELETTES', 'NATURELLES', 'COMPLETION', 'EVOLUTIONS', 'HARMONIQUE', 'PAROISSIAL', 'REPERTOIRE', 'STRUCTURAL', 'OPPOSANTES', 'LANGAGIERS', 'DETERMINER', 'SECONDAIRE', 'RESOLUTION']
}
@dataclass
class Slot:
"""Un slot (emplacement de mot) dans la grille."""
id: int
row: int
col: int
length: int
direction: str # 'H' ou 'V'
cells: List[Tuple[int, int]] # coordonnees des cases
@dataclass
class CrosswordGrid:
"""Grille de mots croises."""
rows: int
cols: int
black_cells: Set[Tuple[int, int]] # Cases noires
slots: List[Slot]
def __post_init__(self):
self.grid = np.full((self.rows, self.cols), None, dtype=object)
for r, c in self.black_cells:
self.grid[r, c] = '#'
def is_white(self, r: int, c: int) -> bool:
"""Verifie si une case est blanche."""
return (r, c) not in self.black_cells
def get_intersections(self) -> List[Tuple[int, int, Tuple[int, int]]]:
"""
Trouve les intersections entre slots.
Retourne: [(slot_h_id, slot_v_id, (pos_h, pos_v))]
"""
intersections = []
horizontal = [s for s in self.slots if s.direction == 'H']
vertical = [s for s in self.slots if s.direction == 'V']
for h_slot in horizontal:
for v_slot in vertical:
# Trouver l'intersection
h_cells = set(h_slot.cells)
v_cells = set(v_slot.cells)
common = h_cells & v_cells
if common:
cell = common.pop()
# Position dans chaque slot
pos_h = h_slot.cells.index(cell)
pos_v = v_slot.cells.index(cell)
intersections.append((h_slot.id, v_slot.id, (pos_h, pos_v)))
return intersections
def create_sample_grid() -> CrosswordGrid:
"""Cree une grille exemple 7x7."""
black_cells = {
(0, 3), (1, 3), (2, 3),
(3, 0), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6),
(4, 3), (5, 3), (6, 3)
}
# Identification des slots
slots = [
# Horizontaux
Slot(0, 0, 0, 3, 'H', [(0, 0), (0, 1), (0, 2)]),
Slot(1, 0, 4, 3, 'H', [(0, 4), (0, 5), (0, 6)]),
Slot(2, 1, 0, 3, 'H', [(1, 0), (1, 1), (1, 2)]),
Slot(3, 1, 4, 3, 'H', [(1, 4), (1, 5), (1, 6)]),
Slot(4, 2, 0, 3, 'H', [(2, 0), (2, 1), (2, 2)]),
Slot(5, 2, 4, 3, 'H', [(2, 4), (2, 5), (2, 6)]),
# Bas
Slot(6, 4, 0, 3, 'H', [(4, 0), (4, 1), (4, 2)]),
Slot(7, 4, 4, 3, 'H', [(4, 4), (4, 5), (4, 6)]),
Slot(8, 5, 0, 3, 'H', [(5, 0), (5, 1), (5, 2)]),
Slot(9, 5, 4, 3, 'H', [(5, 4), (5, 5), (5, 6)]),
Slot(10, 6, 0, 3, 'H', [(6, 0), (6, 1), (6, 2)]),
Slot(11, 6, 4, 3, 'H', [(6, 4), (6, 5), (6, 6)]),
# Verticaux
Slot(12, 0, 0, 3, 'V', [(0, 0), (1, 0), (2, 0)]),
Slot(13, 0, 1, 3, 'V', [(0, 1), (1, 1), (2, 1)]),
Slot(14, 0, 2, 3, 'V', [(0, 2), (1, 2), (2, 2)]),
Slot(15, 0, 4, 3, 'V', [(0, 4), (1, 4), (2, 4)]),
Slot(16, 0, 5, 3, 'V', [(0, 5), (1, 5), (2, 5)]),
Slot(17, 0, 6, 3, 'V', [(0, 6), (1, 6), (2, 6)]),
# Droite
Slot(18, 4, 0, 3, 'V', [(4, 0), (5, 0), (6, 0)]),
Slot(19, 4, 1, 3, 'V', [(4, 1), (5, 1), (6, 1)]),
Slot(20, 4, 2, 3, 'V', [(4, 2), (5, 2), (6, 2)]),
Slot(21, 4, 4, 3, 'V', [(4, 4), (5, 4), (6, 4)]),
Slot(22, 4, 5, 3, 'V', [(4, 5), (5, 5), (6, 5)]),
Slot(23, 4, 6, 3, 'V', [(4, 6), (5, 6), (6, 6)]),
]
return CrosswordGrid(rows=7, cols=7, black_cells=black_cells, slots=slots)
grid = create_sample_grid()
print(f"Grille creee: {grid.rows}x{grid.cols}")
print(f"Cases noires: {len(grid.black_cells)}")
print(f"Slots: {len(grid.slots)}")
# Verification du dictionnaire : chaque mot doit avoir la bonne longueur
errors = 0
for length, words in DICTIONARY.items():
for w in words:
if len(w) != length:
print(f"ERREUR: '{w}' dans cle {length} mais longueur reelle = {len(w)}")
errors += 1
if errors == 0:
print("Dictionnaire OK: toutes les longueurs sont correctes.")
else:
print(f"Dictionnaire: {errors} erreur(s) detectee(s).")