public T getBestTransition() {
        if (getPossibleTransitions().isEmpty()) {
            return null;
        }
        final int currentPlayer = getCurrentPlayer();
        Path<T, N> path;
        boolean stop = false;
        // TODO : do it in a interuptable Thread
        do {
	        path = selection(pathToRoot, currentPlayer);
	        if (path != null) {
	            // the tree has not been fully explored yet
	            path = expansion(path);
	            int winner = simulation();
	            backPropagation(path, winner);
	        }
        } while (path != null && !stop);
        // state is restored
        assert currentPlayer == getCurrentPlayer();
        T best = null;
        double bestValue = Double.NEGATIVE_INFINITY;
        // all possible transitions are set on root node
        // see expansion(Path<T, N> path)
        for (Map.Entry<T, ? extends Node<T>> e : pathToRoot.endNode().getTransitionsAndNodes().entrySet()) {
            double value = e.getValue().value(currentPlayer);
            if (value > bestValue) {
                bestValue = value;
                best = e.getKey();
            }
        }
        return best;
    }