JS代码在codepen上运行缓慢,尽管它在本地运行良好 [英] JS code runs slow on codepen, though it runs good locally

查看:453
本文介绍了JS代码在codepen上运行缓慢,尽管它在本地运行良好的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为无与伦比的tic toc toe游戏实现了minimax算法。
minimax算法是递归的,执行大的迭代,这对于计算机来说并不大,对人类来说只是很大。
第一步在codepen上执行大约需要3秒钟,但在本地计算机上立即执行。
怎么了?我的代码效率不高?或者它在codepen上有问题吗?
如何使它在codepen上高效?
这是我的JS代码:

  var player; 
var opponent;
var myMove = false;

var board = [
[null,null,null],
[null,null,null],
[null,null,null]
];

//显示模态
$('。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();
});

函数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];
//检查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){
返回值? 1:0;
}
}
if(diagonalComplete1 || diagonalComplete2){
返回值? 1:0;
}
}
if(allNotNull){
返回-1;
}
返回null;
}


函数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();
}




函数updateMove(){
updateSymbol();
var winner = checkWin(board);
if(winner === 1){
$('h3')。css(display,block)。append(opponent +won !!)。addClass(animated无限脉冲);
markWin();
setTimeout(resetGame,2000);
}否则if(胜利者=== 0){
$('h3')。css(display,block)。append(player +'won !!')。addClass( 动画无限脉冲);
markWin();
setTimeout(resetGame,2000);
}否则if(胜利者=== -1){
$('h3')。css(display,block)。append(这是一个抽奖!!)。addClass (动画无限脉冲);
markWin();
setTimeout(resetGame,2000);
}
}


函数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);
}否则if(board [i] [j] === true&& $(#+b+ i ++ j).is(':empty')){
$(#+b+ i ++ j)。text(对手);
}
}
}
}

函数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)')。长度> 0&& $('。'+'b'+ arr [i] [1] +':包含(O)')。长度> 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;
}
} //检查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)')。长度> 0&& $('。'+'b'+ arr [j] [2] +':包含(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;
}
} //检查X win
返回false;
}

// [0,0] [0,1] [0,2]
// [1,0] [1,1] [1,2 ]
// [2,0] [2,1] [2,2]

函数minimax(board,player){
nodes ++;
var winner = checkWin(board);
if(winner!== null){
switch(winner){
case 1:
// AI赢
return [1,board];
case 0:
//对手赢
返回[-1,board];
case -1:
// Tie
return [0,board];
}
} else {
//下一个状态
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;
}
}
}
返回[nextVal,nextBoard];
}
}

函数minimaxMove(board){
nodes = 0;
返回minimax(board,true)[1];
}

函数makeMove(){
board = minimaxMove(board);
console.log(节点);
myMove = false;
if(nodes!== 1){
updateMove();
}
}

这是我的代码的codepen链接:


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/

解决方案

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.

这篇关于JS代码在codepen上运行缓慢,尽管它在本地运行良好的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆