2017-08-23 2 views
0

Je travaille sur le jeu Tic Tac Toe, en utilisant JavaScrip. Lorsque j'appelle la fonction MinMax, j'obtiens une séquence d'erreur de journal. Ici j'appelle la fonction minmax et les valeurs que j'ai assignées sont correctes selon mes connaissances.Erreur de console de retour de l'algorithme JavaScript Minmax Uncaught TypeError: Impossible de lire la propriété 'cost' de undefined

const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN));

Je reçois une erreur dans la console

main.js:86 Uncaught TypeError: Cannot read property 'cost' of undefined 
    at minmax (main.js:86) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at minmax (main.js:64) 
    at computerMove (main.js:120) 

Si vous voulez avoir regard sur mon funtion complet est le code ici.

function minmax(newGrid, depth, player) { 
     const gameState= gameOver(newGrid); 
     if(gameState === false) { 
     const values= []; 
      for (var i=0; i<3; i++) { 
       for (var j = 0; j<3;j++){ 
       const gridCopy = _.cloneDeep(newGrid); 
       if (gridCopy[i][j]!=='') continue; 
       gridCopy[i][j]=player; 
       const value = minmax(gridCopy, depth+1, ((player===PLAYER_TOKEN)?COMPUTER_TOKEN:PLAYER_TOKEN)); 
       values.push({ 
        cost:value, 
       cell: { 
        i:i, 
        j:j 
       } 
       }); 
       } 
      } 
      if (player === COMPUTER_TOKEN) { 
       const max = _.maxBy(values, (v) => { 
       return v.cost; 
       }); 
       if (depth === 0) { 
       return max.cell; 
       } 
       else { 
       return max.cost; 
       } 
      } 
      else { 
       const min = _.minBy(values, (v) => { 
       return v.cost; 
       }); 
       if (depth === 0) { 
       return min.cell; 
       } 
       else { 
       return min.cost; 
       } 

      } 

     }else if (gameState === null){ 
     return 0; 
     } 
     else if (gameState===PLAYER_TOKEN) { 
     return depth - 10; 
     } 
     else if (gameState===COMPUTER_TOKEN) { 
     return 10 - depth; 
     } 
    } 
    function computerMove(){ 
     return minmax(grid,0,COMPUTER_TOKEN); 
    } 

Voici le lien pour compléter le projet

https://codepen.io/ziaullahzia/full/wqpGxW/

Répondre

1

Je pense que mal ici est votre fonction récursive. Vous appelez minmax neuf fois et quand depth atteint finalement 8 il devrait résoudre sa valeur mais il ne peut pas parce que la valeur est calculée du tableau values qui ne serait jamais rempli. Et les résultats avec l'appel .min/ .max méthodes avec vide values tableau. L'appel interne le plus récursif devrait résoudre sa valeur de retour à partir d'une constante ou de quelque chose d'autre mais pas avec une variable (values) qui dépend de la fonction récursive elle-même. Donc, à mon avis, la moitié inférieure de minmax devrait ressembler à quelque chose comme ça. Mais je ne connais pas votre coût? algorithme donc juste renvoyer 1 comme résultat.

   if (player === COMPUTER_TOKEN) { 
        const max = _.maxBy(values, (v) => { 
         return v.cost; 
        }); 
        if (depth === 8) { 
         return 1; 
        } else { 
         return max.cost; 
        } 
       } else { 
        const min = _.minBy(values, (v) => { 
         return v.cost; 
        }); 
        if (depth === 8) { 
         return 1; 
        } else { 
         return min.cost; 
        } 

       } 

Mais voici un autre problème. minmax La fonction renvoie une valeur entière et let value = minmax(gridCopy, depth + 1, ((player === PLAYER_TOKEN) ? COMPUTER_TOKEN : PLAYER_TOKEN)); attend une valeur entière correcte, mais const move = computerMove(); attend un objet position mais obtient un nombre entier.

EDIT

Désolé pour la réponse tardive. J'ai regardé à nouveau le code et j'avais tort.

Vous simulez le gameover pour chaque itération en minmax avec const gameState = gameOver();. Mais la fonction gameOver utilise la variable globale grid qui est l'état réel du jeu. Donc je l'ai changé avec const gameState = gameOver(newGrid);. Et sur la boîte cliquez sur le bouton a changé let gameState = gameOver(); à let gameState = gameOver(grid); Fait d'autres changements pour le redémarrage du jeu et ne permettant pas de changer la cellule de la grille si le jeu est terminé ou la cellule de la grille n'est pas vide.

Code modifié here

+0

Bonjour, Merci pour votre réponse ................ J'utilise funtion computerMove() pour appeler minmax funtion. . si vous vérifiez le code dans codepne ... ressemble à ça ..................................... ............................. fonction computerMove() { return minmax (grille, 0, COMPUTER_TOKEN); } – ziaullahzia

+0

Ajout d'une modification pour la réponse. – alperenc

+0

Oui, merci, ça marche. Je vais vérifier les détails pour en savoir plus. – ziaullahzia