<commit_before>var crypto = require('crypto');

/**
 * Current version supports only two colours of checkers and two players as
 * the author is not yet aware of rules with three or more types of checkers
 * and/or players.
 * @readonly
 * @enum {number}
 */
var PieceType = {
  /** White piece */
  WHITE : 0,
  /** Black piece */
  BLACK : 1
};

/**
 * Denotes direction of piece movement relative to initial position.
 * @readonly
 * @enum {number}
 */
var Direction = {
  /** LEFT: from initial position to left (then to right on opposite side of board) */
  LEFT : 0,
  /** RIGHT: from initial position to right (then to left on opposite side of board) */
  RIGHT : 1
};

/**
 * Random generator.
 * @constructor
 */
function Random() {

}

/**
 * Get random number from 1 to 6
 * @returns {number} - Random value from 1 to 6
 */
Random.get = function() {
  // TODO: replace with quality random generator
  
  // Combine Math random generator with crypto one
  var buffer = crypto.randomBytes(1);
  var value = buffer.readUInt8(0);
  console.log(value);
  if (value > 255) {
    value = 255;
  }
  var k = value / 256;
  
  return (Math.floor(k * 6) + 1);
};

/**
 * Pieces are round checkers that are being moved around the board.
 * @constructor
 * @param {PieceType} type - Type of piece
 * @param {number} id - ID of piece
 */
function Piece(type, id) {
  /**
   * Type of piece (white/black)
   * @type {PieceType}
   */
  this.type = type;

  /**
   * ID of piece
   * @type {number}
   */
  this.id = id;
}

/**
 * Dice with basic functionality to roll using good random generator.
 * @constructor
 */
function Dice() {
  /**
   * Values of the two dice
   * @type {Array}
   */
  this.values = [0, 0];

  /**
   * List of moves the player can make. Usually moves are equal to values,
   * but in most rules doubles (eg. 6:6) are played four times, instead of
   * two, in which case moves array will contain four values in stead of
   * only two (eg. [6, 6, 6, 6]).
   * @type {Array}
   */
  this.moves = [];

  /**
   * After dice is rolled, movesLeft contains the same values as moves.
   * When the player makes a move, the corresponding value is removed from
   * movesLeft array. If the player wants to undo the moves made, movesLeft is
   * replaced with moves.
   * @type {Array}
   */
  this.movesLeft = [];
}

/**
 * Roll dice and return result as a new Dice object
 * @returns {Dice} - New dice with random values
 */
Dice.roll = function() {
  var dice = new Dice();
  
  dice.values[0] = Random.get();
  dice.values[1] = Random.get();
  dice.values.sort(function (a, b) { return b - a; });
  return dice;
};

/**
 * Roll dice and return result as a new Dice object
 * @param {Dice} dice - New dice with random values
 * @param {number} move - New dice with random values
 */
Dice.markAsPlayed = function (dice, move) {
  for (var i = 0; i < dice.movesLeft.length; i++) {
    if (dice.movesLeft[i] === move) {
      dice.movesLeft.splice(i, 1);
      return;
    }
  }
  throw new Error("No such move!");
}

/**
 * State contains points and pieces and very basic methods to move pieces
 * around without enforcing any rules. Those methods are responsible for
 * required changes to internal state only, the UI layer should handle
 * graphical movement of pieces itself.
 * @constructor
 */
function State() {
  /**
   * All popular variants of the game have a total of 24 positions on the board
   * and two positions outside - the place on the bar where pieces go when
   * hit and the place next to board where pieces go when beared off.
   * Number of positions is not strictly defined here to allow more options
   * when creating new rules.
   * The points, bar, outside and pieces properties should be initialized by the
   * Rule object. Each element in those properties should contain a stack
   * (last in, first out).
   * @type {Array}
   */
  this.points = [];
<commit_msg>Add field for tracking moves played in Dice, determining doubles and getting remaining moves (moves that has not been played).<commit_after>var crypto = require('crypto');

/**
 * Current version supports only two colours of checkers and two players as
 * the author is not yet aware of rules with three or more types of checkers
 * and/or players.
 * @readonly
 * @enum {number}
 */
var PieceType = {
  /** White piece */
  WHITE : 0,
  /** Black piece */
  BLACK : 1
};

/**
 * Denotes direction of piece movement relative to initial position.
 * @readonly
 * @enum {number}
 */
var Direction = {
  /** LEFT: from initial position to left (then to right on opposite side of board) */
  LEFT : 0,
  /** RIGHT: from initial position to right (then to left on opposite side of board) */
  RIGHT : 1
};

/**
 * Random generator.
 * @constructor
 */
function Random() {

}

/**
 * Get random number from 1 to 6
 * @returns {number} - Random value from 1 to 6
 */
Random.get = function() {
  // TODO: replace with quality random generator
  
  // Combine Math random generator with crypto one
  var buffer = crypto.randomBytes(1);
  var value = buffer.readUInt8(0);
  console.log(value);
  if (value > 255) {
    value = 255;
  }
  var k = value / 256;
  
  return (Math.floor(k * 6) + 1);
};

/**
 * Pieces are round checkers that are being moved around the board.
 * @constructor
 * @param {PieceType} type - Type of piece
 * @param {number} id - ID of piece
 */
function Piece(type, id) {
  /**
   * Type of piece (white/black)
   * @type {PieceType}
   */
  this.type = type;

  /**
   * ID of piece
   * @type {number}
   */
  this.id = id;
}

/**
 * Dice with basic functionality to roll using good random generator.
 * @constructor
 */
function Dice() {
  /**
   * Values of the two dice
   * @type {Array}
   */
  this.values = [0, 0];

  /**
   * List of moves the player can make. Usually moves are equal to values,
   * but in most rules doubles (eg. 6:6) are played four times, instead of
   * two, in which case moves array will contain four values in stead of
   * only two (eg. [6, 6, 6, 6]).
   * @type {Array}
   */
  this.moves = [];

  /**
   * After dice is rolled, movesLeft contains the same values as moves.
   * When the player makes a move, the corresponding value is removed from
   * movesLeft array. If the player wants to undo the moves made, movesLeft is
   * replaced with moves.
   * @type {Array}
   */
  this.movesLeft = [];
  
  /**
   * After a piece is moved, the value of the die used is added to movesPlayed array.
   * @type {Array}
   */
  this.movesPlayed = [];
}

/**
 * Roll dice and return result as a new Dice object
 * @returns {Dice} - New dice with random values
 */
Dice.roll = function() {
  var dice = new Dice();
  
  dice.values[0] = Random.get();
  dice.values[1] = Random.get();
  dice.values.sort(function (a, b) { return b - a; });
  return dice;
};

/**
 * Roll dice and return result as a new Dice object
 * @param {Dice} dice - New dice with random values
 * @param {number} move - New dice with random values
 */
Dice.markAsPlayed = function (dice, move) {
  for (var i = 0; i < dice.movesLeft.length; i++) {
    if (dice.movesLeft[i] === move) {
      dice.movesPlayed.push(dice.movesLeft[i]);
      dice.movesLeft.splice(i, 1);
      return;
    }
  }
  throw new Error("No such move!");
};

/**
 * Check if the dice object has double (equal) values.
 * @param {Dice} dice - New dice with random values
 * @returns {boolean} - True if dice object has dobule values, false otherwise
 */
Dice.isDouble = function (dice) {
  return dice.values[0] == dice.values[1];
};

/**
 * Get remaining moves from dice object - moves that have not been played.
 * @param {Dice} dice - Dice object
 * @returns {Array} - Array containing remaining move values
 */
Dice.getRemainingMoves = function (dice) {
  var remaining = [];
  var played = [];
  played = played.concat(dice.movesPlayed);

  for (var i = 0; i < dice.moves.length; i++) {
    var index = played.indexOf(dice.moves[i]);
    if (index >= 0) {
      played.splice(index, 1);
    }
    else {
      remaining.push(dice.moves[i]);
    }
  }
  
  return remaining;
};

/**
 * State contains points and pieces and very basic methods to move pieces
 * around without enforcing any rules. Those methods are responsible for
 * required changes to internal state only, the UI layer should handle
 * graphical movement of pieces itself.
 * @constructor
 */
function State() {
  /**
   * All popular variants of the game have a total of 24 positions on the board
   * and two positions outside - the place on the bar where pieces go when
   * hit and the place next to board where pieces go when beared off.
   * Number of positions is not strictly defined here to allow more options
   * when creating new rules.
   * The points, bar, outside and pieces properties should be initialized by the
   * Rule object. Each element in those properties should contain a stack
   * (last in, first out).
   * @type {Array}
   */
  this.points = [];

{'fraction_non_alphanumeric': 0.11575418994413408, 'fraction_numerical': 0.008603351955307263, 'mean_word_length': 2.8631851532153645, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, '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': '5723003', 'n_tokens_mistral': 2805, 'n_tokens_neox': 2717, 'n_words': 1151}