В БД все вопросы должны содержать дополнительный аттрибут: сложность.
Пусть сложность = Sloz: int и изменяется от Sloz_0 до Sloz_1.
Для отвечающего (пользователя) можно тоже создавать профили в базе данных (если хочешь покруче). Можно сделать категории вопросов и т.о. дифференцировать опыт пользователя по категориям (математика, физика, информатика и т.д.).
Рассматриваем случай, когда без категорий.
Значит для тестируемого в профиле должен быть один аттрибут: "умность"
.
Пусть умность = Um: double и изменяется от Um_0 до Um_1.
Если без профилей (аноним), то Um := (Um_0 + Um_1) / 2;
Итерация ответа: {
Находишь вопрос который подходит для текужего значения Um.
(Это можно делать разными способами) [1]
В зависимости от правильности ответа изменяешь значение Um
(Это можно делать разными способами) [2]
}
[1]
тут если размеры Sloz и Um разные, то надо нормировать:
Otv_Pow = (Sloz - Sloz_0) / (Sloz_1 - Sloz_0);
Usr_Pow = (Um - Um_0) / (Um_1 - Um_0);
Как видишь все эти нормированные переменные изменябются от 0.0 до 1.0 и типа double.
Находим рандомный вопрос с таким вычисленным (т.е. вычисляется для каждого вопроса) Otw_Pow наиболее близким к вычисленным для пользователя Usr_Pow. Сам придумывай как. Зависит от твоей бд, и способов, собственно тоже много. Лучше вынести такие вещи в отдельные методы (процедуры), и менять их подгоняя алгоритм под себя. Так например, следующий вопрос должен быть желательно чуть выше, чем уровень пользователя, иначе он никогда не научится ))
[2]
А.
Если ответил правильно то вычисляем для отвеченного вопроса:
Otv_Pow = (Sloz - Sloz_0) / (Sloz_1 - Sloz_0);
Вычисляем для пользователя:
Usr_Pow = (Um - Um_0) / (Um_1 - Um_0);
IF (Usr_Pow > Otv_Pow) {
Usr_Pow увеличивается, но не сильно
} ELSE IF (Usr_Pow == Otv_Pow) {
Usr_Pow увеличивается нормально
} ELSE {
Usr_Pow увеличивается до Otv_Pow или даже больше
}
Б.
Если ответил неправильно то вычисляем для неотвеченного вопроса:
Otv_Pow = (Sloz - Sloz_0) / (Sloz_1 - Sloz_0);
Вычисляем для пользователя:
Usr_Pow = (Um - Um_0) / (Um_1 - Um_0);
IF (Usr_Pow < Otv_Pow) {
Usr_Pow уменьшаем совсем чуть-чуть
} ELSE IF (Usr_Pow == Otv_Pov) {
Usr_Pow уменьшаем нормально
} ELSE {
Usr_Pow уменьшаем до Otv_Pow или даже меньше
}
Конечно, лучше все уменьшения-увеличения делать пропорционально: Abs(Usr_Pow - Otv_Pow); где Abs - модуль