public List<GPTreePlayer> runTournament() {
        System.out.println("Tournament has started! --- " + new Date(System.currentTimeMillis()) + " --- ");

        Collections.shuffle(players, GPRandom.INSTANCE.getRand());

        try {
            playerTournament();
            randomPlayerTournament();
            positionTournament();
        } catch (InterruptedException  e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        List<GPTreePlayer> winners = new ArrayList<>(numberOfPlayersToReturn);
        System.out.println("\nThe best evolved players:\nwins EP / wins RP / draws EP / draws RP / matches / positions correct / treetitle_geneticCount");
        PlayerEnlist p;

        if (!maxApproach) {
            // using a weighted approach, see overall()-method below for more information
            Collections.sort(players);
            for (int i = 0; i < numberOfPlayersToReturn && i < players.size(); i++) {
                p = players.get(i);

                winners.add(p.player);
                System.out.println("\t" + i + "\t"
                                + p.matchesWonAgainstPlayer + "\t"
                                + p.matchesWonAgainstRandom + "\t"
                                + p.drawAgainstPlayer + "\t"
                                + p.drawAgainstRandom + "\t"
                                + p.matches + "\t"
                                + p.positionsCorrect + "\t"
                                + p.player.getTree().getTitle() + "_" + p.player.getTree().getGeneticCount()

                );
            }
        } else {

            // using the max approach

            // Sort by random
            Collections.sort(players, new Comparator<PlayerEnlist>() {
                @Override
                public int compare(PlayerEnlist o1, PlayerEnlist o2) {
                    return o2.matchesWonAgainstRandom - o1.matchesWonAgainstRandom;
                }
            });
            for (int i = 0; i < numberOfPlayersToReturn / 2 && i < players.size(); i++) {
                p = players.get(0);
                winners.add(p.player);
                System.out.println("\t" + i + " : "
                                + p.matchesWonAgainstPlayer + " / "
                                + p.matchesWonAgainstRandom + " / "
                                + p.drawAgainstPlayer + " / "
                                + p.drawAgainstRandom + " / "
                                + p.matches + " / "
                                + p.player.getTree().getTitle() + "_" + p.player.getTree().getGeneticCount()
                );
                players.remove(0);
            }

            // Sort by player
            Collections.sort(players, new Comparator<PlayerEnlist>() {
                @Override
                public int compare(PlayerEnlist o1, PlayerEnlist o2) {
                    return o2.matchesWonAgainstPlayer - o1.matchesWonAgainstPlayer;
                }
            });

            for (int i = 0; i < numberOfPlayersToReturn / 2 && i < players.size(); i++) {
                p = players.get(0);
                winners.add(p.player);
                System.out.println("\t" + i + " : "
                                + p.matchesWonAgainstPlayer + " / "
                                + p.matchesWonAgainstRandom + " / "
                                + p.drawAgainstPlayer + " / "
                                + p.drawAgainstRandom + " / "
                                + p.matches + " / "
                                + p.player.getTree().getTitle() + "_" + p.player.getTree().getGeneticCount()
                );
                players.remove(0);
            }

            // Mostly for the last selection of the overall winner.
            Collections.shuffle(winners, GPRandom.INSTANCE.getRand());
        }

        return winners;
    }