```plantuml


@startuml

enum Couleur {
  ROUGE
  VERT
  BLEU
  JAUNE
  NOIR
  BLANC
}

enum Indicateur {
  BONNEPLACE
  BONNECOULEUR
}

struct Jeton {
  ---
  ---
  +Jeton(couleur: Couleur)
}

Jeton *--> Couleur: +Couleur: Couleur

class Code {
  ---
  +NbJetons: int = 0
  ---
  +Code(tailleCode: int)
  +Code(jetons: Jeton[])
  +AjouterJeton(jeton: Jeton): void
  +SupprimerDernierJeton(): void
  +RecupererJeton(indice: int): Jeton
  +Jetons(): Jeton?[]
  +EstComplet(): bool
  +TailleMaximale(): int
  +Comparer(autreCode: Code): Indicateur[]
}

Code o--> Jeton: -lesJeton: Jeton?[]

class Plateau {
  -random: Random
  -tailleCode: int
  ---
  +Victoire: bool = false
  +Tour: int = 1
  ---
  +Plateau(tailleCode: int, tailleGrille: int)
  +GenererCodeAleatoire(): void
  +EstComplet(): bool
  +AjouterCode(code: Code): void
  +EstBonCode(code: Code): bool
  +Grille(): Jeton?[][]
  +Indicateurs(): Indicateur[][]
}

Plateau *--> Code: -codeSecret: Code
Plateau *--> Code: -grille: Code?[]
Plateau *--> Indicateur: -indicateurs: Indicateur[][]


class Joueur {
  ---
  +Nom: string
  ---
  +Joueur(nom: string, plateau: Plateau)
}

Joueur *--> Plateau: +Plateau: Plateau


interface IRegles {
  ---
  +Nom: string
  +TourMaximum: int
  +TailleCodeMaximum: int
  +NbJoueurs: int
  +NbJoueursMaximum: int
  ---
  +AjouterJoueur(joueur: string): Joueur
  +JoueurCourant(): Joueur
  +PasserLaMain(): void
  +GenererCode(): Code
  +CommencerLaPartie(): void
  +EstTerminee(): bool
  +Gagnants(): Joueur[]
  +Perdants(): Joueur[]
}


class ReglesClassiques {
  -nbJoueurs: int = 0
  -joueurCourant: int?
  ---
  +Nom: string = "Règles classiques"
  +TourMaximum: int = 12
  +TailleCodeMaximum: int = 4
  +NbJoueurs: int
  +NbJoueursMaximum: int = 2
  ---
  +ReglesClassiques()
}

IRegles <|.. ReglesClassiques

ReglesClassiques *--> Joueur: -joueurs: Joueur[]



class Partie {
  ---
  +StringEventHandler<TEventArgs>(sender: Object?, e: TEventArgs): string?
  +JetonEventHandler<TEventArgs>(sender: Object?, e: TEventArgs): Jeton
  ---
  +DemanderJoueur: StringEventHandler<DemanderJoueurEventArgs>?
  +DemanderJeton: JetonEventHandler<DemanderJetonEventArgs>?
  +AjouterJoueur: EventHandler<AjouterJoueursEventArgs>?
  +DebutPartie: EventHandler<AjouterJoueursEventArgs>?
  +NouveauTour: EventHandler<AjouterJoueursEventArgs>?
  +NouveauJeton: EventHandler<AjouterJoueursEventArgs>?
  +NouveauCode: EventHandler<AjouterJoueursEventArgs>?
  +PasserMain: EventHandler<AjouterJoueursEventArgs>?
  +PartieTerminee: EventHandler<AjouterJoueursEventArgs>?
  ---
  -QuandDemanderJoueur(int numero): string?
  -QuandDemanderJeton(): Jeton?
  -QuandAjouterJoueur(Joueur joueur): void
  -QuandDebutPartie(): void
  -QuandNouveauTour(Joueur joueur, int tour, Jeton?[][] grille, Indicateur[][] indicateurs): void
  -QuandNouveauJeton(Jeton jeton): void
  -QuandNouveauCode(Code: code): void
  -QuandPasserMain(): void
  -QuandPartieTerminee(Joueur[] gagnants, Joueur[] perdants): void
  +Partie(IRegles regles)
  +Jouer(): void
}


Partie *--> IRegles: -regles: IRegles



@enduml

```
