JS code runs slow on codepen, though it runs good locally

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

I have implemented minimax algorithm for an unbeatable tic toc toe game. The minimax algorithm is recursive, performing big iterations, which are not big for the computer, only big for humans. The very first step takes about 3 seconds to perform on codepen, but performs instantly on my computer locally. what's wrong? is my code not efficient? or it's a problem on codepen? How do it make it efficient on codepen? Here's my JS code:

var player; var opponent; var myMove = false;  var board = [   [null, null, null],   [null, null, null],   [null, null, null] ];  //displays modal $('.play').click(function() {   $('.modal').css("display", "block"); });  $('.O').click(function() {   $('.modal').css("display", "none");   player = 'O';   opponent = 'X';   resetGame();   updateSymbol();   main(); });  $('.X').click(function() {   $('.modal').css("display", "none");   player = 'X';   opponent = 'O';   resetGame();   updateSymbol();   main(); });  function main() {   $(".col-xs-4").click(function() {     if ($(this).is(':empty')) {        var cell = $(this).attr("id");       var row = parseInt(cell[1]);       var col = parseInt(cell[2]);       if (!myMove) {         board[row][col] = false;         myMove = true;         updateMove();         makeMove();       }     }   }); }  function checkWin(board) {    vals = [true, false];   var allNotNull = true;   for (var k = 0; k < vals.length; k++) {     var value = vals[k];     // Check rows, columns, and diagonals for win     var diagonalComplete1 = true;     var diagonalComplete2 = true;     for (var i = 0; i < 3; i++) {       if (board[i][i] != value) {         diagonalComplete1 = false;       }       if (board[2 - i][i] != value) {         diagonalComplete2 = false;       }       var rowComplete = true;       var colComplete = true;       for (var j = 0; j < 3; j++) {         if (board[i][j] != value) {           rowComplete = false;         }         if (board[j][i] != value) {           colComplete = false;         }         if (board[i][j] === null) {           allNotNull = false;         }       }       if (rowComplete || colComplete) {         return value ? 1 : 0;       }     }     if (diagonalComplete1 || diagonalComplete2) {       return value ? 1 : 0;     }   }   if (allNotNull) {     return -1;   }   return null; }   function resetGame() {   board = [     [null, null, null],     [null, null, null],     [null, null, null]   ];   myMove = false;   for (var i = 0; i < 3; i++) {     for (var j = 0; j < 3; j++) {       $("#" + "b" + i + "" + j).text("").css("background", "#222");     }   }   $('h3').css("display", "none").text(""); }     function updateMove() {   updateSymbol();   var winner = checkWin(board);   if (winner === 1) {     $('h3').css("display", "block").append(opponent + " won!!").addClass("animated infinite pulse");     markWin();     setTimeout(resetGame, 2000);   } else if (winner === 0) {     $('h3').css("display", "block").append(player + ' won!!').addClass("animated infinite pulse");     markWin();     setTimeout(resetGame, 2000);   } else if (winner === -1) {     $('h3').css("display", "block").append("It's a Draw!!").addClass("animated infinite pulse");     markWin();     setTimeout(resetGame, 2000);   } }   function updateSymbol() {   for (var i = 0; i < 3; i++) {     for (var j = 0; j < 3; j++) {       if (board[i][j] === false && $("#" + "b" + i + "" + j).is(':empty')) {         $("#" + "b" + i + "" + j).text(player);       } else if (board[i][j] === true && $("#" + "b" + i + "" + j).is(':empty')) {         $("#" + "b" + i + "" + j).text(opponent);       }     }   } }  function markWin() {   var arr = [     [1, 2, 3],     [4, 5, 6],     [7, 8, 9],     [1, 4, 7],     [2, 5, 8],     [3, 6, 9],     [1, 5, 9],     [3, 5, 7]   ];   for (var i = 0; i < arr.length; i++) {     if ($('.' + 'b' + arr[i][0] + ':contains("O")').length > 0 && $('.' + 'b' + arr[i][1] + ':contains("O")').length > 0 && $('.' + 'b' + arr[i][2] + ':contains("O")').length > 0) {       $('.' + 'b' + arr[i][0]).css("background", "green");       $('.' + 'b' + arr[i][1]).css("background", "green");       $('.' + 'b' + arr[i][2]).css("background", "green");       i = arr.length;     }   } //checks O win   for (var j = 0; j < arr.length; j++) {     if ($('.' + 'b' + arr[j][0] + ':contains("X")').length > 0 && $('.' + 'b' + arr[j][1] + ':contains("X")').length > 0 && $('.' + 'b' + arr[j][2] + ':contains("X")').length > 0) {       $('.' + 'b' + arr[j][0]).css("background", "green");       $('.' + 'b' + arr[j][1]).css("background", "green");       $('.' + 'b' + arr[j][2]).css("background", "green");       j = arr.length;     }   } //checks X win   return false; }  //[0,0] [0,1] [0,2] //[1,0] [1,1] [1,2] //[2,0] [2,1] [2,2]  function minimax(board, player) {   nodes++;   var winner = checkWin(board);   if (winner !== null) {     switch (winner) {       case 1:         // AI wins         return [1, board];       case 0:         // opponent wins         return [-1, board];       case -1:         // Tie         return [0, board];     }   } else {     // Next states     var nextVal = null;     var nextBoard = null;      for (var i = 0; i < 3; i++) {       for (var j = 0; j < 3; j++) {         if (board[i][j] === null) {           board[i][j] = player;           var value = minimax(board, !player)[0];           if ((player && (nextVal === null || value > nextVal)) || (!player && (nextVal === null || value < nextVal))) {             nextBoard = board.map(function(arr) {               return arr.slice();             });             nextVal = value;           }           board[i][j] = null;         }       }     }     return [nextVal, nextBoard];   } }  function minimaxMove(board) {   nodes = 0;   return minimax(board, true)[1]; }  function makeMove() {   board = minimaxMove(board);   console.log(nodes);   myMove = false;   if (nodes !== 1) {     updateMove();   } } 

Here's the codepen link of my code: http://codepen.io/makkBit/pen/JXgdEo/

回答1:

Use a profiler to pinpoint where the code is slow.

Here's the profiler result using Google Chrome.

The problem seems to start from the function minimaxMove.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!