Jeu de Domino en R Eseau: Algorithmique Distribu Ee I Encadr e Par: Damien LOLIVEJ
Jeu de Domino en R Eseau: Algorithmique Distribu Ee I Encadr e Par: Damien LOLIVEJ
Langage Java
Mot clefs Naimi - Trehel
RMI - Thread
Algorithmique Distribuée
I Encadré par : Damien LOLIVEJ
Résumé : Ce document rend compte des traveaux réalisés dans le cadre des 8h de projet
consacrées à la réalisation d’un jeu de domino en réseau. L’architecture aura pour support l’al-
gorithme de Naimi et Tréhel pour la gestion de l’exclusion mutuelle et les échanges entre les
objets seront gérés par RMI (Remote Method Invocation).
Introduction 2
Conclusion 14
1
Introduction
Puisqu’il est évident que ces objets distants doivent communiquer, un mécanisme de par-
tage doit être mis en place pour assurer cette communication. En effet, RMI permet l’accès aux
méthodes dobjets distants, permettant ainsi d’établir une communication riche.
Commentaires :
Note : certains passages de ce document ont purement vocation d’aide mémoire personnels pour d’éventuelles
réutilisations des concepts vus ici.
2
I Analyse & Conception
I.1 Présentation
Nous présentons ici la problématique posée par la l’exclusion mutuelle (locale et distribuée)
qui sous-tend l’existence de cet algorithme. Nous allons donc rappeler très brièvement le principe
de ces notions qui sont indispensables à la compréhension du sujet et à sa réalisation :
Exclusion mutuelle
Le joueur possédant le jeton doit poser l’un de ses dominos sur la table de jeu. S’il ne peut
pas, il prend alors un domino de la pioche qu’il pose ou qu’il garde. Ce dernier passe ensuite le
jeton au joueur ayant demandé à jouer après lui c’est dire le joueur qui se trouve en tête de la
file d’attente d’accès à la section critique 1 .
1
Voir Structures de données I.4.a) page 7
3
I.2. CHOIX D’IMPLÉMENTATION I. Analyse & Conception
Lorsqu’un joueur ne dispose plus de dominos, il le signale à l’arbitre qui envoi à ce joueur le
message “fin de partie” et informe les autres joueurs qu’il y a un gagnant.
Nous nous intéressons dans ce projet à l’implémentation ce jeu à l’aide de L’algorithme pro-
posé par Naı̈mi et Tréhel pour la gestion de la partie accédée en exclusion mutuelle distribuéee.
Cet algorithme assure le bon déroulement des parties conformément à ce qui a été cité dans la
section précédente. Il appartient à la famille basée sur la notion de jeton unique.
Dans notre cas, l’arbitre et les joueurs sont tous dans des threads séparés puisqu’ils héritent
de Site qui elle-même hérite de Thread. Le comportement général d’un arbitre ou d’un joueur,
quel qu’il soit passe donc par la redéfinition de la méthode run().
4
I.3. PRÉSENTATION DE L’ALGORITHME DE NAIMI ET I.
TR Analyse
ÉHEL & Conception
Une autre solution aurait été d’utiliser les sockets comme vecteur d’acheminement des mes-
sages. Initialement, mon choix s’est porté sur RMI pour les raisons suivantes :
– très pratique, une fois configuré ;
– semble plus flexible que les sockets quand à la nature des messages ;
– (l’occasion de le découvrir.)
Sur le second point, il semble toutefois que l’on puisse véhiculer tout type de données, y
compris des objets. À la suite des séances de TP, nous n’avions vu que des échanges de chaı̂nes
de caractères, car facile à réaliser. Cependant, en sérialisant un objet, il serait possible de le
transformer en flot de bit qui est le véritable contenu des messages transitant via les sockets.
De plus, au regard des difficultés rencontrées pour la configuration de RMI, une solution plus
“efficace” par sockets aurait certainement été plus bénéfique puisque la mise en place de RMI
n’est qu’un outil et non l’objet du projet.
• Interface du joueur :
• Interface de l’arbitre :
// Vers l’arbitre
// Vers la partie applicative des joueurs
→ debutPartie(int num joueur)
→ finPartie(int num joueur)
// Vers la partie contrôle (des autres joueurs)
→ enviePartie(int num joueur)
→ demandeSC(int num joueur)
→ donneJeton(int num joueur)
La structure arborescente permet de faire transiter la demande jusqu’à la racine. Les de-
mandeurs de la section critique sont mis en attente dans une file globale. Chaque demande
d’entrée en section critique doit être transmise au site successeur et chaque demandeur devient
la nouvelle racine. La mise à jour de l’arborescence est bien illustrée par un exemple dans le sujet.
5
I.3. PRÉSENTATION DE L’ALGORITHME DE NAIMI ET I.
TR Analyse
ÉHEL & Conception
D’après le schéma, nous pouvons constater qu’un site joueur est décomposé en deux parties.
Une partie applicative qui communique avec l’arbitre qui lui aussi doit pouvoir communiquer
avec tous les joueurs. Une partie contrôle qui assure la communication avec les autres joueurs
et l’exclusion mutuelle.
6
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception
Une fois ce schéma réalisé, il ne nous reste plus qu’à définir les méthodes qui n’y apparaissent
pas et qui sont pourtant indispensable. Nous pouvons ensuite programmer les différents processus
indépendamment les uns des autres car les communications entre eux sont maintenant définies.
7
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception
sorties en section critique des différents sites. La racine de cet arbre, appelée dernier, est
le dernier site émetteur d’une requête d’entrée en section critique. La seconde structure
représente la file d’attente pour l’accès à cette section critique.
Ces structures sont éclatées et réparties sur chacun des sites. Ainsi, en négligeant les
messages en cours de transmition entre les sites, on peut représenter l’état du système de
la manière suivante : (ici, l’initialisation)
/-----+------+------+------+------\
| P1 | P2 | P3 | P4 | P5 |
----------|------+------+------+------+------|
dernier | nil | P1 | P1 | P1 | P1 | <= arbre des demandes de s.c.
suivant | nil | nil | nil | nil | nil | <= file d’attente de s.c.
jeton | vrai | faux | faux | faux | faux |
demandeur | vrai | faux | faux | faux | faux |
---------/ \-----+------+------+------+------/
qui décrit donc un état dans lequel P1 est le seul site à avoir fait une demande et pour
lequel la file d’attente est vide.
La classe Application : Il s’agit ici d’un raccourcis permettant de créer les objets arbitre et
joueur. Dans la pratique, la création de ces objets doit leur être propre - on doit avoir la
possibilité de créer un joueur à n’importe quel instant.
La classe Joueur : Un joueur sera composé d’une partie applicative et d’une partie contrôle.
L’application a en charge le dialogue avec l’arbitre signalant, par exemple, son arrivée ou la
de la partie. Alors que le contrôle permet la communication entre les joueurs et notamment
les échanges du jeton ou la demande d’entrée / sortie de section critique.
En “langage RMI”, cela veut dire que :
– l’arbitre possède un talon pour chacun des (partie applicative des) joueurs ;
– la partie applicative d’un joueur à connaissance du talon de l’arbitre ;
– la partie contrôle connaı̂t les talons des autres parties contrôles.
La classe Table : existe dans la modélisation mais n’est pas réalisée.
Factoriser du code : Cette décomposition hiérarchique est sensée permettre de factoriser, à
différents étage, du code qui serait inutilement répété. En plus des accesseurs, comme
chaque site est à la fois client et serveur dans la communication, on pourrait également
envisager d’y placer les instructions réalisant cette communication bidirectionnelle.
Cependant, cette modélisation considère un arbitre comme étant un Site à part entière. Hors,
il n’intervient nullement dans la gestion de l’exclusion mutuelle. Nous avons donc retouché notre
modélisation pour en arriver au diagramme de classe présente à la figure I.3 page 9.
8
I.4. DIAGRAMME DE CLASSES I. Analyse & Conception
9
II Réalisation & Exploitation
1. Spécifier l’interface de l’objet qui est un fichier .java avec la structure suivante :
import j a v a . rmi . RemoteException ; 1
2
p u b l i c i n t e r f a c e I n t e r f a c e A r b i t r e e x t e n d s j a v a . rmi . Remote { 3
/∗ p r o t o t y p e d e s methodes p a r t a g e e s ∗/ 4
p u b l i c v o i d f i n P a r t i e ( i n t num joueur ) throws RemoteException ; 5
} 6
3. Générer le talon et le squelette de l’objet distant : rmic. La génération des talons fait en
ligne de commande une fois que l’interface est définie et implémentatée.
cd <c h e m i n P r o j e t >/b i n / 1
rmic <nomPackage>.<nomClasse> 2
La classe en question est celle qui implémente l’interface et son nom est donnée sans le
.class. Cela a pour effet de générer des fichiers <nomClasse> Stub.class.
4. Définir l’objet (l’exposer) afin de le rendre visible aux clients : le rebind
S t r i n g machine = l o c a l h o s t ; 1
String port = 1099; 2
S t r i n g objetToRebind = a r b i t r e 3
10
II.2. DU CSP AU JAVA II. Réalisation & Exploitation
Processus Arbitre ::
variable nbDemandeur entier,
variable list_joueur_inscrit tableau de booleen,
variable start booleen,
variable j entier
11
II.2. DU CSP AU JAVA II. Réalisation & Exploitation
Une fois la spécification CSP faite, nous pouvons le coder en Java. L’arbitre est unique dans
une partie et contient les variables suivantes :
private Pioche p i o c h e ; /∗ i n s t a n c e de l a c l a s s e P i o c h e ∗/ 1
private boolean s t a r t ; /∗ b o o l e e n q u i i n d i q u e s i une p a r t i e e s t commencee ∗/ 2
private b o o l e a n [ ] l i s t j o u e u i n s c r i t ; /∗ d e f i n i t l a l i s t e d e s j o u e u r s i n s c r i t s ∗/ 3
private i n t nbDemandeur ; /∗ nombre de j o u e u r q u i ont f a i t une demande de j e u ∗/ 4
Cette classe possède d’autres méthodes pour assurer la distribution des dominos, avec entre
autres :
→ public void genererDominos() qui génère les 28 dominos pour jouer et les place dans la pioche.
→ public LinkedList<List<Domino>> distribuerDomino (int nbJoueur) qui permet de créer à partir
des dominos présents dans la pioche des listes de 7 dominos, attribués à chaque joueur.
→ La méthode public synchronized void Envie partie( int num joueur)throws RemoteException est rap-
pelée par la partie applicative d’un joueur quand ce dernier veut jouer une partie. Cela
incrémente le nombre de joueurs qui ont demandé de jouer. Nous testons par la suite
si ce nombre est égal au nombre minimal de joueurs qui est fixé à 2 dans notre projet.
Dans ce cas, l’arbitre signale aux joueurs inscrits le début de la partie et leurs distribue
les dominos.
→ Si un joueur n’a plus de dominos, il rappelle la méthode public void finPartie ( int idJoueur)
throws RemoteException pour signaler la fin de la partie. L’arbitre envoi aux autres joueurs
l’identité du joueur vainqueur qui est le joueur qui a évoqué la méthode.
12
II.3. JEU D’ESSAI II. Réalisation & Exploitation
13
Conclusion
État d’avancement
À l’issue de ce projet, le produit rendu est assez loin de l’objectif de ce projet qui était
d’implémenter et de tester un algorithme de gestion de l’exclusion mutuelle. Cependant, les
réflexions que nous avons pu avoir sur les codes CSP, celui de la partie contrôle qui était fournit
ou de la partie applicative que nous avons développée ont tout de même fait naı̂tre quelques
interrogations.
Comme le montrait le dernier exemple, la communication entre les sites et le début de la
partie fonctionne (moyennant encore quelques petites erreurs). Nous nous sommes d’ailleurs
concentré en priorité sur l’arbitre et la partie applicative du joueur, le contrôle et la gestion de
l’exclusion mutuelle étant correctement détaillé dans le sujet.
14