model projet_bataille_navale enum TypeCase { Vide, Bateau, Touche, Rate } enum TypeBateau { Torpilleur, Contre_Torpilleur, Croiseur, Porte_Avions } enum TypeCoup { Rate, Touche, Touche_Coule } enum EtatBateau { Operationnel, Coule } class Jeu operations init(nom1: String,nom2: String) debut() constraints -- Contraintes qui vérifient qu'il y a bien un bateau à un endroit coulé inv coule1: joueur1.plateau.cases.forAll( c1: Case | c1.type = TypeCase::Touche implies joueur2.plateau.cases->select( c2: Case | c2.x = c1.x and c2.y = c1.y)->forAll( c3: Case | c3.type = TypeCase::Bateau ) ) inv coule2: joueur2.plateau.cases.forAll( c1: Case | c1.type = TypeCase::Touche implies joueur1.plateau.cases->select( c2: Case | c2.x = c1.x and c2.y = c1.y)->forAll( c3: Case | c3.type = TypeCase::Bateau ) ) -- Contraintes qui vérifient qu'il n'y a pas de bateau à un endroit raté inv rate1: joueur1.plateau.cases.forAll( c1: Case | c1.type = TypeCase::Rate implies joueur2.plateau.cases->select( c2: Case | c2.x = c1.x and c2.y = c1.y)->forAll( c3: Case | c3.type = TypeCase::Vide ) ) inv rate2: joueur2.plateau.cases.forAll( c1: Case | c1.type = TypeCase::Rate implies joueur1.plateau.cases->select( c2: Case | c2.x = c1.x and c2.y = c1.y)->forAll( c3: Case | c3.type = TypeCase::Vide ) ) -- Contrainte qui vérifie que les joueurs ont des noms différents inv noms: not(joueur1.nom = joueur2.nom) end class Joueur attributes nom: String operations tirer(case: String): TypeCoup tirerRobot(): TypeCoup end class Flotte operations ajouterBateau(bateau: Bateau) constraints -- Contraintes qui vérifient que les bateaux sont de la bonne taille inv torpilleur: bateaux->select(b: Bateau | b.type = TypeBateau::Torpilleur)->size() = 1 inv contre_torpilleur: bateaux->select(b: Bateau | b.type = TypeBateau::Contre_Torpilleur)->size() = 2 inv croiseur: bateaux->select(b: Bateau | b.type = TypeBateau::Croiseur)->size() = 1 inv porte_avions: bateaux->select(b: Bateau | b.type = TypeBateau::Porte_Avions)->size() = 1 end class Coup attributes type: TypeCoup end class Plateau operations afficherPlateau(CacherBateaux: Boolean) end class Case attributes x: Integer y: Integer type: TypeCase operations changerEtat(nouveauEtat: TypeCase) getEtat(): TypeCase constraints -- Contrainte qui vérifie qu'il n'y a pas deux cases au même endroit inv unicite: plateau.cases->select(c: Case | c.x = x and c.y = y)->size() = 1 -- Contrainte qui vérifie que le plateau est de bonne dimensions inv dimensions: x <= 10 and x > 0 and y > 0 and y <= 10 end class Bateau attributes type: TypeBateau longueur: Integer etat: EtatBateau constraints -- Contraintes qui vérifient que les bateaux sont de la bonne taille inv torpilleur: type = TypeBateau::Torpilleur implies longueur = 2 inv contre_torpilleur: type = TypeBateau::Contre_Torpilleur implies longueur = 3 inv croiseur: type = TypeBateau::Croiseur implies longueur = 4 inv porte_avions: type = TypeBateau::Porte_Avions implies longueur = 5 -- Contrainte qui dit que si toutes les cases d'un bateau sont touchées alors le bateau est coulé inv coule: cases->forAll(c: Case | c.type = TypeCase::Touche) implies etat = EtatBateau::Coule end association Utilise between Joueur[1] role joueur Plateau[1] role plateau end composition Joue1 between Joueur[1] role joueur1 Jeu[1] role jeu1 end composition Joue2 between Joueur[1] role joueur2 Jeu[1] role jeu2 end association Tire between Joueur[*] role joueur Coup[1] role coups end association Appartient between Joueur[1] role joueur Flotte[1] role flotte end composition Appartient2 between Flotte[1] role flotte Bateau[5] role bateaux end composition Compose between Case[100] role cases Plateau[1] role plateau end association Etat between Case[1] role case Coup[1] role coup end association Repartit between Case[2..5] role cases Bateau[0..1] role bateau end