moveList = generateMoves();
while (moveList not empty) {
   nextMove = getNextMove();
   if (nextMove in moveChains) {
      moveSequence = getMoveSequence(nextMove, moveChains);
      if (isValid(moveSequence)) {
         linkPath = moveSequence;
         nextEval = evalSearch(linkPath, then rest of a-b plus quies);
      } else {
         remove moveSquence from moveChains;
         linkPath = null;
      }
   } else {
      linkPath = null;
   }
   if (linkPath == null) {
      nextEval = evalSearch(full a-b search + quies);
   }
   if (nextEval > bestEval) {
      bestEval = nextEval;
      bestMove = nextMove;
   }
   if (bestEval > alpha) {
      alpha = bestEval;
      bestPath = serchPath;
      if (linkPath != null) update linkPath in moveChains;
   }
}
always add final bestPath to moveChains;
function update_linkPath {
   if (path exists under move key) {
      replace with linkPath;
   } else {
      add linkPath as new path with first move as key;
   }
}
Algorithm 1: Search algorithm with move chains, highlighting where move chains are used.