Carnet de bord

Vendredi 05 Décembre :

 

 Nous avons réfléchis sur l’allure générale de notre programme , ce que l’utilisateur verra. Nous sommes partis sur l’idée d’une fenêtre rectangulaire nous n’avons pas trouvé la taille idéale nous y re réfléchirons le vendredi suivant. Nous avons fait la légende des balles :

-La balle rouge : la couleur n’y est pas .

- La balle noir : la couleur y est mais mal placée

- La balle blanche : la couleur y est et est bien placée

Puis nous avons choisis le nombre de balle de différentes couleur que pourra choisir l’utilisateur . Nous avons choisis 6 couleurs différentes.

Parmi toutes ces balles de différentes couleurs l’utilisateur en choisie 5 et il peut mettre plusieurs fois la même . On s’est demandée combien d’essais étaient nécessaire pour que le jeu soit ni impossible ni trop facile . On a choisis comme base de départ 10 essais . Puis pour voir la faisabilité du jeu nous l’avons testé sur une feuille de papier.

En essayant de faire le jeu avec les règles que nous avions établie de nouveaux problèmes se sont posés a nous . 

 

Comme la balle d’une même couleur  pouvait être à deux endroits différents,  si l’ordi a choisi un ensemble de couleur dont la couleur choisi en double par l’utilisateur y est une fois, alors la couleur y était mais n’y était pas à la fois, ce qui est contradictoire. Cela remet donc en question notre légende de départ concernant les balles. 

 

On s’est demandé si on devait ajouter une balle de légende qui serait « la balle y est une fois mais pas plusieurs fois » or cela changeait le jeu Mastermind. Il y a donc quelque chose dans notre règle qui fait que ça ne marche pas.

Nous avons donc pour objectif la prochaine fois de trouver une solution au problème.

Allure provisoire : 

Vendredi 19 décembre 2014 :

 

Nous avons réduis le nombre de balles que l'utilisateur doit choisir à 4 . Nous avons augmenté le  nombre de couleurs possible à 8. 

- 0 36 255 //bleu foncé

- 250 255 0 // jaune

- 0 227 255 // bleu clair

- 14 224 39 //vert

- 255 0 0 //rouge

- 255 15 228 //rose

- 102 10 142 //violet

- 255 166 0//orange

 

Nous avons ensuite trouvé la solution au probléme de la semaine derniére : -une boule noire signifie que la balle est mal placée mais que la couleur est présente. 

                                                                                                                                  -une boule blanche signifie que la balle est bien placée.

 

 

- 0 0 0//noir

- 255 255 255 //blanc

 

Nous avons aussi mis à jour le carnet de bord. 

 

 

Mardi 30 Décembre 2014:

 

Nous avons fais notre site web ensemble .  Malheureusement ce n'etait pas ce que nous attendions ! Nous avons donc passé beaucoup de temps à essayer d'enlever un fond sur un théme .Mais ce site ne permet pas de changer un fond facilement . Finalement nous avons changé de théme . 

Ensuite nous avons commencé la trace écrite de ce que nous voulions que notre programme fasse . Nous publierons la trace écrite quand elle sera finis entiérement car beaucoup d'éléments restent flous .  

Vendredi 09 Janvier 2015:


 

Nous avons commencé l'interface graphique avec GUI builder. Nous avons crée un bouton " valider " pour que l'utilisateur puisse valider son choix . En allant dans le GUI on a modifier la taille de l'interface et sa couleur . Nous avons aussi mis un label servant de titre . Voici l'apperçu de l'interface pour l'interface actuelle: 

 

Nous avons ensuite réflechis a comment faire valider une par une ces couleurs à l'utilisateur . Nous avons penser a mettre sous chaque boules une bouton tournant à 10 positions qui ferait varier la couleurs de la boule . Nous essairons cette solution au prochain cour .  Voici le code du sketch puis du BuI que vous pouvez aussi voir dans la partie " Etat du code " . 

Sketch code :

 

 

Dimanche 11 Janvier 2015:


 

Nous avons fait un récapitulatif déroulant de comment doit s'organiser notre code . Il y aura une partie graphique , et une pour le coeur du jeu. 

Voici le récapitulatif de ce que doit faire le code ( or interface graphique ) :


 

1/ Distribution aléatoire ( combinaison) pour l'IA ( combinaison qui sera caché )

 2/ Le jeu démarre ( joueur choisit )

3/ IA indique :

- nombre de bonne couleurs bien placées

- nombre de bonne couleurs bien placées

ex : 

break = fin du jeu

combJ = combinaison joueur

combC = combinaison IA

1 = il reste des tours

2= le joueur n'a pas trouvé 

* si combJ == combC alors ( break )  

* tant que ( 1&&2 ) ( not break)


 

4/ Si le joueur n'a pas trouvé a la fin = perdu sinon = gagne 


 

Il faut maintenant qu'on réussisse à mettre tout cela sous forme . Le 1 er probléme pour le coeur du jeu auquel nous avons a faire est la distribution aléatoire des balles pour l'IA. 

Nous pensons qu'il faudra d'abord créer une liste de boule de differentes couleurs dans laquelle l'IA en piochera aléatoirement . 

- list = newList ;

 

Vendredi 16 Janvier 2015: 

 

Grâce à GUI Builder, nous avons créer huit boutons sur lesquels nous avons inscrit la couleur correspondante.  Nous nous sommes alors demandées comment faire pour faire apparaitre une balle lorsqu'on clique sur un bouton, puis comment faire pour que la balle soit de la couleur correspondante. 

Dans un premier temps nous avons déclarer les variables x et y, ensuite nous avons rajouter la méthode fill (couleur()), puis ellipse (x,y,30,30) et enfin x=x+30. Ainsi lorsque nous cliquons sur un bouton la balle s'affiche, et si nous recliquons sur le même bouton ou un autre, une balle s'affiche à côté de la première et ainsi de suite.

Voici à quoi ressemble notre interface graphique pour le moment: 

 

   

 

Vendredi 23 janvier 2015: 

Dans un premier temps, nous avons associé chaque couleur choisie à tout les  boutons correspondants avec la méthode fill et ellipse. Dans un second temps nous avons cherchés à faire afficher les quatre balles les unes à la suite des autres, puis lorsque l'on clique sur la touche " Valider ! " faire afficher quatre autres balles en dessous des précédentes. Nous avons donc rajouter les lignes de codes qui suivent sous le println associé au bouton valider : 

y=y+50;

  x=50;

Vendredi 30 janvier 2015:

Nous nous sommes intéressées à la partie de l'IA. Nous avons donc commencés par tenter de comprendre le code de mastermind que le professeur nous a envoyé. Le code étant divisé en trois parties, la création aléatoire de la combinaison secrète, le void keyPressed() et le void submit(). Nous nous sommes penchées sur la création aléatoire de la combinaison, et avons modifiés le code qui nous servait d'exemple afin qu'il soit adapté à notre projet.

Voici le code en question : 

/* Transposition sur Processing du mastermind simplifié de Javascool. A TERMINER*/
int combinaisonMystere []={0,0,0,0};
int combiSaisie []={0,0,0,0};
boolean victoire = false;
int i;
int x=0;
int y=0;
int keyIndex = 0;
int keynom =0;
boolean combiOK = false;
boolean estOK = false;
int nombredecoup =0 ;
 
boolean [] estEvalueMystere = {false, false, false, false};
String phrase1;
void setup(){
   background(0);
  size(640, 660);
  //println("Programme test permettant de suivre les valeurs de variables au cours de son exécution");
  text ("Java Mastermind 4 couleurs. Jouez contre l'ordinateur.", 0, 20);
 
 
  // Création aléatoire de la combinaison mystère
 
 
   for (i = 0; i < 4 ; i ++) {
  //combinaisonMystere [i]=(int)(Math.random() * (100));
  while ( combinaisonMystere [i] != 82 && combinaisonMystere [i] != 86 && combinaisonMystere [i] != 66 && combinaisonMystere [i] != 74) {
     combinaisonMystere [i]=(int)(Math.random() * (100));
 
     //println(i);
     //println (combinaisonMystere [i]);
     }
 
        }
  //char combinaisonMystere = (char)(Math.random() * (10000));
  //println ("La combinaisonMystere est");
   for (i = 0; i < 4 ; i ++) {
  println (combinaisonMystere [i]);
  }
    phrase1 = ("" + (char) (combinaisonMystere[0]));
      for (i = 1; i < 4; i ++) {
         phrase1 += "  " + ("" + (char) (combinaisonMystere[i]));}
         println (phrase1);
 
 
  text("Les 4 couleurs possibles sont Rouge(82) Vert(86) Bleu(66) et Jaune(74)", 0, 40);
 
 

}

void keyPressed() {
 
 
  if (key == 'r' ) { combiSaisie [keyIndex] = 82;text("R",x,y+200);
 
  if (keyIndex <3){keyIndex = keyIndex +1;}else { keyIndex =0; submit();}
   x=x+10;
  if (x==40){x=0; y=y+20;}
  }
  if (key == 'b' ) { combiSaisie [keyIndex] = 66;text("B",x,y+200);
    if (keyIndex <3){keyIndex = keyIndex +1; }else { keyIndex =0; submit();}
     x=x+10;
  if (x==40){x=0; y=y+20;}
  }
  if (key == 'v' ) { combiSaisie [keyIndex] = 86;text("V",x,y+200);
    if (keyIndex <3){keyIndex = keyIndex +1;}else { keyIndex =0; submit();}
     x=x+10;
  if (x==40){x=0; y=y+20;}
  }
  if (key == 'j' ) { combiSaisie [keyIndex] = 74;text("J",x,y+200);
    if (keyIndex <3){keyIndex = keyIndex +1;}else { keyIndex =0; submit();}
     x=x+10;
  if (x==40){x=0; y=y+20;}
  }
 
 
  
}

void submit(){
  text("Vous avez " + (8-nombredecoup) +" essais",200,y+200);
  nombredecoup = nombredecoup+1;
  text (combiSaisie [keyIndex], 100, y+200);
  if (nombredecoup ==8) {text("Vous avez perdu",200,y+220);x=0;y=0;fill(0); rect(0,150,400,400);nombredecoup =0;}
        int valeur []={0,0,0,0};
        int x1=0;
        int y1=0;
        for (int i = 0; i < 4; i ++) {
         valeur [i] = combiSaisie [i];
         //println (valeur[i]);
         // test des couleurs bien placées
    if (valeur[i] == combinaisonMystere [i]) {x1=x1+1;estEvalueMystere [i] = true;}}
    for ( i = 0; i < 4; i ++) {
    // test des couleurs mal placées ( A REVOIR !!!!!!)
    
 
      for (int j = 0; j < 4; j ++) {
        //boolean b = valeur[i] == combinaisonMystere [j] && i != j && estEvalueMystere [j] == false;
        //println (b);
      if (valeur[i] == combinaisonMystere [j] && i != j && estEvalueMystere [j] == false ) {y1=y1+1; estEvalueMystere [j] = true;}
      } 
 
      }
      println (x1 + " couleurs bien placées");
      text (x1 + " couleurs bien placées", 350, y+200);
      if (x1 == 4) {nombredecoup =8;println ("Vous avez gagné"); text("Vous avez gagné",100,500);victoire = true;}
      println (y1 + " couleurs mal placées");
      text (y1 + " couleurs mal placées",350,y+210);
      //Ecrire sur la console les lettres correspondant au code ASCII des caractères
String phrase = ("" + (char) (valeur[0]));
      for (i = 1; i < 4; i ++) {
         phrase += "  " + ("" + (char) (valeur[i]));}
         //println (phrase);  
 

if (victoire == false) { println("Vous avez perdu");println (phrase1);}



}

void draw() {

fill(102);
rect(81, 81, 63, 63);


}

 

Vendredi 30 janvier au soir :

 

Nous avons continués l'interface , il fallait limiter le nombre de boule par tour et limiter le nombre de tour . 

 

Limiter le nombre de  tour : - définission d'une variable définissant le nombre  de tour max et une variable qui indique le tour courant s'écrémentant à chaque validation de tour . 

 

Limiter nombre balles : - on a mis un nombre de boule max par tour , plus une variable qui s'écremente à chaque ajout de boule et se remet à zéro lors de chaque tour .

 

Nous avons définis huit variables couleurs qui nous serons utile à la fois pour l'affichage et les algorithmes du mastermind . 

 

Grace à tout ceci le joueur ne peut pas dépasser le nombre de boule maximun d'un tour et ne peut pas valider son choix  le temps qu'il n'a pas mis le nombre de boules maximum . 

 

 

Samedi 31 janvier 2015 : 

 

Nous avons créés deux tableaux .  Le premier contient la combinaison  gagnante , puis un vide de la même taille que celui de la combinaison gagnante. 

A chaque fois que l'on ajoute une boule , la boule est ajoutée dans le deuxième tableau  puis quand on valide le choix on appelle une fonction qui fait la comparaison entre les deux tableaux. 

Cette fonction parcours la combinaison du joueur en comparant une à une les couleurs par rapport au tableau de la combinaison  gagnante . 

Si toutes les couleurs sont identiques alors la partie est gagnée sinon on continue la partie .

Nous avons encore continués l'interface . Nous avons mis une condition sur le bouton valider ( en plus de celle victoire ) qui vérifie si le nombre du tour courant n'est pas égal à celui du tour maximum , si elle est égale au nombre de tour max et que la combinaison n'est toujours pas bonne , " defaite " s'affiche sur l'interface .

On modifie le texte du bouton valider qui devient " recommencer "  et donc on utilise une nouvelle variable boolean " recommencer"  ( qui est à faux par défaut ) nous l'avons mis à vrai à ce moment là. 

Ensuite on rajoute une nouvelle condition au clic du bouton  valider ( au début du code de gestion clic bouton ) qui va tester si la variable recommencer est à vrai . Si elle est vrai on met le boolean " recommencer " à faux , et on appel la fonction setup dans laquelle  nous avons placé le code d'initialisation du jeu ( background , variables , tableau ==> et contiendra quand nous l'aurons fait la fonction de combi aléatoire ) . 

 

Dimanche 01 février  2015 :

 

Jusqu' à présent nous avions testés le jeu avec une liste gagnante fixe maintenant nous avons rajoutés une fonction de combinaison gagnante aléatoire . 

combinaison gagnante aléatoire : nous avons créés un nouveau tableau qui contient toutes les couleurs possibles . On créé la fonction " compiutrandomcombinationwin " , qui va attribuer à chaque élément du tableau une couleur aléatoire de la liste de couleur . Pour chaque éléments du tableau de combinaison gagnante :

  • on choisit un index ( entier qui indique la position dans le tableau ) aléatoire compris entre 0 et la taille de la liste de couleurs -1

  • on récupère la couleur située à cet index dans la liste de couleur ( nous avons donc récupérés une couleur aléatoire ) .

  • On attribue cette couleur aléatoire à l’élément en question .

 

Il ne manque plus qu'à vérifier pour chaque tour qu'elles sont les boules de couleurs bien placées et mal placées .

 

Pour ceci à la fin de chaque tour , dans le cas ou la combinaison n'est pas gagnante , on appelle une fonction qui va calculer ces informations.

Le principe c'est qu'on compare un à un les éléments entre les deux tableaux ( combinaison joueur et gagnante ) . Si la couleur est identique on incrémente le nombre de boule de bonnes couleurs bien placé , sinon on cherche cette couleur dans tous les autres index de la combinaison gagnante . Si on retrouve la couleur parmi ces index alors on incrémente le compteur du nombre de bonne couleur mal placée ( pour cela on appelle une fonction qui a pour paramètre la couleur en question et son index dans le tableau du joueur et qui va comparer la couleur avec tous les index différents de celui donné en paramètre , et qui renvoie 1 si cette couleur est trouvée et sinon 0) .

Il suffit ensuite d'afficher à chaque tour sur l'interface ces informations à côtés des balles choisies par le joueur.

 

Vendredi 6 Février 2015:

 

Nous nous sommes rendu compte que nous n'avions pas écrit sur l'interface ce qu'était une balle blanche et une balle noire . Mais nous ne pouvions pas ré ouvrir GUI car sinon il supprimait tout ce qui a été fait . Nous avons donc directement fait la modification sur notre programme :

 

infosBW = new GLabel(this, 580, 650, 200, 80);
infosBW.setText("Blanche: bonne couleur bien placée\nNoire: bonne couleur mal placée");
infosBW.setTextAlign(GAlign.LEFT, GAlign.MIDDLE);
 
 
Vendredi 13 février 2015 :
Nous avons fait un bouton qui permet au joueur de corriger son choix de couleur , c'est à dire qu'il peut supprimer une ou plusieurs balles du tour . Pour cela on remet le pointeur de la position " n " a la position " n- 1"  , on supprime la boule en remplissant avec la couleur du background sans oublier de mettre à jour que le joueur a joué une boule de moins quand il appuit sur supprimer.
 
public void removeBall() {
  x -= 50;
  fill(backgroundColor);
  ellipse(x,y,radius,radius);
  --turnBallsCount;
}

 

Lundi 23 Février 2015 :

Cependant, comme on supprime une balle en en rajoutant une "creuse" par dessus, il reste toujours le contour. Nous avons donc decidé que pour chaque début de tour, nous allions déssiner 4 balles creuses qui seront ensuite remplies par le joueur.

On regle ainsi le probleme précédent tout en permettant au joueur de voir directement lorsqu'il a enclenché un nouveau tour, le nombre de balles à jouer, etc.

 

public void drawNewTurn() {

  noFill();
  for (int i = 0; i < nbBallsByTurn; ++i)
    ellipse(x + i*50, y, radius,radius);
A l'aide de cette boucle on dessine "n"  balles creuses (noFill), "n" correspondant au nombre de balles dans un tour.
 

 

 

Nous avons décidé de répartir le code de la manière suivante :
 mastermind.pde : sketch principal servant à initialiser toutes les variables nécessaires et contenant les fonctions setup() et draw() de Processing.
 ball.pde : sketch contenant les constantes propres aux balles, comme par exemple la taille, la position à laquelle les placer, les couleurs qu’elles peuvent prendre.
 combination.pde : sketch contenant une classe définissant le concept de combinaison. Une combinaison est une liste de couleurs, et la classe combination contient plusieurs fonctions comme générer une combinaison aléatoire, comparer la combinaison avec une autre, etc.
 turn_infos.pde : sketch contenant une classe qui permet de stocker des infomrations relatives à un tour, comme le nombre de balles de bonnes couleurs bien/mal placées. Cette classe contient également une fonction permettant de calculer ces informations.
 gui.pde : sketch contenant toutes les fonctions et variables relatives à la gui, c’est-à-dire tous les labels et boutons avec les fonctions associées à déclencher (ex : afficher une balle, valider un tour, etc.). DESCRIPTION DU CODE mastermind.pde
setup() : void
Setup continent toutes les initialisations des variables :
 on indique le nombre de balles à trouver
 le nombre de tours pour y parvenir
 On creé un tableau contenant toutes les couleurs possibles
 on définit la taille de la balle et sa première position
 on initialise les variables de jeu (numéro du tour à 1, nombre de balles jouées à 0, etc.)
 on génère une combinaison aléatoire à trouver
 on affiche les 4 premières cases à remplir par le joueur
isVictory()
Cette fonction booléenne n’a pour but qu’une meilleure lisibilité du code. Elle appelle la méthode equals() de la classe combinaison pour vérifier si la combinaison du joueur est identique à la combinaison gagnante.
Renvoie vrai ou faux en fonction. ball.pde
Aucune fonction, ne sert seulement qu’à définir les couleurs possibles et les variables relatives à la balle (position, taille). combination.pde
Continent la définition de la classe Combination. Celle-ci contient une variable d’instance (qui définit les caractéristiques de l’objet) un tableau de couleurs (color[] combination).
Cette classe contient les méthodes suivantes :
 
Combination(int length)
C’est le constructeur de la classe Combination, il est chargé de créer un objet de type Combination et d’initialiser ses variables de classe (ici le tableau de couleurs).
Il prend en paramètre un entier qui servira à définir la taille du tableau de combinaison.
getCombination()
Accesseur de la variable combination. Type de retour : color[]
setCombination(color[] combination)
Mutateur de la variable combination.
computeRandomCombination()
Méthode permettant de modifier la combinaison actuelle en une nouvelle combinaison aléatoire.
Pour cela :
 On parcourt la combinaison (tableau de couleur) à l’aide d’une boucle for
 Pour chaque élément :
o On choisit un nombre aléatoire entre 0 et la taille de la liste des couleurs possibles – 1
o On récupère une couleur à l’index aléatoire précédemment obtenu
o On attribue cette couleur à l’élément courant
equals(Combination c)
Cette méthode permet de comparer la combinaison courante à une autre combinaison et ainsi indiquer si celle-ci est identique ou non. On retourne don une valeur booléenne.
Pour cela :
 On parcourt la combinaison à l’aide d’une boucle for
 On compare les couleurs une à une :
o si elle est différente on s’arrête et on retourne faux, les combinaisons sont différentes
o sinon on continue
 Si on atteint la fin de la boucle alors, toutes les couleurs sont identiques, on retourne vrai.
print()
Cette methode est utile pour debugger. Elle affiche pour chaque couleur de la combinaison, ses composantes R, G, B à aide des fonction red(int color), green(int color) et blue(int color).
turn_infos.pde
Ce sketch contient la définition de la classe TurnInfos. Celle-ci contient deux variables entières: nbGoodColors at nbWrongColors, le nombre de balles de bonne couleur bien/mal placées.
Cette classe contient les méthodes suivantes :
 
TurnInfos()
Constructeur initialisant les deux variables à 0.
getNbGoodColors()
Accesseur de la variable nbGoodColors.
getNbWrongColors()
Accesseur de la variable nbWrongColors.
isMisplaced(int index, color c)
Fonction privée utilisée dans computeTurnInfos(). Celle-ci sert à indiquer si la couleur c placée en argument et se situant à la position index dans la combinaison du joueur, se situe ailleurs dans la combinaison gagnante. Elle permet donc d’identifier le cas d’une balle de bonne couleur mais mal placée.
Pour cela :
 On parcourt la combinaison gagnante à l’aide d’un boucle for
 Si l’index courant est différent de l’index passé en argument alors
o Si la couleur courante de la combinaison gagnante est égale à celle passée en argument, alors on est bien en présence d’une bonne couleur mal placée, on retourne alors vrai.
o Sinon on continue
 Si on arrive à la fin de la boucle, nous ne sommes pas en présence d’une bonne couleur mal placée (autres possibilité : mauvaise couleur ou bonne couleur bien placée), on retourne alors faux.
computeTurnInfos()
Cette méthode permet de calculer, à partir de la combinaison du joueur et de la combinaison gagnante, le nombre de balles de bonne couleur bien/mal placées, et met à jour les variables de classe correspondantes.
Pour cela :
 On remet à zéro les deux variables de classes
 On compare un à un les élements des deux combinaisons (gagnate et joueur) à laide d’une boucle for
o Si les couleurs sont égales ont incrémente le compteur de bonnes couleurs bien placées (nbGoodColors)
o Sinon on appelle la fonction isMisplaced citée précédemment pour vérifier que la couleur courante de la combinaison joueur ne soit pas présente ailleurs dans la combinaison gagnante. Si isMisplaced renvoie vrai alors on incrémente le compteur de bonnes couleurs mal placées (nbWrongColors)
o (Sinon on est dans le cas d’une mauvaise couleur, on n’incrémente don aucun compteur)
gui.pde
Contient toute la partie générée via le GUI Builder. Ont été rajoutées des fonctions relatives à l’affichage, et ont été remplis les fonctions relatives aux clicks sur les différents boutons.
 
drawNewTurn()
Cette fonction affiche un nombre de cercles vides égal au nombre de balles que le joueur doit trouver. Cela permet au joueur de lui indiquer le nombre de cases à remplir, ainsi que l’endroit où vont se positionner ses balles choisies. Cela lui permet de savoir ainsi également le nombre de balles restantes à jouer.
Pour cela :
 On s’assure que l’on va laisser les formes géométriques que l’on va dessiner vides avec noFill()
 On dessine n cercles vides à l’aide d’une boucle for, n étant le nombre de balles à trouver
o A chaque tour on dessine un cercle avec ellipse à la position x+i*50, y (i n° du tour de boucle) L’écart entre chaque balle étant de 50 pixels, on commence à x, y (contenant toujours la position à laquelle dessiner) et à chaque tour on va de décaler de 50 pixels vers la droite.
Ainsi si nbBallsByTurn est égal à 4, on va afficher 4 cercles vides. x et y ne sont pas modifiés, ainsi le prochain dessin de balle se fera à la position du premier cercle, donnant ainsi l’impression qu’il se remplit.
button<Color>_click1(GButton source, GEvent event)
La Color diffère en fonction du bouton cliqué. Ces fonctions sont associées aux balles de couleurs que le joueur peut choisir (balle rouge choisie en cliquant sur buttonRed_click1, etc.).
Pour cela :
 On vérifie à chaque fois que turnBallsCount < nbBallsByTurn, c’est-à-dire que le nombre de balles jouées est inférieur au nombre de balles que l’on peut jouer à chaque tour (= nombre de balles à trouver), car sinon cela veut dire que le nombre de balles à jouer est atteint.
 Si la condition est respectée on appelle la fonction drawBall(color c) pour afficher la balle jouée de la couleur c correspondante, sinon on ne fait rien.
buttonRemove_click1(GButton source, GEvent event)
Cette function (appellee par un clic sur le bouton « Supprimer ») appelle la fonction removeBall() pour effacer la dernière balle jouée.
drawBall(color c)
Cette fonction affiche la balle jouée dans la case correspondante. La couleur c diffère en fonction du bouton qui a été cliqué. Par exemple si le joueur clique sur le bouton bleu, la fonction buttonBlue_click1 va appeler la fonction drawBall(blue) qui va dessiner la balle de la couleur bleu à la position x, y (position à laquelle on dessine).
Pour cela :
 On s’assure de remplir les formes géométriques que l’on dessine avec fill(c)
 On dessine un cercle rempli de taille radius à la position x, y
 On met à jour x à x += 50 pour que la position de la prochaine balle soit décalée de 50 pixels
 On rajoute la couleur jouée dans la combinaison du joueur (variable combination)
 On incrémente le nombre de balles jouées (turnBallCount++)
removeBall()
A l’inverse de drawBall() cette function supprime la dernière balle placée par la joueur.
 
Pour cela :
 On décrémente x de 50 (on décalle de 50 pixels à gauche)
 On s’assure de remplir la prochaine balle avec la couleur du fond (on remplace ainsi la dernière balle par un cercle vide), avec fill()
 On dessine un cercle avec ellipse a la position x, y
 On décrémente le nombre de balles jouées par le joueur (--turnBallsCount)
endTurn()
Cette fonction est appelée lorsque l’on finit un tour.
Dans cette fonction :
 On affiche le nombre de balles de bonne couleur bien/mal placées contenues dans l’objet turnInfos, à l’aide de text().
 On remet x à 50, et on incrémente y de 50. On place ainsi la position de la prochaine balle à la première position d’un tour (50) et 50 pixels en dessous du tour actuel
 On incrémente le n° du tour (++turnId)
 On affiche 4 nouveaux cercles vides avec la fonction drawNewTurn()
 On remet le nombre de balles jouée par le joueur sur un tour à 0 (turnBallsCount = 0)
 On réinitialise la combinaison du joueur avec une nouvelle liste de couleur vide (combination = new Combination(4))
buttonValidate_click1(GButton source, GEvent event)
Cette function est appellee lorsque la joueur clique sur “Valider”.
Déroulement :
 Si au tour précédent le joueur à perdu ou gagné (varibale restart), on redémarre une partie en appelant la fonction setup() de processing, qui contient toute les initialisation nécessaires.
 Ensuite on vérifie que le joueur a bien remplis toutes les cases vides du tour (turnBallsCount < nbBallsByTurn)
o Si le joueur n’a pas tout rempli on ne fait rien et on s’arrête
o Sinon on continue
 On teste le cas d’une victoire grace à la fonction isVictory() décrite plus tot
o Si le joueur à gagné on affiche sa victoire en vert (fill(green) et text(str)), on met la variable restart (on indique qu’on dot recommencer au prochain valider), on change le texte du bouton « Valider » en « Recommencer » et on s’arrête
o Sinon on passe on continue
 Sinon on vérifie que le joueur à perdu, c’est à dire qu’il a atteint le nombre de tours maximum (turnId == turnMax)
o Si le joueur à perdu alors on affiche défaite, on met la variable restart à vrai, on met le texte du bouton à « Recommencer » et on s’arrête
o Sinon on continue
 Ici on est dans le cas où le joueur n’a ni perdu ni gagné, on continue la partie
 On calcule les balles de bonne couleur bien/mal placées à l’aide de la méthode computeTurnInfos() de l’objet infos.
 On appelle ensuite la fonction endTurn() qui s’occupe des actions de fin de tour (affichage des infos, affiches des cases du tour suivant…)
 
PROBLEMES RENCONTRES
Dès la première séance, nous avons rencontré un problème vis-à-vis de notre légende. La balle d’une même couleur pouvait être à deux endroits différents, mais dans ce cas la balle était à la fois présente et à la fois absente, ce qui est contradictoire. Mais si on ajoutait une nouvelle balle de légende « la balle y est une fois mais pas plusieurs fois », cela changeait le jeu du Mastermind. La semaine suivante, nous avons trouvé la solution à ce problème en instaurant une légende avec deux balles : une noire et une blanche. La noire signifie que la balle est mal placée mais que la couleur est présente, et la blanche que la balle est bien placée.
Notre second problème s’est posé sur notre site web. Nous voulions changer le fond d’un des thèmes mais nous n’y sommes pas arrivées, le site ne permettant pas de changer de fond facilement. Nous avons donc changé de thème.
Le problème suivant s’est porté sur le coeur du jeu par rapport à la distribution aléatoire des balles pour l’IA. Pour cela nous avons pensé à d’abord créer une liste de balles de différentes couleurs dans laquelle l’IA irait en piocher aléatoirement.
Nous nous sommes rendu compte que nous n’avions pas inscrit à quoi correspondait une balle noire et une balle blanche. Cependant si nous ré-ouvrions le GUI Builder, il supprimerait tout ce que nous avions déjà fait. On a donc directement fait la modification sur notre programme.
Suite à la création d’un bouton « supprimer », un dernier problème c’est posé à nous. La balle supprimée laissant son contour, on a décidé de dessiner au début de chaque tour, quatre balles creuses qui seront ensuite remplies par le joueur.
 
BILAN ET PERSPECTIVES DEVELOPPEMENT
Nous pourrions ajouter un menu avant le lancement de la partie qui nous permettrait de régler la difficulté du jeu (notamment en variant le nombre de balles à trouver ainsi que le nombre de tours pour y parvenir).
Notre projet s’effectue sur un ordinateur, nous pourrions cependant le développer sur téléphone portable ou bien sur tablette tactile afin que l’utilisateur puisse y jouer même en dehors de chez lui.
PLAN PERSONNEL
Ce projet nous a tout d'abord permis de découvrir l’informatique. Découvrir le monde qui se cache derrière un jeu, un site, une application, et bien d'autre pour en saisir une partie de la complexité. Ce projet nous a confronté à un autre univers, a agrandi notre culture en nous permettant, même pour ceux qui ne souhaite pas continuer dans ce domaine, de toucher l'informatique du bout des doigts. Nous nous sommes rendu compte que l'informatique est loin d'être simple et demande logique, rigueur, concentration et surtout de la passion. En effet pour pouvoir réussir à coder, chercher encore et encore des solutions, et continuer le temps que l'on ne la trouve pas, il faut être passionné par le sujet.
Nous nous sommes faites aider par un jeune étudiant en ingénierie informatique, qui nous a montré à quel point l'informatique est diversifié, il a essayé de nous expliquer cette diversité tout comme notre professeur.
Nous ressortons de cette expérience initiées à cette discipline et nous comprenons maintenant toute sa difficulté, ainsi que le travail obstiné qu'elle demande .Même si nous ne continuerons pas sur cette voie mais nous sommes heureuses d'avoir pu la découvrir.
Il n'y a pas que le projet qui nous apporté de l'expérience mais aussi le travail en équipe. Nous avions déjà travaillé en équipe lors de notre TPE.
Ici se fut plus simple car nous avions appris de nos erreurs. Nous avons pris le temps de nous voir pour travailler et suivre les explications que l’étudiant essayait de nous faire saisir. Ceci nous a pris beaucoup de temps car nous ne savions pas du tout ou nous allions. Mais le fait que l'on soit deux nous a aidé à ne pas baisser les bras. Le travail en équipe nous a permis de confronter nos points de vue et de les faire coïncider. Il fait prendre conscience des avis de chacun, pour atteindre un but commun.

 


 

 

CODE FINAL

CODE SOURCE mastermind.pde
// Need G4P library
import g4p_controls.*;
import java.awt.Font;
// Variables
int nbBallsByTurn; // Nombre de balles maximum par tour
int turnBallsCount; // Nombre de balles dans le tour actuel
int turnMax; // Nombre de tours maximum
int turnId; // Numéro du tour actuel
TurnInfos infos; // infos contenant le nombre de balles de bonne couleur bien/mal placées
boolean restart; // Permet de vérifier si le jeu doit recommencer
color[] colors; // Liste des couleurs possible
Combination combination; // Combinaison du joueur (liste de couleurs)
Combination combinationWin; // Combinaison gagnante (liste de couleurs)
/*
** Fonction renvoyant vrai si la combinaison du joueur est gagnante, faux sinon
*/
boolean isVictory() {
return (combination.equals(combinationWin));
}
public void setup(){
 
size(900, 900, JAVA2D);
background(backgroundColor);
createGUI();
customGUI();
// Règles
nbBallsByTurn = 4; // Nombre de balles a trouver
turnMax = 10; // Nombre de tours
colors = new color[]{blue, yellow, cyan, green, red, gold, violet, orange};
// Initialisation
// Balle
x = 50;
y = 150;
radius = 30;
// Jeu
turnId = 1;
turnBallsCount = 0;
infos = new TurnInfos();
restart = false;
combinationWin = new Combination(4);
combination = new Combination(4);
combinationWin.computeRandomCombination();
drawNewTurn(); // Affiche 4 premieres cases vides à remplir
}
 
public void draw(){
}
// Use this method to add additional statements
// to customise the GUI controls
public void customGUI(){
} ball.pde
// Couleurs
color blue = color(51,0,221);
color yellow = color(255,255,51);
color cyan = color(0,255,255);
color green = color(2,187,6);
color red = color(255,51,0);
color gold = color(239,216,7);
color violet = color(153,51,204);
color orange = color(255,153,51);
color backgroundColor = color(245, 242, 255);
// Propriétés
int x; // Position en x
int y; // Position en y
int radius; // Taille du rayon combination.pde
class Combination {
color[] combination; // Combinaison: liste de couleurs
Combination(int length) {
combination = new color[length];
}
 
color[] getCombination() {
return combination;
}
void setCombination(color[] combination) {
this.combination = combination;
}
/*
** Calcule une combinaison aléatoire
*/
void computeRandomCombination() {
for (int i = 0; i < combination.length; ++i) {
combination[i] = colors[(int) random(0, colors.length - 1)]; //Ajoute à l'ième élément de la combinaison la nième couleur de la liste de couleurs (n étant un entier aléatoire entre 0 et la taille de cette liste - 1)
}
}
/*
** Fonction de comparaison de le combinaison actuelle avec la combinaison c
*/
boolean equals(Combination c) {
for (int i = 0; i < nbBallsByTurn; ++i) {
if (combination[i] != c.getCombination()[i]) //Couleur différente
return false;
}
return true;
}
 
/*
** Affiche la combinaison (couleurs RGB)
*/
void print() {
for (int i = 0; i < combination.length; ++i)
println("Red:" + red(combination[i]) +" Green:" + green(combination[i]) + " Blue:" + blue(combination[i]));
}
} turn_infos.pde
class TurnInfos {
int nbGoodColors; // Nombre de balles de bonne couleur bien placées
int nbWrongColors; // Nombre de balles de bonne couleur mal placées
TurnInfos() {
nbGoodColors = 0;
nbWrongColors = 0;
}
int getNbGoodColors() {
return nbGoodColors;
}
int getNbWrongColors() {
return nbWrongColors;
}
/*
 
** Fonction indiquant si la combinaison contient la couleur c qui ne se situe pas à l'index i (bonne couleur mal placée)
*/
boolean isMisplaced(int index, color c) {
for (int i = 0; i < combinationWin.getCombination().length; ++i)
if (i != index && combinationWin.getCombination()[i] == c)
return true;
return false;
}
/*
** Fonction mettant à jour le nombre de bonnes couleurs bien/mal placées à la fin d'un tour
*/
void computeTurnInfos() {
nbGoodColors = 0;
nbWrongColors = 0;
for (int i = 0; i < combination.getCombination().length; ++i) {
if (combination.getCombination()[i] == combinationWin.getCombination()[i]) //Bonne couleur bien placée
++nbGoodColors;
else if (isMisplaced(i, combination.getCombination()[i])) //Bonne couleur mal placée
++nbWrongColors;
}
}
} gui.pde
void myBtnEvents(GButton button) { //_CODE_:button1:12356:
// It is safe to enter your event code here
} //_CODE_:button1:12356:
 
/*
** Dessine une balle de la couleur c
** Met à jour la position pour la balle suivante
** Met à jour la combinaison du joueur
*/
void drawBall(color c) {
fill(c);
ellipse(x,y,radius,radius);
x = x + 50;
combination.getCombination()[turnBallsCount++] = c;
}
/*
** Supprime la derniere balle placée
** Met à jour la position à la balle précedente
*/
void removeBall() {
x -= 50;
fill(backgroundColor); // On remplit avec la couleur du fond
ellipse(x,y,radius,radius);
--turnBallsCount;
}
/*
** Affiche 4 cercles vides, qui seront remplies par le joueur
*/
void drawNewTurn() {
noFill();
 
for (int i = 0; i < nbBallsByTurn; ++i)
ellipse(x + i*50, y, radius,radius);
}
/*
** Affiche le nombre de balles bien/mal placées
** Met à jour le numéro du tour et la position de la balle à la ligne suivante
** Remise à zero de la combinaison du joueur
*/
void endTurn() {
textSize(15);
fill(0);
text("Blanches: " + infos.getNbGoodColors() + ", Noires: " + infos.getNbWrongColors(), x, y + 7);
y=y+50;
x=50;
++turnId;
drawNewTurn();
// Remise à zéro
turnBallsCount = 0;
combination = new Combination(4);
}
public void buttonValidate_click1(GButton source, GEvent event) { //_CODE_:button1:967742:
if (restart) { // On a cliqué sur le bouton recommencer
setup(); // Remise à zéro du jeu
return;
 
}
if (turnBallsCount < nbBallsByTurn) // Empeche le joueur de valider tant que la combinaison n'est pas complete
return;
if (isVictory()) { // Cas d'un victoire du joueur
textSize(30);
fill(green);
text("Victoire !", 600, 450);
restart = true;
buttonValidate.setText("Recommencer");
return;
}
else if (turnId == turnMax) { // Cas d'une défaite du joueur
textSize(30);
fill(red);
text("Défaite !", 600, 450);
restart = true;
buttonValidate.setText("Recommencer");
return;
}
// On calcule le nombre de bien/mal placées
infos.computeTurnInfos();
// Mises à jour à la fin du tour
endTurn();
} //_CODE_:button1:967742:
 
public void buttonRemove_click1(GButton source, GEvent event) { //_CODE_:button2:587044:
removeBall();
} //_CODE_:button2:587044:
public void buttonBlue_click1(GButton source, GEvent event) { //_CODE_:button2:587044:
if (turnBallsCount < nbBallsByTurn)
drawBall(blue);
} //_CODE_:button2:587044:
public void buttonYellow_click1(GButton source, GEvent event) { //_CODE_:button3:311723:
if (turnBallsCount < nbBallsByTurn)
drawBall(yellow);
} //_CODE_:button3:311723:
public void buttonCyan_click1(GButton source, GEvent event) { //_CODE_:button4:779461:
if (turnBallsCount < nbBallsByTurn)
drawBall(cyan);
} //_CODE_:button4:779461:
public void buttonGreen_click1(GButton source, GEvent event) { //_CODE_:button5:398508:
if (turnBallsCount < nbBallsByTurn)
drawBall(green);
} //_CODE_:button5:398508:
public void buttonRed_click1(GButton source, GEvent event) { //_CODE_:button6:356184:
if (turnBallsCount < nbBallsByTurn)
drawBall(red);
 
} //_CODE_:button6:356184:
public void buttonGold_click1(GButton source, GEvent event) { //_CODE_:button7:272583:
if (turnBallsCount < nbBallsByTurn)
drawBall(gold);
} //_CODE_:button7:272583:
public void buttonViolet_click1(GButton source, GEvent event) { //_CODE_:button8:445442:
if (turnBallsCount < nbBallsByTurn)
drawBall(violet);
} //_CODE_:button8:445442:
public void buttonOrange_click1(GButton source, GEvent event) { //_CODE_:button9:781116:
if (turnBallsCount < nbBallsByTurn)
drawBall(orange);
} //_CODE_:button9:781116:
// Create all the GUI controls.
// autogenerated do not edit
public void createGUI(){
G4P.messagesEnabled(false);
G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
G4P.setCursor(ARROW);
if(frame != null)
frame.setTitle("Sketch Window");
 
buttonValidate = new GButton(this, 480, 800, 140, 60);
buttonValidate.setText("Valider");
buttonValidate.setTextItalic();
buttonValidate.setLocalColorScheme(GCScheme.PURPLE_SCHEME);
buttonValidate.addEventHandler(this, "buttonValidate_click1");
buttonRemove = new GButton(this, 640, 800, 70, 60);
buttonRemove.setText("Supprimer");
buttonRemove.setTextItalic();
buttonRemove.setLocalColorScheme(GCScheme.RED_SCHEME);
buttonRemove.addEventHandler(this, "buttonRemove_click1");
title = new GLabel(this, 260, 0, 340, 80);
title.setFont(new Font("Mickey", Font.PLAIN, 24));
title.setText("Mastermind");
title.setOpaque(false);
infosBW = new GLabel(this, 580, 650, 200, 80);
infosBW.setText("Blanche: bonne couleur bien placée\nNoire: bonne couleur mal placée");
infosBW.setTextAlign(GAlign.LEFT, GAlign.MIDDLE);
button2 = new GButton(this, 16, 745, 28, 25);
button2.setText("bleu");
button2.addEventHandler(this, "buttonBlue_click1");
button3 = new GButton(this, 58, 744, 28, 25);
button3.setText("jaune");
button3.setLocalColorScheme(GCScheme.YELLOW_SCHEME);
button3.addEventHandler(this, "buttonYellow_click1");
 
button4 = new GButton(this, 102, 744, 28, 25);
button4.setText("cyan");
button4.setLocalColorScheme(GCScheme.CYAN_SCHEME);
button4.addEventHandler(this, "buttonCyan_click1");
button5 = new GButton(this, 144, 745, 28, 25);
button5.setText("vert");
button5.setLocalColorScheme(GCScheme.GREEN_SCHEME);
button5.addEventHandler(this, "buttonGreen_click1");
button6 = new GButton(this, 59, 783, 28, 25);
button6.setText("or");
button6.setLocalColorScheme(GCScheme.GOLD_SCHEME);
button6.addEventHandler(this, "buttonGold_click1");
button7 = new GButton(this, 15, 783, 28, 25);
button7.setText("rouge");
button7.setLocalColorScheme(GCScheme.RED_SCHEME);
button7.addEventHandler(this, "buttonRed_click1");
button8 = new GButton(this, 101, 784, 28, 25);
button8.setText("violet");
button8.setLocalColorScheme(GCScheme.PURPLE_SCHEME);
button8.addEventHandler(this, "buttonViolet_click1");
button9 = new GButton(this, 142, 784, 28, 25);
button9.setText("orange");
button9.setLocalColorScheme(GCScheme.ORANGE_SCHEME);
button9.addEventHandler(this, "buttonOrange_click1");
}
// Variable declarations
// autogenerated do not edit
GButton buttonValidate;
 
GButton buttonRemove;
GLabel title;
GLabel infosBW;
GButton button2;
GButton button3;
GButton button4;
GButton button5;
GButton button6;
GButton button7;
GButton button8;
GButton button9;

Contact

Mastermind-VincianeLilia vincianelilia@gmail.com