#!/usr/bin/perl package Quiz; use cybot; my @FILES = (); my %TOPICS = (); open F, "data/quiz/index" or die(""); while() { chomp; push @FILES, $_; open T, "data/quiz/$_" or die(""); my $i = 0; my $linha; while ($linha = ) { chomp($linha); push @{$TOPICS{$_}}, $linha unless $i; $i = 1; $i = 0 if ($linha eq "%"); } close T; } close F; my $quiz_channel = undef; my %players = (); my $state = 0; ## states: ## ## 0 - not playing at all ## 1 - waiting for a tick. next question in a tick -> (2) ## 2 - waiting for a tick. show the question and start logging answers. -> (3) ## 3 - waiting for n*tick. show results -> (1) my $nticks = 0; my $SUBJECT = ""; my %ANSWERS = (); # answer => 1 and after a player have corrected answer, answer => nick my $TOEND = 0; sub get_subject { my $bot = shift; %ANSWERS = (); $TOEND = 5; my @keys = keys %TOPICS; my $topic = $keys[random(scalar(@keys))-1]; @keys = @{$TOPICS{$topic}}; my $subject = $keys[random(scalar(@keys))-1]; $SUBJECT = $subject; open T, "data/quiz/$topic"; my $linha; my $s = 0; my @as = (); while($linha = ) { chomp($linha); if ($s == 0 && $linha =~ /^\s*$subject\s*$/) { while($linha=) { chomp($linha); last if $linha =~ /^%\s*$/; my $flinha = $linha; $linha =~ s/\(.*\)//; $linha =~ s/^\s*//; $linha =~ s/\s*$//; push @as, [$linha,$flinha] unless $linha eq "%"; } for (@as) { #$bot->message($quiz_channel, ">>$_"); $ANSWERS{$_->[0]}[0] = $_->[1]; $ANSWERS{$_->[0]}[1] = 1; } while(scalar(keys %ANSWERS) > 5) { my @x = keys %ANSWERS; my $rand = random(scalar(@x)-1); delete($ANSWERS{$x[$rand]}); } #for (keys %ANSWERS) { #$bot->message($quiz_channel, ">$_"); #} } if ($linha eq "%") { $s = 0; } else { $s = 1; } } close T; } sub show_punctuation { my $bot = shift; $bot->message($quiz_channel, join(" - ",map {"$_: $players{$_}"} keys %players)); } sub show_results { my $bot = shift; $bot->message($quiz_channel,"Subject: $SUBJECT"); my $i = 0; for (keys %ANSWERS) { $i++; if ($ANSWERS{$_}[1] == 1) { $bot->message($quiz_channel, "$i: $ANSWERS{$_}[0] ---> not answered"); } else { $bot->message($quiz_channel, "$i: $ANSWERS{$_}[0] ---> $ANSWERS{$_}[1] ($players{$ANSWERS{$_}[1]})"); } } show_punctuation($bot); } sub trigger { my ($bot,$nick,$hostmask,$chan,$message) = @_; if ($state == 3) { if (exists($players{$nick})) { if (exists($ANSWERS{$message}) && $ANSWERS{$message}[1] == 1) { $ANSWERS{$message}[1] = $nick; $players{$nick}++; $TOEND--; $bot->message($quiz_channel,"Answer '$message' by $nick($players{$nick}) | still $TOEND to end "); ## Check if all answers where given my $end = 1; for (keys %ANSWERS) { $end = 0 if $ANSWERS{$_}[1] == 1; } if ($end) { show_results($bot); $state = 1; } } } } } register_tick(sub { my $bot = shift; if ($state == 1) { $bot->message($quiz_channel,"Subject in $bot->{ticksize} seconds"); get_subject($bot); $state = 2; } elsif ($state == 2) { $bot->message($quiz_channel,"Subject is '$SUBJECT'"); $state = 3; $nticks = 0; } elsif ($state == 3) { if ($nticks == 6) { show_results($bot); $state = 1; } $nticks ++; } }); register_command("quiz",sub { my ($bot,$chan,$nick,$mask, @commands) = @_; if ($commands[0] eq "debug") { if ($commands[1] eq "files") { for (@FILES) { $bot->message($chan, "file: $_"); } } if ($commands[1] eq "topic") { for (@{$TOPICS{$commands[2]}}) { $bot->message($chan, "topic: $_"); } } if ($commands[1] eq "question") { my $old = $quiz_channel; $quiz_channel = $chan; get_subject($bot); show_results($bot); $quiz_channel = $old; } } if ($commands[0] eq "status") { if (defined($quiz_channel)) { $bot->message($chan,"Status from $quiz_channel"); for (keys %players) { next if $players{$_} == 0; $bot->message($chan,"$_: $players{$_}"); } } else { $bot->message($chan,"Quiz not in use"); } } if ($commands[0] eq "help") { $bot -> message($chan, "Help: todo"); } if ($commands[0] eq "start") { if (!defined($quiz_channel)) { $state = 1; $quiz_channel = $chan; register_trigger($quiz_channel, \&trigger); $bot->message ($chan, "Quiz started. To play, use '$bot->{nick}:quiz join'"); } else { $bot->message($chan, "Quiz already in use ($quiz_channel)"); } } if (defined($quiz_channel)) { if ($commands[0] eq "stop") { $state = 0; uregister_trigger($quiz_channel, \&trigger); %players = (); $quiz_channel = undef; $bot -> message($chan, "Quiz closed"); } if ($commands[0] eq "players") { for (keys %players) { $bot->message($chan, "- $_"); } } if ($commands[0] eq "leave") { delete($players{$nick}) if exists ($players{$nick}); $bot->message($chan, "$nick: done!"); } if ($commands[0] eq "join") { if (exists($players{$nick})) { $bot->message($chan, "$nick: already playing"); } else { $players{$nick} = 0; $bot->message($chan, "$nick: done!"); } } } },"Quiz: start - starts a new game, if none is already in use stop - stops current game players - show list of players leave - do not play anymore join - I want to play. Let me join! status - Who is winning?"); 1;