Как я могу выбрать почти случайные вопросы из списка в зависимости от того, на каком уровне вы находитесь? - PullRequest
0 голосов
/ 13 ноября 2018

Я работаю над проектом и хочу выбрать разные вопросы в зависимости от того, на каком уровне вы находитесь.

Например, первые 25 уровней, которые я хочу, чтобы моя система выбирала простые вопросы, например, ввероятность 80% и средние вопросы в 20%.В конце 80-го уровня я хочу, чтобы сложность постепенно увеличивалась, и система будет на 100% выбирать только сложные вопросы.Как я могу написать работающий медленно растущий граф математически для реализации в мой arraypicker?

Я пытался перетасовать ArrayList объекты с:

Collections.shuffle(random);

, например, чтобы получить проценты,но я должен найти более простой способ обойти это.

Трудно объяснить, но я надеюсь, что вы понимаете, спросите, нужна ли вам дополнительная информация.Я работаю над проектом libgdx на Android studio

1 Ответ

0 голосов
/ 17 ноября 2018

У вас есть несколько проблем, заключенных в один вопрос, что делает ваш вопрос немного более широким для этого сайта, но давайте разберем ваши проблемы:

  • Создайте класс вопросов с различными уровнями сложности.Давайте назовем этот класс Question и уровень сложности Difficulty
  • Создайте класс, который содержит эти вопросы в коллекции или в коллекциях какого-либо рода, и разрешите пользователю запрашивать случайный вопрос из этого класса.Давайте назовем этот класс QuestionCollection и метод, используемый для запроса случайного вопроса, public Question getRandomQuestion(...).
  • Разрешить пользователю иметь свой собственный уровень продвижения.Это может быть User класс
  • Распределение вопросов, возможно, полученных из запроса getRandomQuestion(...), будет зависеть от уровня продвижения пользователя

Итак, сначала инкапсулируем уровеньсложности, давайте создадим перечисление, которое имеет 3 (или более) уровня:

public enum Difficulty {
    EASY, MEDIUM, HARD
}

Тогда класс Question может иметь поле private Difficulty difficulty;, одно в своем конструкторе и с открытым методом getter.public Difficulty getDifficulty().Упрощенный класс Question может выглядеть примерно так:

public class Question {
    private String question;
    private String answer;
    private Difficulty difficulty;

    public Question(String question, String answer, Difficulty difficulty) {
        this.question = question;
        this.answer = answer;
        this.difficulty = difficulty;
    }

    public String getQuestion() {
        return question;
    }

    public String getAnswer() {
        return answer;
    }

    public Difficulty getDifficulty() {
        return difficulty;
    }

}

Опять же, это слишком упрощенное решение, но его можно использовать для иллюстрации проблемы и возможного решения.При желании вы могли бы реализовать в этом классе Comparable<Question> и использовать Трудность, чтобы помочь выполнить сравнение, и позволить вам сортировать List<Question> по сложности.

Тогда ключом ко всему этому будетQuestionCollection класс, который содержал набор (ы) вопросов и в котором был метод getRandomQuestion(...) - как это реализовать.

Один из способов, а не беспокоиться об уровне продвижения пользователя на уровнеНа этом этапе передайте методу getRandomQuestion(...) некоторые параметры, которые позволят QuestionCollection узнать, какой дистрибутив использовать.Самое простое, на мой взгляд, дать ему относительную частоту сложности, в процентах Difficulty.EASY, Difficulty.MEDIUM и Difficulty.HARD, что-то вроде:

public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
    // ... code here to get the random question
}

ОК, так что теперь мы находимся накак построить внутреннюю работу класса QuestionCollection, а затем использовать это, чтобы получить правильное распределение случайных вопросов, основанных на процентах параметров.Вероятно, самый простой - это поместить вопрос в свой собственный список, такой как ArrayList, основываясь на его уровне сложности - так что здесь 3 списка, один для EASY, один для MEDIUM и один для HARD вопросов.

Итак:

private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();

Или другое, возможно, чистое решение состоит в том, чтобы использовать Map<Difficulty, List<Question>> вместо отдельных списков, но сейчас я сделаю все просто иоставьте это в 3 Списках.

Тогда у класса будет метод public void addQuestion(Question q), который будет добавлять вопросы в правильный список на основе уровня сложности:

public void addQuestion(Question q) {
    switch (q.getDifficulty()) {
    case EASY:
        easyQuestions.add(q);
        break;
    case MEDIUM:
        mediumQuestions.add(q);
        break;
    case HARD:
        hardQuestions.add(q);
    }
}

ОК, поэтому наши списки заполнены вопросамиТеперь мы находимся в центре вопроса о том, как получить правильное распределение рандомизации?Я бы рекомендовал двухэтапный процесс - сначала используйте Math.random() или экземпляр класса Random, чтобы выбрать из какого списка , чтобы получить вопрос, а затем используйте команду randomization, чтобы выбрать случайный вопрос извыбранный список.

Итак, первый шаг для получения случайного списка может выглядеть так:

// declare variable before the if blocks
List<Question> randomList = null;

// get a random int from 0 to 99
int rand = (int) (100 * Math.random());

// get the random list using basic math and if blocks
if (rand < percentEasy) {
    randomList = easyQuestions;
} else if (rand < percentEasy + percentMedium) {
    randomList = mediumQuestions;
} else {
    randomList = hardQuestions;
}

ОК, как только будет получен randomList, затем получите случайный вопрос из него:

// first get a random index to the list from 0 to < size
int size = randomList.size();
int listIndex = (int)(size * Math.random());
Question randomQuestion = randomList.get(listIndex);
return randomQuestion;

Весь класс QuestionCollection (упрощенная версия) может выглядеть так:

// imports here

public class QuestionCollection {
    private List<Question> easyQuestions = new ArrayList<>();
    private List<Question> mediumQuestions = new ArrayList<>();
    private List<Question> hardQuestions = new ArrayList<>();

    public void addQuestion(Question q) {
        switch (q.getDifficulty()) {
        case EASY:
            easyQuestions.add(q);
            break;
        case MEDIUM:
            mediumQuestions.add(q);
            break;
        case HARD:
            hardQuestions.add(q);
        }
    }

    public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
        // if the numbers don't add up to 100, the distribution is broken -- throw an exception
        if (percentEasy + percentMedium + percentHard != 100) {
            String format = "For percentEasy: %d, percentMedium: %d, percentHard: %d";
            String text = String.format(format, percentEasy, percentMedium, percentHard);
            throw new IllegalArgumentException(text);
        }

        List<Question> randomList = null;
        int rand = (int) (100 * Math.random());
        if (rand < percentEasy) {
            randomList = easyQuestions;
        } else if (rand < percentEasy + percentMedium) {
            randomList = mediumQuestions;
        } else {
            randomList = hardQuestions;
        }

        // we've now selected the correct List
        // now get a random question from the list:

        // first get a random index to the list from 0 to < size
        int size = randomList.size();
        int listIndex = (int)(size * Math.random());
        Question randomQuestion = randomList.get(listIndex);
        return randomQuestion;
    }
}

Итак, для проверки концепции, тестовая программа показывает, что дистрибутив работает:

// imports

public class QuestionFun {
    public static void main(String[] args) {
        // create QuestionCollection object
        QuestionCollection questionCollection = new QuestionCollection();

        // fill it with questions with random difficulty
        for (int i = 0; i < 1000; i++) {
            String question = "Question #" + i;
            String answer = "Answer #" + i;
            int randomIndex = (int) (Difficulty.values().length * Math.random());
            Difficulty difficulty = Difficulty.values()[randomIndex];
            Question q = new Question(question, answer, difficulty);
            questionCollection.addQuestion(q);
        }

        Map<Difficulty, Integer> frequencyDistMap = new EnumMap<>(Difficulty.class);
        for (Difficulty diff : Difficulty.values()) {
            frequencyDistMap.put(diff, 0);
        }

        int easyPercent = 20;
        int mediumPercent = 70;
        int hardPercent = 10;

        int questionCount = 10000;
        for (int i = 0; i < questionCount; i++) {
            Question q = questionCollection.getRandomQuestion(easyPercent, mediumPercent, hardPercent);
            Difficulty difficulty = q.getDifficulty();
            int currentCount = frequencyDistMap.get(difficulty);
            currentCount++;
            frequencyDistMap.put(difficulty, currentCount);
        }

        System.out.println("Difficulty: Count (Percent)");
        String format = "%-12s %4d   (%02d)%n";
        for (Difficulty difficulty : Difficulty.values()) {
            int number = frequencyDistMap.get(difficulty);
            int percent = (int) Math.round((100.0 * number) / questionCount);
            System.out.printf(format, difficulty + ":", number, percent);
        }
    }
}

Возвращает исходный процент распределения:

Difficulty: Count (Percent)
EASY:      200325   (20)
MEDIUM:    699341   (70)
HARD:      100334   (10)
...