Source Code
#!/usr/bin/perl
# Kanji tester app
use v5.16;
use Tk;
use utf8;
use List::Util qw(shuffle);
require Tk::LabEntry;
#### create a Tk main window
my $MW = MainWindow->new;
$MW->title("Kanji Tester");
$MW->geometry("580x370+20+20");
#### read in the kanjis
my @kanjis;
while ( my $line = <DATA> ) {
chomp($line);
my ($kanji, $eigo) = split(/,/, $line);
push @kanjis, [$kanji, $eigo];
}
say "There are " . scalar(@kanjis) . " kanji in the database.";
# randomize the kanjis
my @kanji_rand = shuffle @kanjis;
#### variables
# for kanji
my $kanji_text = q{};
my $kanji_eigo = q{};
# for scoring
my $score = 0;
my $total = 30;
my $count = 1;
my $score_text;
# for entry box
my $entry_text = q{};
#### create TK user interface
# Kanji display label
my $label = $MW->Label(
-textvariable => \$kanji_text,
-relief => 'flat',
-padx => 20,
-pady => 20,
-font => [ -size => 72 ],
)->pack;
my $score_label = $MW->Label(
-textvariable => \$score_text,
-font => [ -size => 24 ],
)->pack;
my $labentry_box = $MW->LabEntry(
-label => "Enter guess: ",
-labelPack => [ -side => 'left', -anchor => 'w' ],
-labelFont => [ -size => 18 ],
-textvariable => \$entry_text,
-font => [ -size => 18 ],
)->pack( -expand => 1, -fill => 'x' );
# 'next' button
my $next = $MW->Button(
-text => 'Check Kanji',
-font => [ -size => 18 ],
-command => \&check_kanji,
)->pack( -expand => 1, -fill => 'both' );
# 'restart' button
my $restart = $MW->Button(
-text => 'Restart Quiz',
-font => [ -size => 18 ],
-command => sub { $score = 0;
$total = 10;
$count = 1;
$entry_text = q{};
next_kanji();
get_score();
},
)->pack( -expand => 1, -fill => 'both' );
# 'exit' button
my $exit = $MW->Button(
-text => 'Exit',
-font => [ -size => 18 ],
-command => sub { say "Exiting..."; exit; },
)->pack( -expand => 1, -fill => 'both' );
#### Initialise and main loop
next_kanji();
get_score();
MainLoop; # the TK gui main loop
exit;
END {
say "Your final score is $score out of $total";
}
sub next_kanji {
my $ar_ref = pop @kanji_rand; # get the next Kanji
$kanji_text = $count . ": " . $ar_ref->[0]; # display with the current question number
$kanji_eigo = $ar_ref->[1]; # also store the English meaning
}
sub check_kanji {
if ( length($entry_text) && # only check the user's guess if text is entered
($count <= $total) && # while still asking questions
scalar(@kanji_rand) # make sure there's Kanji left in the list
) {
# increase score if correct and ask next Kanji
$score++ if $kanji_eigo =~ /$entry_text/i; # sometimes a Kanji has several meanings,
say $entry_text, "\t-\t", $kanji_eigo; # so be nice to the user
$count++;
next_kanji() if $count <= $total;
$entry_text = q{};
get_score();
}
}
sub get_score {
$score_text = ($count > $total ? "Final" : "Current");
$score_text .= " score: $score out of $total";
}
# Kanji database - add Kanjis here
__DATA__
一,one
一人,one person
一日目,the first day
二,two
三,three
三月,march
四,four
五,five
六,six
七,seven
八,eight
九,nine
十,ten
千,thousand
人,person
人口,population
入,enter
入口,entrance
力,power
力土,sumo wrestler
上,top
上手,skillful
下,low
下手,unskillful/awkward
大,big
小,small
小犬,puppy
口,mouth
山,mountain
子,child
女,woman
女子,woman/women's
夕,evening
夕力,evening
川,river
川上,upstream
土,earth
円,round/yen
王,king
火,fire
火山,volcano
月,month/moon
犬,dog
手,hand
水,water
中,centre/China
日,sun/day/Japan
日本,Japan
天,heaven
天下,the whole world
文,writing
木,tree/wood
右,right
右手,right hand
左,left
左右,left and right
玉,jewel/jade/ball
玉子,egg
出,emerge/go out/send
出口,exit
正,right/correct
正月,new year's
生,life/birth/grow/student
石,stone
田,rice field/paddy
本,book/true/real
目,eye
目玉,eyeball
目上,one's superior