2009 : Test de QJ


Mise en situation
Niveau : BTS IRIS première année (23/03/2009)
Durée : 36 H
Equipe : 3 Etudiants
|
Objectif
- C1.6 Présenter la mise en œuvre d’une solution informatique
- C2.1 S’intégrer dans une équipe de projet
- C4.6 Assembler les éléments matériels assurant la liaison physique dans un système de communication
- C4.7 Installer les différentes couches logicielles d’un système de communication sur une station
- C4.8 Coder un module logiciel
- C4.9 Intégrer un module logiciel dans une application
- C5.5 Installer des services techniques internet
- C6.2 Dépanner un système informatique
- C6.6 Dépanner un module logiciel
|
Pré requis
- Programmation Java
- Initiation réseau
|
Travail demandé
- Analyse de l'application
- Documentation sur JMF (Java Media Framework)
- Créer une interface Java
- Utiliser la dérivation pour la création d'objets
- Design en Java
- Appréhender le concept MVC (Modèle Vue Contrôleur)
|
Matériel
- PC de développement
- Un PC serveur de développement
- Un hébergeur Internet
|
Critères d’évaluation
- Un rapport par groupe figurant la description du travail fourni. Une première partie décrit le travail du groupe, puis chaque étudiant décrit son propre travail. Le rapport doit être clair et doit servir de guide d’utilisateur c’est à dire qu’un utilisateur doit pouvoir à l’aide de ce rapport facilement utiliser l’application développée. Les sources du code seront données en annexe.
- Un exposé oral d’une durée de 15mn, décomposé en 10mn sans interruption du jury suivi de 5mn de questions. Cet exposé aura comme support le rapport précédemment décrit. Il se déroulera dans la semaine 20/21.
- Une démonstration du développement en cours de TP
- Une partie du travail se fait en groupe, une autre individuellement. Mais le principe est de réaliser la totalité de l’application. Le travail de groupe est donc prédominant, l’entraide entre étudiant est donc souhaité, voir indispensable.
- Un CD de sauvegarde de l’ensemble du travail (Rapport, code, manuel d’utilisation…)
|
Mise en situation
Le but du projet est de créer un logiciel de test d'agilité du cerveau.
La Nintendo DS a ouvert la voie à de nombreux jeux de réflexion. Certes, ils existaient déjà avant, mais ils ont pris de l’ampleur depuis le fameux Docteur Kawashima. 4 mini-jeux devront être proposés, ils correspondent à 4 entraînements cérébraux différents : analyse, calcul, mémoire, visualisation. Le niveau augmente au fur et à mesure
Exemple de jeu
Analyse
Le jeu consiste à proposer de façon aléatoire un trajet pour une ou plusieurs voitures placées en haut de l'écran est devant aller en bas. La voiture doit tourner à chaque angle. Le joueur doit trouver la ou les arrivées des voitures le plus rapidement possible.
Exemples :
Calcul
Le jeu consiste a retrouver l'opération le plus rapidement possible. L'ordinateur propose 4 nombres et deux opérations, ainsi qu'un résultat. Il faut retrouver l'ordre des opérandes et de l'opération.
Ex :
Mémoire
De façon dynamique, des groupes de personnes rentrent par la porte d'une maison. De même des groupes d'anges entrent par la fenêtre. Certains sortent d'autres restent dans la maison. Le but est de donner le nombre de personnes (sachant qu'un ange est une personne) restantes dans la maison une fois la séquence terminée.
Exemple d'une séquence :
- 2 personnes entre en même temps 1 ange entre
- 1 personnes entre, 1 ange entre, en même temps 1 personne sort et 1 ange sort
La réponse est 3. La difficulté réside dans le fait que les êtres peuvent entrer ou sortir en même temps et en nombre aléatoire.
Exemple :

La solution est 3 êtres sont restés dans la maison
- Pour exemple :
L'ordinateur donne une séquence de boutons qui "clignotent". Le joueur doit cliqué sur les rectangles pour retrouver cette séquence. Le but est de trouver la séquence la plus longue. Dès qu'il y a une erreur, la séquence redémarre à un.
Cliquer sur démarrer pour lancer le jeu
Remarque :Pour avoir le diagramme de classes et le code de la programmation multitâches, voir les annexes.
Visuel
L'ordinateur propose différentes formes de différentes tailles. Le joueur doit remettre dans l'ordre croissant de taille par glissement à la souris dédites formes.
Est pris en compte :
- Pour un cercle, le diamètre
- Pour un parallélogramme, le diamètre du cercle circonscrit
- Pour un triangle, le diamètre du cercle circonscrit
- De manière générale (Polygone), le diamètre du cercle circonscrit
Exemple :
Travail demandé
Travail de groupe
Il faut créer "l'enveloppe" qui contiendra tous les jeux. Ainsi, le joueur doit pouvoir choisir son jeu. Il peut rentrer son nom, et un liste des 10 meilleurs scores est affichable. Le calcul du score est à créer.
Le travail du groupe consistera à :
- Analyse du logiciel global
- Création du diagramme de classe pour mutualiser certaines classes (ex : Timer)
- Création du "conteneur"
- Documentation sur le graphisme en Java (JMF : Java Media Framwork ...)
Etudiant 1, 2 et 3
Chaque étudiant sera en charge d'une rubrique (Analyse, calcul, mémoire et visuel)qui sera choisi par assemblée générale du groupe. Le thème restant sera réservé au plus rapide. La communication sera très importante car certaines parties des jeux se ressemblent (d'où l'importance d'une analyse commune en UML).
Annexes
Documentation
Exported from Notepad++
/**
* Composant de base du jeu. Sert principalement à la visualisation
*/
package jeuxqi;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author Didier Petitjean le 07/02/2009
*/
public class JeuLumiere extends JComponent{
private JPanel centre = new JPanel();
private JButton start = new JButton("Démarrer");
private JButton boule[] = new JButton[4];
private JPanel nord = new JPanel();
private JLabel score = new JLabel("Max = 0");
private JLabel temps = new JLabel("Temps = 30");
private Object moniteur = new Object();
private Moteur moteur = null;
private Temps decompteur;
private Ecouteur ecouteur = new Ecouteur(this,moniteur);
/**
* Débute le jeu en lancant le timer et le moteur
*/
public void demarre(){
moteur = new Moteur(this,moniteur);
decompteur = new Temps(this, moteur,30);
moteur.start();
decompteur.start();
setTemps("Temps = 30");
setScore("Max = 0");
}
/**
* Sert de lien entre l'écouteur et le moteur pour passer le numero du bouton cliqué
*/
public void setBoutonCourant(int courant){
moteur.setBoutonCourant(courant);
}
public JeuLumiere(){
int i;
setLayout(new BorderLayout());
start.addActionListener(ecouteur);
add(start, BorderLayout.SOUTH);
add(centre, BorderLayout.CENTER);
centre.setLayout(new GridLayout(5,5));
// Init du panel nord
add(nord, BorderLayout.NORTH);
nord.setLayout(new FlowLayout());
nord.add(score);
nord.add(temps);
// Init des 4 boutons de couleur mis au entre
for(i=0; i<4; i++){
boule[i] = new JButton();
boule[i].addActionListener(ecouteur);
}
for(i=0; i<7;i++)
centre.add(new Vide());
centre.add(boule[0]);
for(i=0; i<3;i++)
centre.add(new Vide());
centre.add(boule[1]);
centre.add(new Vide());
centre.add(boule[2]);
for(i=0; i<3;i++)
centre.add(new Vide());
centre.add(boule[3]);
for(i=0; i<7;i++)
centre.add(new Vide());
boule[0].setBackground(Color.blue);
boule[1].setBackground(Color.red);
boule[2].setBackground(Color.yellow);
boule[3].setBackground(Color.green);
}
/**
* Met en noir puis remet la couleur initiale du bouton dont le numéro
* est passé en argument
*/
public void changeCouleur(int cercle) throws InterruptedException{
Color couleur = boule[cercle].getBackground();
boule[cercle].setBackground(Color.black);
Thread.sleep(350);
boule[cercle].setBackground(couleur);
Thread.sleep(250);
}
/**
* Affiche le nouveau score
* @param nouveau
*/
public void setScore(String nouveau){
score.setText(nouveau);
}
/**
* Affiche le temps restant
* @param nouveau
*/
public void setTemps(String nouveau){
temps.setText(nouveau);
}
}
/**
* Moteur de l'application du jeu. La classe permet de savoir si la séquence cliqué
* par le joueur est la même que celle de l'ordinateur.
*/
package jeuxqi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Didier Petitjean 08/02/2009
*/
public class Moteur extends Thread {
private JeuLumiere jeu;
private boolean fin = false;
private boolean finSequence = false;
private boolean egal = false;
private ArrayList listeSequence = new ArrayList();
private ArrayList sequenceUser = new ArrayList();
private Random alea = new Random();
private int numeroBoutonCourant = 0;
private int max = 0;
private Object moniteur;
public Moteur(JeuLumiere jeu, Object moniteur){
this.jeu = jeu;
this.moniteur = moniteur;
}
public void run() {
System.out.println("Démarre");
fin = false;
// Tant que le chrono tourne
while(!fin){
egal = true;
finSequence = false;
listeSequence.add(new Integer(alea.nextInt(4)));
// Affichage de la séquence de l'ordinateur
sequence();
// Séquence de choix de l'user
while((!finSequence)&&(egal)){
// Attente clic user
synchronized(moniteur){
try {
moniteur.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Moteur.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Ajoute le clic du joueur à sa séquence en cours
sequenceUser.add(numeroBoutonCourant);
// Compare la séquence du joueur avec celle de l'ordi
egal = compare();
if(listeSequence.size()==sequenceUser.size())
finSequence = true;
}
if(egal){
// Nouveau max du jeu
if(max < listeSequence.size()){
max = listeSequence.size();
jeu.setScore("Max = "+max);
}
}
else{
// Erreur de l'utilisateur sur une séquence
listeSequence.clear();
}
sequenceUser.clear();
}
max = 0;
}
/**
* Compare la suite de l'ordinateur avec celle de l'utisateur
* @return vrai si le début de la liste de l'ordi est égal à la liste user
* faux sinon
*/
private boolean compare(){
Integer ordi, user;
int compteur = 0;
Iterator iterateur = sequenceUser.iterator();
while(iterateur.hasNext()){
user = (Integer) iterateur.next();
ordi = (Integer) listeSequence.get(compteur);
compteur++;
if(!user.equals(ordi))
return false;
}
return true;
}
/**
* Fin du jeu
*/
public void arret(){
fin = true;
}
/**
* Affiche une séquence de l'ordi avec clignotement des boutons
*/
private void sequence() {
Integer courant;
Iterator iterateur = listeSequence.iterator();
while(iterateur.hasNext()){
courant = (Integer) iterateur.next();
try {
jeu.changeCouleur(courant.intValue());
} catch (InterruptedException ex) {
Logger.getLogger(Moteur.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void setBoutonCourant(int courant){
numeroBoutonCourant = courant;
}
}
/**
* Ecouteur sur les boutons du jeu
*
*/
package jeuxqi;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
/**
* @author Didier Petitjean le 07/02/2009
*/
public class Ecouteur implements ActionListener{
private Object moniteur;
private JeuLumiere jeu;
public Ecouteur(JeuLumiere jeu, Object moniteur){
this.moniteur = moniteur;
this.jeu = jeu;
}
/**
* Quand un bouton est clic, demarre le jeu ou passe au moteur le numéro du bouton cliqué
* et le libère de son wait (Rendez-vous)
*/
public void actionPerformed(ActionEvent e) {
JButton courant = (JButton) e.getSource();
Color couleur = courant.getBackground();
String nom = courant.getText();
if(nom.equals("Démarrer")){
System.out.println("Ecoute");
jeu.demarre();
}
if(couleur == Color.blue){
jeu . setBoutonCourant(0);
synchronized(moniteur){
moniteur.notify();
}
}
if(couleur == Color.red){
jeu . setBoutonCourant(1);
synchronized(moniteur){
moniteur.notify();
}
}
if(couleur == Color.yellow){
jeu . setBoutonCourant(2);
synchronized(moniteur){
moniteur.notify();
}
}
if(couleur == Color.green){
jeu . setBoutonCourant(3);
synchronized(moniteur){
moniteur.notify();
}
}
}
}
/**
* Tâche servant de timer. Affiche toutes les secondes le temps restant
* Arrête le moteur à la fin du décompte
*/
package jeuxqi;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Didier Petitjean 08/02/2009
*/
public class Temps extends Thread{
private JeuLumiere jeu;
private Moteur moteur;
private int seconde;
public Temps(JeuLumiere jeu, Moteur moteur, int seconde){
this.moteur = moteur;
this.jeu = jeu;
this.seconde = seconde;
}
public void run(){
int compteur = seconde;
while(compteur > 0){
try {
sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Temps.class.getName()).log(Level.SEVERE, null, ex);
}
compteur--;
jeu.setTemps("Temps = "+compteur);
}
moteur.arret();
}
}
/**
* Applet contenant le composant JeuLumiere
*/
package jeuxqi;
import javax.swing.JApplet;
/**
* @author Didier Petitjean 08/02/2009
*/
public class IHM extends JApplet {
public void init() {
add(new JeuLumiere());
}
}
/**
* Permet d'avoir une disposition régulière quelque soit la taille du composant
* contenant les boutons de couleur
*/
package jeuxqi;
import javax.swing.JComponent;
/**
* @author Didier Petitjean 08/02/2009
*/
public class Vide extends JComponent{
}

