@Override
  public void suggestMove(Graph g, GameDefinition d, MovePointer movePtr) {
    Graph mg = GraphUtils.deepCopy(g);

    HashSet<Move> movesHistory = new HashSet<>();
    HashSet<Move> moveDraws = new HashSet<>();

    Move bestMove = getRandomMove(g, d.getActions(), weightLevels, null, false);
    movesHistory.add(bestMove);

    while (!this.isInterrupted()) {
      Move newMove = getRandomMove(g, d.getActions(), weightLevels, bestMove, clever);
      int gameScore = Game.runMoves(mg, d, bestMove, newMove).score;
      if (gameScore == 0) {
        if (moveDraws.add(newMove)) {
          log.debug("Draw with move {}", newMove);
        }
      } else if (gameScore > 0) {
        boolean contained = movesHistory.add(newMove);
        if (!contained) {
          log.debug("Going in circles after {}", newMove);
        }
        moveDraws.clear();
        bestMove = newMove;
        movePtr.submit(bestMove);
        log.info("New best move {}", newMove.toString());
      }
    }
  }
 public static Move getRandomMoveWithoutMutation(Graph g, int numOfMoves, int weightLevels) {
   Move moves = new Move();
   RandomVertexIterator it = new RandomVertexIterator(g);
   while (moves.getVerticesCount() < numOfMoves) {
     // TODO: Something must be done to allow selecting less than numOfMoves vertices.
     moves.putVertex(it.next(), RandomHelper.getRandom().nextInt(weightLevels) + 1);
   }
   return moves;
 }
  public static Move getRandomMoveWithMutation(
      Graph g, int numOfMoves, int weightLevels, Move lastMove) {
    double jump_probability =
        0.2; // TODO: Make it an option, or even better adaptive since it should depend on the
             // diameter of the graph

    Move moves = new Move();
    // TODO: This loop is problematic. There is a chance that 2 nodes surf to the same node and thus
    // create a move with less than numOfMoves nodes.
    // TODO: If this happens, it will never increase the nodes again
    for (Vertex mp : lastMove) {
      RandomSurferIterator randomSurfer = new RandomSurferIterator(g, 0.0, mp);
      while (RandomHelper.getRandom().nextDouble() < jump_probability) {
        mp = randomSurfer.next();
      }
      moves.putVertex(mp, RandomHelper.getRandom().nextInt(weightLevels) + 1);
    }
    return moves;
  }