var opponent = [];
var self = [];
var opponent_offset = [];
var self_offset = [];
var thresh = [5, 10, 20, 100, 1000];

var maxthresh = thresh[thresh.length - 1];

function update_offset(offset, hist, m) {
  if (hist.length > offset.length && offset.length < m[m.length - 1]) {
    offset.push(0);
  }
  var lastidx = hist.length - 2;
  var last = hist[lastidx + 1];
  var prediction = 0;
  var best = -1;
  var result = [];
  var j = 0;
  for (var k = 0; k < m.length; ++k) {
    var limit = Math.min(m[k], lastidx + 1);
    for (; j < limit; ++j) {
      offset[j] = (hist[lastidx - j] == last) ? offset[j] + 1 : 0;
      if (offset[j] > best) {
        best = offset[j];
        prediction = hist[lastidx - j + 1];
      }
    }
    result.push(prediction);
  }
  return result;
}

var scores = [];
var last_pred = [];

function pick_best(pred) {
  if (opponent.length > 0) {
    while (scores.length < 3 * last_pred.length) { scores.push(0); }
    var opp = opponent[opponent.length - 1];
    for (var k = 0; k < last_pred.length; ++k) {
      var offset = (3 + opp - last_pred[k]) % 3;
      scores[offset + 3 * k] += 1;
    }
  }
  last_pred = pred;
  var best = -1;
  var choice = 0;
  for (var k = 0; k < scores.length; ++k) {
    if (scores[k] > best) {
      best = scores[k];
      choice = k;
    }
  }
  log(scores.join(','));
  return (pred[Math.floor(choice / 3)] + choice) % 3;
}

function play() {
  pred = [Math.floor(Math.random() * 3)];
  pred.push(opponent[Math.floor(Math.random() * opponent.length)]);
  pred.push(self[Math.floor(Math.random() * opponent.length)]);
  pred = pred.concat(update_offset(self_offset, self, thresh));
  pred = pred.concat(update_offset(opponent_offset, opponent, thresh));
  var move = (1 + pick_best(pred)) % 3;
  return move;
}

