classDiagram

%% Classes principales
class Sudoku {
    +grille : Grille
    +blocs : List~Bloc~
    +contraintes : List~Contrainte~
    +rentrerSudoku() void
    +resoudre(resolveur : Resolveur) boolean
    +ajouterContrainte(contrainte : Contrainte) void
}

class MultiDoku {
    +sudokus : List~Sudoku~
    +contraintesPartage : List~ContraintePartage~
    +resoudre(resolveur : Resolveur) boolean
    +ajouterContraintePartage(contrainte : ContraintePartage) void
}

class Grille {
    +taille : int // N×N
    +cases : Symbole[taille][taille]
    +afficherGrille() void
    +estValide() boolean
    +getValeursPossibles(x : int, y : int) List~Symbole~
}

class Bloc {
    +cases : List~Case~
    +estValide() boolean
}

%% Contraintes classiques
class Contrainte {
    <<interface>>
    +estRespectee(grille : Grille, case : Case) boolean
}

class ContrainteLigne {
    +estRespectee(grille : Grille: case : Case) boolean
}

class ContrainteColonne {
    +estRespectee(grille : Grille: case : Case) boolean
}

class ContrainteBloc {
    +estRespectee(grille : Grille: case : Case) boolean
}

%% Contraintes Partagées
class ContraintePartage {
    <<interface>>
    +estRespectee(case : Case) boolean
}

class ContrainteLignePartage {
    -casesPartagees : List~Case~
    +estRespectee(case : Case) boolean
}

class ContrainteColonnePartage {
    -casesPartagees : List~Case~
    +estRespectee(case : Case) boolean
}

class ContrainteBlocPartage {
    -casesPartagees : List~Case~
    +estRespectee(case : Case) boolean
}

%% Résolution
class Resolveur {
    <<interface>>
    +resoudre(sudoku : Sudoku) boolean
    +resoudre(multidoku : MultiDoku) boolean
}

class ResolveurRegles {
    +resoudre(sudoku : Sudoku) boolean
    +resoudre(multidoku : MultiDoku) boolean
}

class ResolveurBacktrace {
    +backtrace : Backtrace
    +resoudre(sudoku : Sudoku) boolean
    +resoudre(multidoku : MultiDoku) boolean
}

%% Classes annexes
class Case {
    +valeur : Symbole
    +x : int
    +y : int
}

class Symbole {
    +valeur : char
    +equals(symbole : Symbole) boolean
}

class Backtrace {
    +pile : Stack~Case~
    +explorer(cases : List~Case~) boolean
}

%% Relations entre classes
Sudoku "1" --> "1" Grille : contient
Sudoku "1" --> "N" Bloc : contient
Sudoku "1" --> "*" Contrainte : utilise
MultiDoku "1" --> "*" Sudoku : contient
MultiDoku "1" --> "*" ContraintePartage : utilise
Grille "1" --> "N*N" Case : contient
Bloc "1" --> "N" Case : contient
Case "1" --> "1" Symbole : contient

%% Lien entre Resolveur et Sudoku/MultiDoku
Resolveur "1" --> "1" Sudoku : agit_sur
Resolveur "1" --> "1" MultiDoku : agit_sur

%% Héritages et implémentations
ResolveurRegles --> Resolveur : implémente
ResolveurBacktrace --> Resolveur : implémente
ResolveurBacktrace --> "1" Backtrace : utilise
ContrainteLigne --> Contrainte : implémente
ContrainteColonne --> Contrainte : implémente
ContrainteBloc --> Contrainte : implémente
ContrainteLignePartage --> ContraintePartage : implémente
ContrainteColonnePartage --> ContraintePartage : implémente
ContrainteBlocPartage --> ContraintePartage : implémente

