Partage
  • Partager sur Facebook
  • Partager sur Twitter

Notez mon code | TIC-TAC-TOE

    15 octobre 2020 à 12:29:31

    Bonjour, j'aimerai voir vos avis pour se qui est de mon code TICTACTOE, alors je suis débutant et mes codes marchent très bien mais j'aimerai quand même savoir si je me gourre dans la syntaxe, structure ou si je pourrais faire plus simple à certains endroits 

    class game{  // s'occupe du jeu
    
          static case = document.querySelectorAll('.case'); // contient les cases du jeu ( 9 du coup ) 
    
          static test(){ // teste les conditions de victoires
               function win(){
               let who = 'X';
                
                for (var i = 0; i < 2; i++) { // on fait une boucle pour savoir si le joueur ou l'ia à rassembler une des conditions requises pour gagner la partie
                   if (game.case[0].firstElementChild.innerHTML == who && game.case[1].firstElementChild.innerHTML == who && game.case[2].firstElementChild.innerHTML == who ||
                       game.case[3].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[5].firstElementChild.innerHTML == who ||
                       game.case[6].firstElementChild.innerHTML == who && game.case[7].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ||
                       game.case[0].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ||
                       game.case[2].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[6].firstElementChild.innerHTML == who ||
                       game.case[0].firstElementChild.innerHTML == who && game.case[3].firstElementChild.innerHTML == who && game.case[6].firstElementChild.innerHTML == who ||
                       game.case[1].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[7].firstElementChild.innerHTML == who ||
                       game.case[2].firstElementChild.innerHTML == who && game.case[5].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ) {
                          switch(who){
                                 case 'X':
                                    pause.time = 1; // si who est égale à X sa veut dire que c'est l'ia qui à remplie une des conditions pour gagner
                                    console.log('L\'ia à gagner se round !'); 
                                 break;
    
                                 case 'O':
                                    pause.time = 1; // si non c'est le joueur 
                                    console.log('Ta gagner bravo !');
                                 break;
                          }
                   }
                   who = 'O'; // après avoir fini la première boucle on teste les conditions pour le joueur 
                }
            }
            function egality(){  // test la condition d'égalité 
              let indice = 0;
    
              for (var i = 0; i < game.case.length; i++) { // si aucune des cases n'est vide ( mais qu'il n'y as pas de victoire ) il y'a égalité
                 if (game.case[i].firstElementChild.innerHTML != '') {
                   indice++;
                 }
    
                 if (indice == 9) {
                     pause.time = 1;
                     console.log('Egalité !');
                 }
              }
             }
          
            let start = [win(),egality()]; // on lance les deux fonctions par une variable 
          }
    }
    
    class pause{ // gère les pauses entre chaque partie
    
         static time = 0;
    
         static interval(){
    
            if (this.time) { // si time est égale à un on lance le "chrono"
                 this.time++;
                 if (this.time > 500) { // au dessus de 500 on remet toute les cases à zero ainsi que time
                      for (var i = 0; i < game.case.length; i++) {
                       game.case[i].firstElementChild.innerHTML = '';
                    }
                   this.time = 0;
                 }
               }
       
          }
    
    }
    
    class ia{
    
          static round = 0;
    
          static event(){
            let indice = 0;
            let random = 0;
    
               if (this.round) { // si c'est le tour de l'ia
    
                   do{
                  random = Math.floor(Math.random(0) * Math.floor(9));
                  indice++;
    
                      if (indice == 9) {
                        break;
                      }
                }while(game.case[random].firstElementChild.innerHTML != ''); 
                    // si l'ia choisis une case vide ou si toute les cases sont choisis la boucle est fini 
                 if(indice != 9){game.case[random].firstElementChild.innerHTML = 'X';} // l'ia coche une case 
                 this.round = 0; // l'ia à fini son tour
               }
    
          }
    }
    
    class player{
    
           static event(e){ // le joueur choisis une case qui n'est pas encore cocher et si le jeu n'est pas en pause 
    
               for (var i = 0; i < game.case.length; i++) {
                  if (e.target == game.case[i] && game.case[i].firstElementChild.innerHTML == '' && !pause.time) {
                      game.case[i].firstElementChild.innerHTML = 'O';
                      ia.round = 1;
                  }
               }
    
           }
    
    }
    
    
    
    class motor{ // gère le jeu en fonction du temps et des interactions de l'utilisateur 
    
        static event(){
    
            document.addEventListener('click', function(e){
                player.event(e); // c'est le tour du joueur de l'ia ensuite on vérifie test si quelqu'un à gagner 
                ia.event();
                game.test();
            });
        }
    
        static interval(){ // pour se qui est de la pause 
    
             setInterval(function(){
                pause.interval();
             }, 1);
        }
    
        static start = [this.event(),this.interval()]; // on lance event est interval à partir de la propriété start
    }
    
    



    PS | pardon d'avance pour les fautes ...

    • Partager sur Facebook
    • Partager sur Twitter
      15 octobre 2020 à 13:54:43

      Salut,

      Je peux te suggérer cette condition :

      const c = 3;
      if(Array(c ** 2 - 1).fill().map((_, i) => i + 1).some(
          a => Array(c ** 2).fill().map((_, i) => i).slice(0, c ** 2 - a * (c - 1)).some(
              b => Array(c).fill().every((_, x) => 
                  game.case[a * x + b].firstElementChild.innerHTML == who
              )
          )
      )) { /* ... */ }

      A la place de :

      if(game.case[0].firstElementChild.innerHTML == who && game.case[1].firstElementChild.innerHTML == who && game.case[2].firstElementChild.innerHTML == who ||
      game.case[3].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[5].firstElementChild.innerHTML == who ||
      game.case[6].firstElementChild.innerHTML == who && game.case[7].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ||
      game.case[0].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ||
      game.case[2].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[6].firstElementChild.innerHTML == who ||
      game.case[0].firstElementChild.innerHTML == who && game.case[3].firstElementChild.innerHTML == who && game.case[6].firstElementChild.innerHTML == who ||
      game.case[1].firstElementChild.innerHTML == who && game.case[4].firstElementChild.innerHTML == who && game.case[7].firstElementChild.innerHTML == who ||
      game.case[2].firstElementChild.innerHTML == who && game.case[5].firstElementChild.innerHTML == who && game.case[8].firstElementChild.innerHTML == who ) { /* ... */

      pour éliminer la redondance.

      Mais en vérité, c'est pas forcément plus simple à comprendre je suppose. Je comprendrais que tu préfère utiliser la tienne d'autant qu'elle est sans doute plus efficace en terme de performance.

      L'avantage, c'est que si ton quadrillage passe de 3x3 à 4x4, 5x5..., tu peux adapter le code en modifiant 'c'.

      Je ne me suis pas trop pencher sur le reste, rien d'autre ne m'a particulièrement interpeler à première vue.

      -
      Edité par BrainError 15 octobre 2020 à 15:49:24

      • Partager sur Facebook
      • Partager sur Twitter
        15 octobre 2020 à 16:02:48

        Salut, enfaîte c'est pas que j'préfère mon algo pour tester les conditions de victoires, c'est juste que j'comprend pas du tout la tienne x)

        ah c'est vraiment trop haut level pour moi, j'aimerai bien comprendre comment sa marche oui mais effectivement sa à l'air plus polyvalent si on change le quadrillage vue que tout se que je comprend c'est qu'il y'a des formules .

        • Partager sur Facebook
        • Partager sur Twitter
          15 octobre 2020 à 18:51:39

          Quelques explications :

          Tu as besoin dans ton jeu de repérer une ligne (ou droite) complètes détenus par un joueur au moment de sa victoire.

          L'équation d'une droite : y = ax +b

          Avec une grille de 3x3 cases (assimilable à un repère), tu as besoin que 3 points soit situé sur la même droite pour déclarer une victoire.

          Donc je commence par créé un array de dimensions 3 (via la valeur contenu dans 'c') avec 'Array(c)' et je le remplis avec 'fill()'. Peu importe les valeurs contenu dans cette array, Il va juste servir à obtenir une séquence d'index {0; 1; 2;... c-1} qui correspond aux valeurs que peut prendre 'x'.

          Avec les 'c-1' points, il faut désormais vérifiée que pour une valeur de 'a' donnée et une valeur de 'b' donnée, tout les 'x' obtenus sont sur la même droite : autrement dit, il faut vérifier ça :

          game.case[a * x + b].firstElementChild.innerHTML == who

          Pour vérifier que cette condition est rempli par tout les 'x', on utilise la méthode 'every' des array. Ça donne donc pour le moment :

          Array(c).fill().every((_, x) =>

             game.case[a * x + b].firstElementChild.innerHTML == who

          )

          Ensuite, on a besoin de tester plusieurs valeur de 'a' et de 'b' pour notre équation, mais attention, en gardant en tête que la valeur maximale que peux prendre 'y' (le résultat de l'équation) correspond au nombre d'entrées dans ton array 'game.case', c'est à dire pour une grille 3x3, ben 3x3 ou autrement écrit 3^2 d'où l'usage par la suite de 'c ** 2' ('c' à la puissance 2).

          On commence par 'a' : on sait que techniquement, avec un array si 'a' vaut 0, on va avoir un problème parceque 'ax + b' sera égal à 'b' et que pour nos trois valeurs de 'x' (ou plus), on va avoir un index qui sera tout le temps identique, alors qu'à minima il faut que l'index varie au moins de 1 par valeur de 'x'. (Si non, on va être amené à contrôler 'game.case[b]' 3 fois de suite ce qui n'a aucun intérêt). On créé donc un array contenant 'c ** 2 - 1' valeurs, on le remplis avec 'fill()', on utilise 'map' pour définir les valeurs (on y est obligé cette fois car 'a' ne doit donc pas valoir '0', or le première index d'un array est '0') et on utilise 'some' pour vérifier si pour au moins une valeur de 'a' on arrive à trouver une droite détenus par un des deux joueurs.

          On procède à nouveau de la même façon pour 'b', en créant un array de dimensions 'c ** 2' (parce que cette fois 'b' à le droit de valoir 0), on le remplis avec 'fill' puis on définit ses valeurs avec 'map' (étape inutile au passage car 'b' à le droit d'être égal à 0), et enfin, on se pose et on réfléchit deux secondes :

          Notre array 'game.case' contient 'c ** 2' entrées (ou 3x3 = 9), donc 'ax + b' ne peux pas être supérieur à l'index max de cette array (càd 'c ** 2 -1' ou 8). En math, ça s'écrit 'ax + b < c ** 2 - 1'. Donc pour la valeur de 'a' pour l'itération actuelle et sachant que la valeur maximale de 'x' sera 'c-1', on peut écrire 'a * (c - 1) + b < c ** 2 - 1'. Quelque termes déplacer plus tard et on obtient donc que 'b' doit être limitée ainsi : 'b < c ** 2 - 1 - a * (c - 1)'.

          On utilise donc 'slice(0, c ** 2 - 1 - a * (c - 1))' pour couper notre array contenant les valeurs possibles de 'b' et ne pas dépasser la limite d'index à 'c ** 2 - 1' (ou 8 dans ce cas) de l'array 'game.case'.

          Puis une fois encore, on vérifie pour toutes les valeurs de 'b' si au moins une d'entre elle permet d'obtenir une droite grâce à 'some'.

          Ce qui donne le code que je t'ai montré.

          J'espère être au moins à moitié clair 😅.

          Désolé, je réponds depuis mon téléphone, je n'ai pas accès aux balises de code.

          PS : 'some' et 'every' renvoient 'true' ou 'false'.

          • Partager sur Facebook
          • Partager sur Twitter

          Notez mon code | TIC-TAC-TOE

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown