// vi:ts=4:sts=4:sw=4:noet:tw=72 package modules import ( "bufio" "flokatirc/util" "fmt" "os" "regexp" "strings" "time" "github.com/sorcix/irc" "code.dnix.de/an/xlog" ) type quizQuestion struct { category, question, answer, regexp string } var ( quizCtrlCh = make(chan string, 1024) quizAnswerCh = make(chan *irc.Message, 1024) quizQuestions []quizQuestion ) func init() { MsgFuncs["quiz"] = quizHandleMessage RunFuncs["quiz"] = quiz quizQuestions = quizLoadQuestions("./modules/quiz/questions.de") } func quizHandleMessage(m *irc.Message) { tok := strings.Split(m.Trailing, " ") if len(tok) < 1 { return } switch tok[0] { case "!quizstart": quizCtrlCh <- "start" break case "!quizstop": quizCtrlCh <- "stop" break default: quizAnswerCh <- m break } } func quiz() { SayCh <- fmt.Sprintf("%s\nquiz mod test. !quizstart to start, !quizstop to end.", "*") for { time.Sleep(1 * time.Millisecond) select { case s := <-quizCtrlCh: if s == "start" { quizRun() } default: break } } } func quizRun() { for { if !quizAskQuestion() { return } } } func quizAskQuestion() bool { q := quizQuestions[util.Random(0, len(quizQuestions))] SayCh <- fmt.Sprintf("%s\n%s (Kategorie: %s)", "*", q.question, q.category) m, solved, cont := quizWaitForAnswer(q) if solved { SayCh <- fmt.Sprintf("%s\n%s hat die Frage beantwortet.", "*", m.Prefix) } else { SayCh <- fmt.Sprintf("%s\nNiemand konnte die Frage beantworten.", "*") SayCh <- fmt.Sprintf("%s\nDie richtige Antwort wäre gewesen:", "*") SayCh <- fmt.Sprintf("%s\n%s", "*", q.answer) } time.Sleep(5 * time.Second) return cont } func quizWaitForAnswer(q quizQuestion) (*irc.Message, bool, bool) { i := 0 t := 0 for { select { case m := <-quizAnswerCh: re, err := regexp.Compile(q.regexp) if err != nil { xlog.Error(err.Error()) return nil, false, false } if re.MatchString(strings.ToLower(util.ReplaceUmlauts(m.Trailing))) { return m, true, true } break case s := <-quizCtrlCh: if s == "stop" { return nil, false, false } break default: time.Sleep(1 * time.Millisecond) t++ if t > 20000 { t = 0 i++ if i > 3 { return nil, false, true } else { quizGiveHint(q) } } } } } func quizGiveHint(q quizQuestion) { //SayCh <- fmt.Sprintf("%s\nHint: %s | %s", "*", q.answer, q.regexp) } func quizLoadQuestions(path string) []quizQuestion { file, err := os.Open(path) if err != nil { xlog.Fatal(err.Error()) } defer file.Close() questions := make([]quizQuestion, 0) q := quizQuestion{"", "", "", ""} scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() if len(line) == 0 || line[0] == '#' || line[0] == '\n' { if q.category != "" { questions = append(questions, q) q = quizQuestion{"", "", "", ""} } } else { tok := strings.Split(line, ": ") switch tok[0] { case "Category": q.category = tok[1] break case "Question": q.question = tok[1] break case "Answer": q.answer = strings.Replace(tok[1], "#", "", -1) q.answer = util.ReplaceUmlauts(q.answer) regexp := strings.Split(tok[1], "#") if q.regexp == "" { if len(regexp) > 1 { q.regexp = strings.ToLower(regexp[1]) } else { q.regexp = strings.ToLower(regexp[0]) } } break case "Regexp": q.regexp = util.ReplaceUmlauts(tok[1]) break } } } if err := scanner.Err(); err != nil { xlog.Fatal(err.Error()) } return questions }