projet-bataille-navale/projet.use
2025-01-19 19:21:06 +01:00

195 lines
5.6 KiB
Text

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
-- pre libre: plateau.cases.
tirerRobot(): TypeCoup
end
class Flotte
operations
ajouterBateau(bateau: Bateau)
pre torpilleur: bateau.type = TypeBateau::Torpilleur implies bateaux->select(b: Bateau | b.type = TypeBateau::Torpilleur)->size() < 1
pre contre_torpilleur: bateau.type = TypeBateau::Contre_Torpilleur implies bateaux->select(b: Bateau | b.type = TypeBateau::Contre_Torpilleur)->size() < 2
pre croiseur: bateau.type = TypeBateau::Croiseur implies bateaux->select(b: Bateau | b.type = TypeBateau::Croiseur)->size() < 1
pre porte_avions: bateau.type = TypeBateau::Porte_Avions implies bateaux->select(b: Bateau | b.type = TypeBateau::Porte_Avions)->size() < 1
constraints
-- Contraintes qui vérifient le nombre de bateaux par type
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
constraints
inv unicite: joueur.coups.isUnique(c: Coup | c.case = case)
end
class Plateau
operations
afficherPlateau(CacherBateaux: Boolean)
end
class Case
attributes
x: Integer
y: Integer
type: TypeCase
operations
changerEtat(nouveauEtat: TypeCase)
pre different: not(nouveauEtat = type)
post change: type = nouveauEtat
getEtat(): TypeCase
constraints
-- Contrainte qui vérifie qu'il n'y a pas deux cases au même endroit
inv unicite: plateau.cases->isUnique(c: Case | c.x = x and c.y = y)
-- 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
x1: Integer
y1: Integer
x2: Integer
y2: Integer
constraints
-- Contraintes qui vérifient que les bateaux sont de la bonne taille
inv torpilleur1: type = TypeBateau::Torpilleur implies longueur = 2 and cases->size() = 2
inv contre_torpilleur1: type = TypeBateau::Contre_Torpilleur implies longueur = 3 and cases->size() = 3
inv croiseur1: type = TypeBateau::Croiseur implies longueur = 4 and cases->size() = 4
inv porte_avions1: type = TypeBateau::Porte_Avions implies longueur = 5 and cases->size() = 2
-- 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
-- Contrainte qui vérifie que le bateau est soit horizontal soit vertical
inv orientation: x1 = x2 or y1 = y2
-- Contraintes qui vérifient que les cases du bateau correspondent bien aux coordonnées
inv horizontal: y1 = y2 implies cases.forAll(c: Case | c.y = y1 and c.x >= x1 and c.x <= x2)
inv vertical: x1 = x2 implies cases.forAll(c: Case | c.x = x1 and c.y >= y1 and c.y <= y2)
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[1] role joueur
Coup[0..100] 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