<commit_before>// returns null if not deep enough to know
function isDrawish(node) {
  if (!hasSolidEval(node)) return null;
  return !node.ceval.mate && Math.abs(node.ceval.cp) < 150;
}
// returns null if not deep enough to know
function isWinning(node, goalCp) {
  if (!hasSolidEval(node)) return null;
  var cp = node.ceval.mate > 0 ? 99999 : (node.ceval.mate < 0 ? -99999 : node.ceval.cp);
  return goalCp > 0 ? cp >= goalCp : cp <= goalCp;
}

function hasSolidEval(node) {
  return node.ceval && node.ceval.depth >= 16;
}

function isMate(root) {
  return root.gameOver() === 'checkmate';
}
function isMyMate(root) {
  return isMate(root) && root.turnColor() !== root.bottomColor();
}
function isTheirMate(root) {
  return isMate(root) && root.turnColor() === root.bottomColor();
}

function hasBlundered(comment) {
  return comment && (comment.verdict === 'mistake' || comment.verdict === 'blunder');
}

// returns null = ongoing, true = win, false = fail
module.exports = function(root, goal, nbMoves) {
  var node = root.vm.node;
  if (!node.uci) return null;
  if (isTheirMate(root)) return false;
  if (hasBlundered(root.practice.comment())) return false;
  switch (goal.result) {
    case 'drawIn':
    case 'equalIn':
      if (node.threefold) return true;
      if (isDrawish(node) === false) return false;
      if (nbMoves > goal.moves) return false;
      if (root.gameOver() === 'draw') return true;
      if (nbMoves === goal.moves) return isDrawish(node);
      break;
    case 'evalIn':
      if (nbMoves === goal.moves) return isWinning(node, goal.cp);
      break;
    case 'mateIn':
      if (nbMoves > goal.moves) return false;
      if (isMyMate(root)) return true;
      if (nbMoves === goal.moves) return false;
      break;
    case 'promotion':
      if (!node.uci[4]) return null;
      return isWinning(node, goal.cp);
      break;
    case 'mate':
    default:
      if (isMyMate(root)) return true;
  }
  return null;
};
<commit_msg>practice: allow success condition on non-winning position<commit_after>// returns null if not deep enough to know
function isDrawish(node) {
  if (!hasSolidEval(node)) return null;
  return !node.ceval.mate && Math.abs(node.ceval.cp) < 150;
}
// returns null if not deep enough to know
function isWinning(node, goalCp, color) {
  if (!hasSolidEval(node)) return null;
  var cp = node.ceval.mate > 0 ? 99999 : (node.ceval.mate < 0 ? -99999 : node.ceval.cp);
  return color === 'white' ? cp >= goalCp : cp <= goalCp;
}

function hasSolidEval(node) {
  return node.ceval && node.ceval.depth >= 16;
}

function isMate(root) {
  return root.gameOver() === 'checkmate';
}
function isMyMate(root) {
  return isMate(root) && root.turnColor() !== root.bottomColor();
}
function isTheirMate(root) {
  return isMate(root) && root.turnColor() === root.bottomColor();
}

function hasBlundered(comment) {
  return comment && (comment.verdict === 'mistake' || comment.verdict === 'blunder');
}

// returns null = ongoing, true = win, false = fail
module.exports = function(root, goal, nbMoves) {
  var node = root.vm.node;
  if (!node.uci) return null;
  if (isTheirMate(root)) return false;
  if (hasBlundered(root.practice.comment())) return false;
  switch (goal.result) {
    case 'drawIn':
    case 'equalIn':
      if (node.threefold) return true;
      if (isDrawish(node) === false) return false;
      if (nbMoves > goal.moves) return false;
      if (root.gameOver() === 'draw') return true;
      if (nbMoves === goal.moves) return isDrawish(node);
      break;
    case 'evalIn':
      if (nbMoves === goal.moves) return isWinning(node, goal.cp, root.bottomColor());
      break;
    case 'mateIn':
      if (nbMoves > goal.moves) return false;
      if (isMyMate(root)) return true;
      if (nbMoves === goal.moves) return false;
      break;
    case 'promotion':
      if (!node.uci[4]) return null;
      return isWinning(node, goal.cp, root.bottomColor());
      break;
    case 'mate':
    default:
      if (isMyMate(root)) return true;
  }
  return null;
};

{'fraction_non_alphanumeric': 0.1521091811414392, 'fraction_numerical': 0.009181141439205955, 'mean_word_length': 3.444321940463065, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 14, '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': '2887056', 'n_tokens_mistral': 1431, 'n_tokens_neox': 1381, 'n_words': 375}