/// <summary> /// 퀴즈를 시작합니다. /// </summary> /// <param name="quizType">퀴즈의 유형</param> /// <param name="subjects">주제 목록</param> /// <param name="requestQuizCount">요청하는 퀴즈의 총 개수</param> /// <param name="minQuizCount">퀴즈 최소 개수</param> /// <param name="quizTimeLimit">퀴즈의 제한시간</param> /// <param name="bonusExperience">퀴즈 정답 시 획득 경험치</param> /// <param name="bonusMoney">퀴즈 정답 시 획득 머니</param> /// <param name="idleTimeLimit">퀴즈의 잠수 제한시간</param> /// <param name="showSubject">주제 표시 여부</param> protected void StartQuiz(Quiz.TypeOption quizType, string[] subjects, int requestQuizCount, int minQuizCount, int quizTimeLimit, int bonusExperience, int bonusMoney, int idleTimeLimit = 180, bool showSubject = true) { IsQuizTaskRunning = true; Thread.Sleep(1000); List <Quiz.Data> quizDataList = GetQuizDataList(quizType, subjects, requestQuizCount); if (quizDataList.Count < requestQuizCount) { requestQuizCount = quizDataList.Count; } if (requestQuizCount < minQuizCount) { Thread.Sleep(SendMessageInterval); OnQuizCountInvalid(minQuizCount, requestQuizCount); IsQuizTaskRunning = false; return; } string[] notices = GetQuizNoticesFromFile(); Thread.Sleep(SendMessageInterval); SendMessage($"{notices[BotRandom.Next(notices.Length)]}"); Thread.Sleep(2000); bool isRandom = subjects.Length > 1 ? true : false; OnQuizReady(); RunQuiz(quizType, subjects, requestQuizCount, quizTimeLimit, bonusExperience, bonusMoney, idleTimeLimit, showSubject, isRandom, quizDataList); if (IsQuizTaskRunning) { IsQuizTaskRunning = false; } Thread.Sleep(2000); KakaoTalk.Message[] messages; if (IsMainTaskRunning) { while ((messages = Window.GetMessagesUsingClipboard()) == null) { Thread.Sleep(GetMessageInterval); } LastMessageIndex = (messages.Length - 1) + 1; OnQuizFinish(); } }
/// <summary> /// 퀴즈 실행부입니다. /// </summary> /// <param name="quizType">퀴즈의 유형</param> /// <param name="subjects">주제 목록</param> /// <param name="requestQuizCount">요청하는 퀴즈의 총 개수</param> /// <param name="quizTimeLimit">퀴즈의 제한시간</param> /// <param name="bonusExperience">퀴즈 정답 시 획득 경험치</param> /// <param name="bonusMoney">퀴즈 정답 시 획득 머니</param> /// <param name="idleTimeLimit">퀴즈의 잠수 제한시간</param> /// <param name="showSubject">주제 표시 여부</param> /// <param name="isRandom">주제 랜덤 여부</param> /// <param name="quizDataList">퀴즈 데이터 목록</param> protected void RunQuiz(Quiz.TypeOption quizType, string[] subjects, int requestQuizCount, int quizTimeLimit, int bonusExperience, int bonusMoney, int idleTimeLimit, bool showSubject, bool isRandom, List <Quiz.Data> quizDataList) { KakaoTalk.Message[] messages; KakaoTalk.MessageType messageType; string userName; string content; DateTime sendTime; QuizUser user; int lastInputTick = Environment.TickCount; for (int i = 0; i < requestQuizCount; i++) // == quizDataList.Count { int currentQuiz = i + 1; var quizData = quizDataList[i]; string subject = quizData.MainSubject; if (quizData.ChildSubject != null) { subject += $"-{quizData.ChildSubject}"; } string question = quizData.Question; string answer = quizData.Answer; string explanation = quizData.Explanation; string beforeImagePath = quizData.BeforeImagePath; string afterImagePath = quizData.AfterImagePath; bool isCaseSensitive = quizData.IsCaseSensitive; while ((messages = Window.GetMessagesUsingClipboard()) == null) { Thread.Sleep(GetMessageInterval); } LastMessageIndex = (messages.Length - 1) + 1; // 뒤에 바로 SendMessage를 하므로, +1 해서 초기화 OnQuizQuestionSend(isRandom, showSubject, subject, currentQuiz, requestQuizCount, question); if (beforeImagePath != null) { OnQuizBeforeImageSend(beforeImagePath); } if (quizData.Choices != null) { OnQuizChoicesSend(quizData.Choices); } int beginTick = Environment.TickCount; bool shouldContinue = true; while (IsQuizTaskRunning && shouldContinue) { Thread.Sleep(QuizScanInterval); if (Environment.TickCount > lastInputTick + (idleTimeLimit * 1000)) { IsQuizTaskRunning = false; OnQuizIdleLimitExceed(); break; } else if (Environment.TickCount > beginTick + (quizTimeLimit * 1000)) // 시간 제한 초과 { OnQuizTimeLimitExceed(answer); shouldContinue = false; } else { while ((messages = Window.GetMessagesUsingClipboard()) == null) { Thread.Sleep(GetMessageInterval); } sendTime = DateTime.Now; for (int j = LastMessageIndex; j < messages.Length; j++) { messageType = messages[j].Type; userName = messages[j].UserName; content = messages[j].Content; LastMessageIndex++; user = FindUserByNickname(userName); if (user == null) { AddNewUser(userName); user = FindUserByNickname(userName); } if (!isCaseSensitive) { content = content.ToLower(); answer = answer.ToLower(); } if (IsQuizTaskRunning) // 다른 곳에서 StopQuiz 요청에 의해 IsQuizTaskRunning은 false가 될 수 있음. 따라서 검사 시마다 확인. { if (messageType == KakaoTalk.MessageType.Unknown) { continue; } else if (messageType == KakaoTalk.MessageType.DateChange) { SendDateChangeNotice(content, sendTime); } else if (messageType == KakaoTalk.MessageType.UserJoin) { SendUserJoinNotice(userName, sendTime); } else if (messageType == KakaoTalk.MessageType.UserLeave) { SendUserLeaveNotice(userName, sendTime); } else if (messageType == KakaoTalk.MessageType.Talk) { if (content == answer) { lastInputTick = Environment.TickCount; OnQuizAnswerCorrect(answer, user, bonusExperience, bonusMoney); shouldContinue = false; break; } else { ProcessUserMessage(userName, content, sendTime); } } } else { break; } } } if (IsQuizTaskRunning && !shouldContinue) { if (afterImagePath != null) { OnQuizAfterImageSend(afterImagePath); } if (explanation != null) { OnQuizExplanationSend(explanation); } else { Thread.Sleep(1500); } } } if (!IsQuizTaskRunning) { break; } else if (i == requestQuizCount - 1) { OnQuizAllCompleted(); IsQuizTaskRunning = false; } } }
/// <summary> /// 퀴즈 데이터 목록을 얻어옵니다. /// </summary> /// <param name="requestedQuizType">요청된 퀴즈 유형</param> /// <param name="subjects">주제 목록</param> /// <param name="quizCount">퀴즈 개수</param> /// <returns>퀴즈 데이터 목록</returns> protected List <Quiz.Data> GetQuizDataList(Quiz.TypeOption requestedQuizType, string[] subjects, int quizCount) { var data2dList = new List <List <Quiz.Data> >(); List <Quiz.Data> tempList; bool matchesChildSubject; /* resultDataList 초기화 */ for (int i = 0; i < subjects.Length; i++) { foreach (Quiz quiz in QuizList) { if (quiz.Type == requestedQuizType) { string mainSubject = quiz.MainSubject; if (mainSubject == subjects[i]) { tempList = new List <Quiz.Data>(); for (int j = 0; j < quiz.DataList.Count; j++) { var data = quiz.DataList[j]; if (quiz.UseMultiChoice == true) { data.Choices = GetChoiceList(quiz, data); } tempList.Add(data); } data2dList.Add(tempList); break; } else { matchesChildSubject = false; foreach (string childSubject in quiz.ChildSubjects) { if ($"{mainSubject}-{childSubject}" == subjects[i]) { tempList = new List <Quiz.Data>(); for (int j = 0; j < quiz.DataList.Count; j++) { var data = quiz.DataList[j]; if (data.ChildSubject == childSubject) { if (quiz.UseMultiChoice == true) { data.Choices = GetChoiceList(quiz, data); } tempList.Add(data); } } data2dList.Add(tempList); matchesChildSubject = true; } } if (matchesChildSubject) { break; } } } } } /* data2dList Shuffle */ int shuffleCount = 3; for (int i = 0; i < data2dList.Count; i++) { for (int j = 0; j < shuffleCount; j++) { ListUtil.Shuffle(data2dList[i]); } } /* 배열 리스트, 문항 수 초기화 */ List <Quiz.Data[]> dataArrList = new List <Quiz.Data[]>(); int totalCount = 0; for (int i = 0; i < data2dList.Count; i++) { dataArrList.Add(new Quiz.Data[data2dList[i].Count]); totalCount += data2dList[i].Count; } if (totalCount > quizCount) { totalCount = quizCount; } /* 문제 선택 및 결과 리스트로 이동 */ var resultDataList = new List <Quiz.Data>(); for (int i = 0; i < totalCount; i++) { int randomValue = BotRandom.Next(dataArrList.Count); for (int j = 0; j < dataArrList[randomValue].Length; j++) { if (dataArrList[randomValue][j] == null) { dataArrList[randomValue][j] = data2dList[randomValue][j]; resultDataList.Add(dataArrList[randomValue][j]); break; } else if (j == dataArrList[randomValue].Length - 1) { i--; } } } /* 결과 리스트 shuffle (리스트 내에서 다시 셔플) */ for (int i = 0; i < shuffleCount; i++) { ListUtil.Shuffle(resultDataList); } return(resultDataList); }