Пример #1
0
        public void StartTesting(User user, string testId)
        {
            lock (_locker)
            {
                try
                {
                    bool sendData = false;
                    Test test;
                    using (TestingSystemContext context = new TestingSystemContext())
                    {
                        test = context.Tests.Include(c => c.Questions).FirstOrDefault(t => t.Id.Equals(testId));
                    }

                    if (test != null)
                    {
                        TestOnline testOnline;
                        bool       isFoundTest = _onlineTests.TryGetValue(testId, out testOnline);

                        // если тест уже есть в списке
                        if (isFoundTest)
                        {
                            // если есть группы
                            if (testOnline.Groups.Count > 0)
                            {
                                // проходим циклом по всем группам
                                for (int i = 0; i < testOnline.Groups.Count; i++)
                                {
                                    if (sendData)
                                    {
                                        break;
                                    }

                                    // если кол-во подгрупп в группе равно макс. кол-ву подгрупп в группе
                                    // значит свободных мест нет и надо идти дальше
                                    if (testOnline.Groups[i].Subgroups.Count == testOnline.MaxCountInGroup)
                                    {
                                        // если i+1 меньше кол-ва групп
                                        // значит есть еще подгруппа
                                        if (i + 1 < testOnline.Groups.Count)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            // иначе больше групп нет надо создавать новую группу
                                            // и вытащить все вопросы с предыдущей группы и найти не повторяющиеся вопросы
                                            // найти первый не повтор и добавить его в список
                                            // после добавлен проверить если кол-во вопросов в списке равно
                                            // кол-ву вопросов всего в тесте то начать сначала

                                            IServiceCallback callback = Callback;

                                            if (callback != null)
                                            {
                                                // список вопросов которые есть в предыдущей группе
                                                List <Question> repeatQuestions = new List <Question>();

                                                int index = i - 1 < 0 ? 0 : i - 1;
                                                // если есть предыдущая группа
                                                if (index >= 0)
                                                {
                                                    // проходим циклом по каждой подгруппе
                                                    for (int j = 0; j < testOnline.Groups[index].Subgroups.Count; j++)
                                                    {
                                                        // добавляем все вопросы из каждой подгруппы в список
                                                        for (int k = 0;
                                                             k < testOnline.Groups[index].Subgroups[j].Questions.Count;
                                                             k++)
                                                        {
                                                            repeatQuestions.Add(testOnline.Groups[index]
                                                                                .Subgroups[j]
                                                                                .Questions[k]);
                                                        }
                                                    }
                                                }

                                                Group newGroup = new Group();
                                                newGroup.Id = Guid.NewGuid().ToString();

                                                Subgroup newSubgroup = new Subgroup();
                                                newSubgroup.Id       = Guid.NewGuid().ToString();
                                                newSubgroup.Callback = callback;
                                                newSubgroup.Timer    =
                                                    GetTimer(test.NumberMinutesToPassTest * 60, callback);

                                                List <Question> questions = new List <Question>();
                                                for (int j = 0; j < test.NumberOfQuestions; j++)
                                                {
                                                    for (int k = 0; k < test.Questions.Count; k++)
                                                    {
                                                        // поиск вопроса с указанным ид в списке выданных вопросов
                                                        Question question =
                                                            repeatQuestions.FirstOrDefault(q => q.Id.Equals(test
                                                                                                            .Questions[k]
                                                                                                            .Id));

                                                        // если не найдено значит вопрос еще не выдавался
                                                        if (question == null)
                                                        {
                                                            questions.Add(test.Questions[k]);
                                                            repeatQuestions.Add(test.Questions[k]);

                                                            // если кол-во вопр в списке равно общему кол-во вопросов в тесте
                                                            // то очищаем список
                                                            if (repeatQuestions.Count == test.Questions.Count)
                                                            {
                                                                repeatQuestions.Clear();
                                                            }
                                                            break;
                                                        }
                                                    }
                                                }

                                                newSubgroup.Questions = questions;

                                                List <Subgroup> subgroups = new List <Subgroup>();
                                                subgroups.Add(newSubgroup);

                                                newGroup.Subgroups = subgroups;

                                                testOnline.Groups.Add(newGroup);

                                                bool isUpdate = _onlineTests.TryUpdate(testId, testOnline, testOnline);

                                                if (isUpdate)
                                                {
                                                    sendData = true;
                                                    callback.SetQuestions(questions, newGroup.Id, newSubgroup.Id);
                                                    newSubgroup.Timer.Start();
                                                }
                                            }
                                        }
                                    }
                                    // иначе в группе есть свободное место для новой погруппы
                                    else
                                    {
                                        // найти свободные вопросы
                                        // взять все вопросы текущей группы и найти недостающие

                                        IServiceCallback callback = Callback;

                                        if (callback != null)
                                        {
                                            // список вопросов которые есть в текущей группе
                                            List <Question> repeatQuestions = new List <Question>();

                                            // проходим циклом по каждой подгруппе
                                            for (int j = 0; j < testOnline.Groups[i].Subgroups.Count; j++)
                                            {
                                                // добавляем все вопросы из каждой подгруппы в список
                                                for (int k = 0;
                                                     k < testOnline.Groups[i].Subgroups[j].Questions.Count;
                                                     k++)
                                                {
                                                    repeatQuestions.Add(testOnline.Groups[i].Subgroups[j].Questions[k]);
                                                }
                                            }

                                            Subgroup newSubgroup = new Subgroup();
                                            newSubgroup.Id       = Guid.NewGuid().ToString();
                                            newSubgroup.Callback = callback;
                                            newSubgroup.Timer    = GetTimer(test.NumberMinutesToPassTest * 60, callback);

                                            List <Question> questions = new List <Question>();

                                            for (int j = 0; j < test.NumberOfQuestions; j++)
                                            {
                                                for (int k = 0; k < test.Questions.Count; k++)
                                                {
                                                    // поиск вопроса с указанным ид в списке выданных вопросов
                                                    Question question =
                                                        repeatQuestions.FirstOrDefault(
                                                            q => q.Id.Equals(test.Questions[k].Id));

                                                    // если не найдено значит вопрос еще не выдавался
                                                    if (question == null)
                                                    {
                                                        questions.Add(test.Questions[k]);
                                                        repeatQuestions.Add(test.Questions[k]);

                                                        // если кол-во вопр в списке равно общему кол-во вопросов в тесте
                                                        // то очищаем список
                                                        if (repeatQuestions.Count == test.Questions.Count)
                                                        {
                                                            repeatQuestions.Clear();
                                                        }
                                                        break;
                                                    }
                                                }
                                            }

                                            newSubgroup.Questions = questions;
                                            testOnline.Groups[i].Subgroups.Add(newSubgroup);

                                            bool isUpdate = _onlineTests.TryUpdate(testId, testOnline, testOnline);

                                            if (isUpdate)
                                            {
                                                sendData = true;
                                                callback.SetQuestions(questions, testOnline.Groups[i].Id,
                                                                      newSubgroup.Id);
                                                newSubgroup.Timer.Start();
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // если групп нет то создаем новую (первую) группу

                                IServiceCallback callback = Callback;

                                if (callback != null)
                                {
                                    Group newGroup = new Group();
                                    newGroup.Id = Guid.NewGuid().ToString();

                                    Subgroup newSubgroup = new Subgroup();
                                    newSubgroup.Id       = Guid.NewGuid().ToString();
                                    newSubgroup.Callback = callback;
                                    newSubgroup.Timer    = GetTimer(test.NumberMinutesToPassTest * 60, callback);

                                    List <Question> questions = new List <Question>();
                                    for (int i = 0; i < test.NumberOfQuestions; i++)
                                    {
                                        questions.Add(test.Questions[i]);
                                    }

                                    newSubgroup.Questions = questions;

                                    List <Subgroup> subgroups = new List <Subgroup>();
                                    subgroups.Add(newSubgroup);

                                    newGroup.Subgroups = subgroups;

                                    List <Group> groups = new List <Group>();
                                    groups.Add(newGroup);

                                    testOnline.Groups = groups;

                                    sendData = true;
                                    callback.SetQuestions(questions, newGroup.Id, newSubgroup.Id);
                                    newSubgroup.Timer.Start();
                                }
                            }
                        }
                        else
                        {
                            IServiceCallback callback = Callback;

                            if (callback != null)
                            {
                                // если теста нет еще в списке, то добавляем его туда
                                TestOnline newTestOnline = new TestOnline();

                                // находим максимальное количество подгрупп в одной группе
                                // кол-во вопросов / кол-во выдаваемых вопросов
                                newTestOnline.MaxCountInGroup = test.Questions.Count / test.NumberOfQuestions;

                                Group newGroup = new Group();
                                newGroup.Id = Guid.NewGuid().ToString();

                                Subgroup newSubgroup = new Subgroup();
                                newSubgroup.Id       = Guid.NewGuid().ToString();
                                newSubgroup.Callback = callback;
                                newSubgroup.Timer    = GetTimer(test.NumberMinutesToPassTest * 60, callback);

                                List <Question> questions = new List <Question>();
                                for (int i = 0; i < test.NumberOfQuestions; i++)
                                {
                                    questions.Add(test.Questions[i]);
                                }

                                newSubgroup.Questions = questions;

                                List <Subgroup> subgroups = new List <Subgroup>();
                                subgroups.Add(newSubgroup);

                                newGroup.Subgroups = subgroups;

                                List <Group> groups = new List <Group>();
                                groups.Add(newGroup);

                                newTestOnline.Groups = groups;

                                _onlineTests.TryAdd(test.Id, newTestOnline);

                                callback.SetQuestions(questions, newGroup.Id, newSubgroup.Id);
                                newSubgroup.Timer.Start();
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
            }
        }