<commit_before>'use strict';

var boxes = [
    [0,0,0],
    [0,0,0],
    [0,0,0]
  ], 
  value_X = -1,
  value_O = 1,
  value_Blank = 0,

  judgement_unknown = -2,
  judgement_draw = 0,
  judgement_win = 1,
  judgement_lose = -1;

$(document).on('click', 'box', function(e){
  var position = $(e.currentTarget).index();
  if (boxes[Math.floor(position/3)][position%3] === 0) {
    boxes[Math.floor(position/3)][position%3] = value_X;
    $(e.currentTarget).addClass('x');
    var myChoice = new State(boxes).placeO().placement;

    if (myChoice === -1) {
      alert('Draw!');
      location.reload();
    } else {
      boxes[Math.floor(myChoice/3)][myChoice%3] = value_O;
      $('box:nth('+myChoice+')').addClass('o');

      if (judge(boxes) !== judgement_unknown) {
        alert('I win!');
        location.reload();
      }
    }
  }
});

// A state Object to analyze the future possibilities.
function State(data) {
  this.data = [[0,0,0],[0,0,0],[0,0,0]];
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      this.data[i][j] = data[i][j];
    }
  }
  this.placement = -1;
  this.judgement = judgement_unknown;
}

State.prototype.placeO = function() {
  var result = new State(this.data);
  var cursor = new State(this.data);
  result.judgement = judge(this.data);

  if (result.judgement !== judgement_unknown) {
    return result;
  }
  
  for(var i = 0; i < 9; i++) {
    //copy data into cursor to start trying from this state
    for (var m = 0; m < 3; m++) {
      for (var k = 0; k < 3; k++) {
        cursor.data[m][k] = this.data[m][k];
      }
    }
    if (this.data[Math.floor(i/3)][i%3] === value_Blank) {
      //Place X at the first blank box to try.
      cursor.data[Math.floor(i/3)][i%3] = value_O;
      cursor = cursor.placeX();
      cursor.placement = i;

      // replace result if cursor is better, better for O player.
      if (isBetter(cursor.judgement, result.judgement)) {
        result = cursor;
      }
    }
  }
  return result;
};

State.prototype.placeX = function() {
  var result = new State(this.data);
  var cursor = new State(this.data);
  result.judgement = judge(this.data);
           
  if (result.judgement !== judgement_unknown) {
    return result;
  }
  
  //copy data into cursor to start trying from this state
  for (var i = 0; i < 9; i++) {
    for (var m = 0; m < 3; m++) {
      for (var k = 0; k < 3; k++) {
        cursor.data[m][k] = this.data[m][k];
      }
    }
    if (this.data[Math.floor(i/3)][i%3] === value_Blank) {
      cursor.data[Math.floor(i/3)][i%3] = value_X;
      cursor = cursor.placeO();
      cursor.placement = i;

      // replace result if cursor is worse, better for O player.
      if (isWorse(cursor.judgement, result.judgement)) {
        result = cursor;
      }
    }
  }
  return result;
}

function isBetter(new_judgement, old_judgement) {
  // new_judgement is not possibly better than win
  if (old_judgement === judgement_win) {
    return false;
  }
  if ( old_judgement === judgement_draw    && new_judgement === judgement_win
    || old_judgement === judgement_lose    && new_judgement !== judgement_lose
    || old_judgement === judgement_unknown && new_judgement !== judgement_unknown) {
    return true;
  }
  return false;
}

function isWorse(new_judgement, old_judgement) {
  // new_judgement is not possibly worse than lose
  if (old_judgement === judgement_lose) {
    return false;
  }
  if ( old_judgement === judgement_draw    && new_judgement === judgement_lose
    || old_judgement === judgement_win     && new_judgement !== judgement_win
    || old_judgement === judgement_unknown && new_judgement !== judgement_unknown) {
      return true;
  }
  return false;
}

function judge(data) {
  var blank = 0, //blank boxes
  row = [0,0,0], //summary of each row
  col = [0,0,0], //summary of each col
  diagonal = [0,0]  //summary of diagonal line
  ;

  // add up rows and cols to see if they are all 1 or -1;<commit_msg>Revert "Revert "merge placeO and planX as a unified place method.""<commit_after>'use strict';

var boxes = [
    [0,0,0],
    [0,0,0],
    [0,0,0]
  ], 
  value_X = -1,
  value_O = 1,
  value_Blank = 0,

  judgement_unknown = -2,
  judgement_draw = 0,
  judgement_win = 1,
  judgement_lose = -1;

$(document).on('click', 'box', function(e){
  var position = $(e.currentTarget).index();
  if (boxes[Math.floor(position/3)][position%3] === 0) {
    boxes[Math.floor(position/3)][position%3] = value_X;
    $(e.currentTarget).addClass('x');
    var myChoice = new State(boxes).place(value_O).placement;

    if (myChoice === -1) {
      alert('Draw!');
      location.reload();
    } else {
      boxes[Math.floor(myChoice/3)][myChoice%3] = value_O;
      $('box:nth('+myChoice+')').addClass('o');

      if (judge(boxes) !== judgement_unknown) {
        alert('I win!');
        location.reload();
      }
    }
  }
});

// A state Object to analyze the future possibilities.
function State(data) {
  this.data = [[0,0,0],[0,0,0],[0,0,0]];
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      this.data[i][j] = data[i][j];
    }
  }
  // next placement, will be 0-8 after calculation.
  this.placement = -1;
  // result of current state.
  this.judgement = judgement_unknown;
}

State.prototype.place = function(value) {
  var result = new State(this.data);
  var cursor = new State(this.data);
  result.judgement = judge(this.data);

  if (result.judgement !== judgement_unknown) {
    return result;
  }
  
  for(var i = 0; i < 9; i++) {
    //copy data into cursor to start trying from this state
    for (var m = 0; m < 3; m++) {
      for (var k = 0; k < 3; k++) {
        cursor.data[m][k] = this.data[m][k];
      }
    }
    if (this.data[Math.floor(i/3)][i%3] === value_Blank) {
      //Place value at the first blank box to try.
      cursor.data[Math.floor(i/3)][i%3] = value;
      cursor.placement = i;
      if (value === value_O) {
        cursor = cursor.place(value_X);
        // replace result if cursor is better, better for O player.
        if (isBetter(cursor.judgement, result.judgement)) {
          result = cursor;
        }
      } else {
        cursor = cursor.place(value_O);
        // replace result if cursor is worse, better for O player.
        if (isWorse(cursor.judgement, result.judgement)) {
          result = cursor;
        }
      }

    }
  }
  return result;
};

function isBetter(new_judgement, old_judgement) {
  // new_judgement is not possibly better than win
  if (old_judgement === judgement_win) {
    return false;
  }
  if ( old_judgement === judgement_draw    && new_judgement === judgement_win
    || old_judgement === judgement_lose    && new_judgement !== judgement_lose
    || old_judgement === judgement_unknown && new_judgement !== judgement_unknown) {
    return true;
  }
  return false;
}

function isWorse(new_judgement, old_judgement) {
  // new_judgement is not possibly worse than lose
  if (old_judgement === judgement_lose) {
    return false;
  }
  if ( old_judgement === judgement_draw    && new_judgement === judgement_lose
    || old_judgement === judgement_win     && new_judgement !== judgement_win
    || old_judgement === judgement_unknown && new_judgement !== judgement_unknown) {
    return true;
  }
  return false;
}

function judge(data) {
  var blank = 0, //blank boxes
  row = [0,0,0], //summary of each row
  col = [0,0,0], //summary of each col
  diagonal = [0,0]  //summary of diagonal line
  ;

  // add up rows and cols to see if they are all 1 or -1;
{'fraction_non_alphanumeric': 0.1582168995342648, 'fraction_numerical': 0.017298735861610112, 'mean_word_length': 2.7542457542457544, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '6128042', 'n_tokens_mistral': 2766, 'n_tokens_neox': 2603, 'n_words': 659}