<commit_before>ai = {
  boardCopy: {},
  INFINITY: 1000000000000,
  nodeCount: 0,
  limit: this.INFINITY,

  updateAIBoard : function(b) {
    var sam = new Array(b.getBoard().length);
    var ba = b.getBoard();
    for ( var i = 0; i < sam.length; i++ )
      sam[i] = ba[i].slice();

    this.boardCopy = new Board(b.getDimension(),
      b.getMoveStack().slice(),
      sam,
      b.getCurrentPlayer().toString() === "Player 1" ? 0 : 1);

    ai.nodeCount = 0;
  },

  getMove : function(b, heuristicChoice, limit) {
    this.limit = undefined;
    this.limit = limit;
    //console.log("Limiting Search By : " + this.limit);
    this.updateAIBoard(b);
    var heuristic = heuristicChoice === 1 ?
      this.maxScoreHeuristic :
      this.coinParityHeuristic;
    return {move: this.minmax(heuristic), nodes: ai.nodeCount};
  },

  maxScoreHeuristic : function(min, max) {
    return max.score;
  },

  coinParityHeuristic : function(min, max) {
    var game = ai.boardCopy;
    var board = game.getBoard();

    var maxCoin = 0,
        minCoin = 0;

    for ( var row = 0; row < game.getDimension(); row++ )
    {
      for ( var col = 0; col < game.getDimension(); col++ )
      {
        if ( board[row][col].toString() !== game.NONE.toString() )
        {
          board[row][col].toString() === max.toString() ?
            ++maxCoin :
            ++minCoin
        }
      }
    }

    return 100 * ( maxCoin - minCoin ) / (maxCoin + minCoin );
  },

  maximize : function(game, move, alpha, beta, heuristic) {
    game.play(move, game.getMoveStack(), game.getBoard());

    if (game.isGameOver(game.getBoard(), false))
    {
      var player = game.getCurrentPlayer();
      return heuristic(player.other, player);
    }

    this.getMoves(game,
      game.getCurrentPlayer()).forEach( function(move, index, moves) {
        if( ai.nodeCount < ai.limit )
        {
          ai.nodeCount++;
          alpha = Math.max(alpha, ai.minimize(game,
            move,
            alpha,
            beta,
            heuristic));
          if ( alpha >= beta ) return alpha;
        }
    });

    return alpha;
  },

  minimize : function(game, move, alpha, beta, heuristic) {
    game.play(move, game.getMoveStack(), game.getBoard());

    if (game.isGameOver(game.getBoard(), false))
    {
      var player = game.getCurrentPlayer();
      return heuristic(player.other, player);
    }

    this.getMoves(game,
      game.getCurrentPlayer()).forEach( function(move, index, moves) {
        if( ai.nodeCount < ai.limit )
        {
          ai.nodeCount++;
          beta = Math.min(beta, ai.maximize(game,
            move,
            alpha,
            beta,
            heuristic));
          if ( beta <= alpha ) return beta;
        }
    });

    return beta;
  },

  minmax : function(heuristic) {
    var max = this.boardCopy.getCurrentPlayer();

    if (this.limit === undefined)
      this.limit = this.INFINITY;

    if (this.limit < 1)
      this.limit = 1;<commit_msg>Fix bug for search limit == NaN<commit_after>ai = {
  boardCopy: {},
  INFINITY: 1000000000000,
  nodeCount: 0,
  limit: this.INFINITY,

  updateAIBoard : function(b) {
    var sam = new Array(b.getBoard().length);
    var ba = b.getBoard();
    for ( var i = 0; i < sam.length; i++ )
      sam[i] = ba[i].slice();

    this.boardCopy = new Board(b.getDimension(),
      b.getMoveStack().slice(),
      sam,
      b.getCurrentPlayer().toString() === "Player 1" ? 0 : 1);

    ai.nodeCount = 0;
  },

  getMove : function(b, heuristicChoice, limit) {
    this.limit = undefined;
    this.limit = limit;
    //console.log("Limiting Search By : " + this.limit);
    this.updateAIBoard(b);
    var heuristic = heuristicChoice === 1 ?
      this.maxScoreHeuristic :
      this.coinParityHeuristic;
    return {move: this.minmax(heuristic), nodes: ai.nodeCount};
  },

  maxScoreHeuristic : function(min, max) {
    return max.score;
  },

  coinParityHeuristic : function(min, max) {
    var game = ai.boardCopy;
    var board = game.getBoard();

    var maxCoin = 0,
        minCoin = 0;

    for ( var row = 0; row < game.getDimension(); row++ )
    {
      for ( var col = 0; col < game.getDimension(); col++ )
      {
        if ( board[row][col].toString() !== game.NONE.toString() )
        {
          board[row][col].toString() === max.toString() ?
            ++maxCoin :
            ++minCoin
        }
      }
    }

    return 100 * ( maxCoin - minCoin ) / (maxCoin + minCoin );
  },

  maximize : function(game, move, alpha, beta, heuristic) {
    game.play(move, game.getMoveStack(), game.getBoard());

    if (game.isGameOver(game.getBoard(), false))
    {
      var player = game.getCurrentPlayer();
      return heuristic(player.other, player);
    }

    this.getMoves(game,
      game.getCurrentPlayer()).forEach( function(move, index, moves) {
        if( ai.nodeCount < ai.limit )
        {
          ai.nodeCount++;
          alpha = Math.max(alpha, ai.minimize(game,
            move,
            alpha,
            beta,
            heuristic));
          if ( alpha >= beta ) return alpha;
        }
    });

    return alpha;
  },

  minimize : function(game, move, alpha, beta, heuristic) {
    game.play(move, game.getMoveStack(), game.getBoard());

    if (game.isGameOver(game.getBoard(), false))
    {
      var player = game.getCurrentPlayer();
      return heuristic(player.other, player);
    }

    this.getMoves(game,
      game.getCurrentPlayer()).forEach( function(move, index, moves) {
        if( ai.nodeCount < ai.limit )
        {
          ai.nodeCount++;
          beta = Math.min(beta, ai.maximize(game,
            move,
            alpha,
            beta,
            heuristic));
          if ( beta <= alpha ) return beta;
        }
    });

    return beta;
  },

  minmax : function(heuristic) {
    var max = this.boardCopy.getCurrentPlayer();

    if (this.limit === undefined || isNaN(this.limit))
      this.limit = this.INFINITY;

    if (this.limit < 1)
      this.limit = 1;
{'fraction_non_alphanumeric': 0.14774804719960113, 'fraction_numerical': 0.009639355160378926, 'mean_word_length': 2.140918580375783, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2160168', 'n_tokens_mistral': 2033, 'n_tokens_neox': 1912, 'n_words': 415}