package BSD Quiz use strict use Carp qw carp cluck confess use constan

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package BSD::Quiz;
use strict;
use Carp qw(carp cluck confess);
use constant {
READING => 0,
EOL => 1,
};
our $VERSION = '0.2';
sub new {
my $class = shift;
my $self = bless {
FILE => undef,
PROMPT => undef || '=> ',
QUESTIONS => undef,
@_
}, $class;
confess 'Определитесь'
if defined $self->{FILE} && defined $self->{QUESTIONS};
return $self;
}
sub prompt {
my ( $self, $prompt ) = @_;
confess 'Не задан prompt' unless $prompt;
$self->{PROMPT} = $prompt;
return $self->{PROMPT};
}
sub get_question {
my $self = shift;
# Если не заполнен массив вопросов
unless ( defined $self->{QUESTIONS} ) {
my $state = READING;
my $line = '';
my @question;
open Q, $self->{FILE}
or cluck 'Ошибка при открытии файла';
while (<Q>) {
chomp;
s/^\s+//go;
s/\s+$//go;
next if m/^$/ or m/^#/;
(s/\\$//o) ? $state = READING : $state = EOL;
$line .= $_;
if ( $state == READING ) {
next;
}
else {
push @{ $self->{QUESTIONS} }, $line;
$line = '';
}
}
close Q;
}
my $total = scalar @{ $self->{QUESTIONS} };
my $correct = 0;
my $guesses = 0;
my $num = 1;
my $answer = 0;
my $giveup = 0;
my ( $question, $hint, $re );
foreach (@{ $self->{QUESTIONS} }) {
# question TAB regex [TAB hint]
unless ( ( $question, $re, $hint ) = (m/^(.*?)\t(.*?)(?:\t(.*))?$/) ) {
print STDERR "format error near '$_'\n";
next;
}
print $num++, '/', $total, '. ', $question, "?\n";
print $self->{ PROMPT };
my $input = <>;
last unless $input;
chomp $input;
while (!( $giveup = $input =~ m/^$/ )
&& !( $answer = $input =~ m/^$re$/ ) )
{
print 'What?', "\n";
$guesses++;
print $self->{ PROMPT };
$input = <>;
chomp $input;
}
if ($giveup) {
print $hint || $re, "\n";
$giveup = 0;
}
elsif ($answer) {
$correct++;
$answer = 0;
}
}
my $score = int( $correct / ( $total + $guesses ) * 100 );
print 'Rights ', $correct, ', wrongs ', $total - $correct, ', guesses ',
$guesses, ', score ', $score, "%\n";
}
1;