Lurois Frederic Gratien Xavier Licence Informatique TRAVAIL D'ETUDES ET DE RECHERCHE : AWELE I. INTRODUCTION ------------ Le but de ce TER est de realiser le jeu Awale utilisant une interface graphique conviviale. On aura trois possibilites : jouer contre la machine, contre un joueur humain, ou observer une partie se deroulant entre deux autres joueurs. L'interface utilisateur permet au joueur humain de dialoguer avec le moteur du jeu. Le plateau du jeu Awale est constitue de deux rangees de 6 trous. Au debut du jeu, chaque case du plateau est garnie de quatre graines. Le plateau est muni de deux trous a ses extremites ou sont entreposees les graines capturees par chaque camp. Le but du jeu est de capturer le plus grand nombre de graines... Ce document presente les differents choix que nous avons effectue pour implementer les trois types de moteurs et l'interface utilisateur. II. LES DIFFERENTS MOTEURS ---------------------- Tout au long de ce TER, nous avons cherche a generaliser nos methodes au maximum, de facon a ce qu'elles puissent etre communes aux trois types de moteurs. Nous avons donc defini la classe abstraite Moteur qui implemente l'interface MoteurProto et qui contient egalement d'autres methodes necessaires a la gestion des differents moteurs. On y trouve donc les methodes : - initialise - legal - charge - sauve presentes dans l'interface MoteurProto, mais egalement les methodes : - famine() : qui permet de tester si le coup que l'on veut jouer ne cree pas de famine chez l'adversaire - distribuer() : qui distribue les graines sur le plateau de simulation - capture() : qui effectue les differentes capture sur le plateau de simulation - est_vide() : qui permet de tester si le camp d'un des joueurs est vide - copiePlateau() : qui effectue la copie d'un plateau - copieReserves() : qui effectue la copie des reserves - partieTerminee() : qui cherche qui est le gagnant de la partie - afficherDistribution() : qui effectue l'animation du deplacement d'une graine d'une case a une autre La methode joue n'est pas definie dans la classe Moteur, c'est une methode abstraite car elle differe selon le type de moteur lance. Il nous faut donc la redefinir pour chacun des moteurs a realiser. 1) Le Moteur Homme/Machine ----------------------- Ce moteur est en fait une classe (la classe Moteur_hm) qui derive de la classe Moteur decrite precedemment. Elle possede donc toutes les methodes definies precedemment en plus de ses propres methodes : - joue() : qui realise le coup choisit, si celui ci est legal, par le joueur humain - choisirCoup() : qui realise le coup choisit par la machine L'intelligence de notre moteur consiste a choisir le coup qui lui rapportera le plus de graines. Si aucun coup ne lui permet de capturer des graines, il choisit un coup aleatoirement, parmi tout ceux qu'il peut effectuer. Bien sur, ces operations ne sont pas effectuees s'il se trouve dans l'obligation de nourrir le joueur humain. Les tests de fin de partie sont effectues par la machine, avant et apres qu'elle effectue son coup... 2) Le Moteur Serveur ----------------- Cette classe (la classe Moteur_s) derive de la classe Moteur. Elle est plus complexe que la classe Moteur_hm car elle doit gerer beaucoup plus d'element a la fois : les connexions avec le client et les espions... Lorsque l'on lance un moteur serveur, ce dernier attend une connexion. Lorsqu'une connexion est etablie, il identifie le connecté : s'il s'agit d'un client, il lance un thread "Client" qui s'occupera de jouer une partie avec le moteur client, s'il s'agit d'un espion, il lance un thread "Espion" dont le but sera d'envoyer les differents coups joue au moteur espion. Une fois ces operations effectuees, le moteur serveur se remet en attente d'une nouvelle connexion. Le role du thread "Client" est de jouer une partie avec le client connecté, c'est a dire qu'il va commence par envoyer son plateau au client, puis il realise le coup choisit par l'utilisateur, et envoie le coup joue au client et au eventuel espion connecté, avant de recuperer le coup joue par le client et de le realiser sur son propre plateau. Le role du thread "Espion" est d'envoyer au moteur espion, chacun des coups realises par les deux joueurs pour qu'il puisse les effectues sur son propre plateau. Remarque : La classe Moteur_s implemente l'interface Runnable pour permettre a la classe qui l'a appelee de continuer son execution. outre la redefinition des methodes start() et run(), la classe Moteur_s ne possede que sa propre methode joue(). 3) Le Moteur Client ---------------- Le moteur client (la classe Moteur_c) fonctionne de maniere analogue au thread "Client", a la difference pres que le moteur commence par d'abord par recuperer le coup effectue par le serveur, il le joue sur son propre plateau, puis il effectue son propre coup, et l'envoi alors au serveur. Remarque : La classe Moteur_c implemente l'interface Runnable pour permettre a la classe qui l'a appelee de continuer son execution. outre la redefinition des methodes start() et run(), la classe Moteur_c ne possede que sa propre methode joue(). 4) Le moteur Espion ---------------- Le moteur espion (la classe Moteur_e) se contente d'attendre a l'infini (tant que la partie n'est pas finie, ou que l'espion se deconnecte) les coups que lui envoie le thread "Espion". Des qu'il recoit un coup, il se contente de le jouer sur son propre plateau, puis il se remet en attente... Remarque : La classe Moteur_e implemente l'interface Runnable pour permettre a la classe qui l'a appelee de continuer son execution. outre la redefinition des methodes start() et run(), la classe Moteur_e ne possede que sa propre methode joue(). III. L'INTERFACE GRAPHIQUE --------------------- Nous avons utiliser un canvas pour representer notre interface graphique. Sur celui ci, on a insere une image gif d'un plateau d'Awale et pour chaque trous et reserves on a mis des gif avec transparence. Le deplacement des graines a ete realisee en double buffering afin de ne pas avoir de clignotement lors des animations. Nous avons ainsi effectue des animations des graines entrant dans les differents trous. IV. PROBLEMES RENCONTRES -------------------- La principale difficulte que nous avons rencontres fut au niveau de la synchronisation de nos differents threads pour l'animation des deplacements de graines. us avons rencontres fut au niveau de la synchronisation de nos differents threads pour l'animation des deplacements de graines.