aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README1
-rwxr-xr-xkana-train.pl152
2 files changed, 153 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..89639ed
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+See http://www.thenautilus.net/SW/kanatrain/
diff --git a/kana-train.pl b/kana-train.pl
new file mode 100755
index 0000000..dc1d4e7
--- /dev/null
+++ b/kana-train.pl
@@ -0,0 +1,152 @@
+#!/usr/bin/perl -w
+require 5.6.0;
+use utf8;
+
+=head1 Japanese hiragana trainer
+
+This program is a little trainer for Japanese Hiragana characters.
+It needs a display that understands UTF-8 output (e.g. the xterm included
+in XFree86 4.x, or Emacs shell-mode with the unicode package).
+
+You will probably need such a display to view the source code, too.
+
+=head2 The exercises
+
+In each exercise, you are expected to give an answer. If you give an empty answer,
+the exercise will terminate.
+
+=cut
+
+# hiragana tables
+%平仮名_char = (
+ a =>'あ',i =>'い',u =>'う',e =>'え',o =>'お',
+ ka =>'か',ki =>'き',ku =>'く',ke =>'け',ko =>'こ',
+ ga =>'が',gi =>'ぎ',gu =>'ぐ',ge =>'げ',go =>'ご',
+ sa =>'さ',si =>'し',su =>'す',se =>'せ',so =>'そ',
+ za =>'ざ',zi =>'じ',zu =>'ず',ze =>'ぜ',zo =>'ぞ',
+ ta =>'た',ti =>'ち',tu =>'つ',te =>'て',to =>'と',
+ da =>'だ',di =>'ぢ',du =>'づ',de =>'で',do =>'ど',
+ na =>'な',ni =>'に',nu =>'ぬ',ne =>'ね',no =>'の',
+ ha =>'は',hi =>'ひ',hu =>'ふ',he =>'へ',ho =>'ほ',
+ ba =>'ば',bi =>'び',bu =>'ぶ',be =>'べ',bo =>'ぼ',
+ pa =>'ぱ',pi =>'ぴ',pu =>'ぷ',pe =>'ぺ',po =>'ぽ',
+ ma =>'ま',mi =>'み',mu =>'む',me =>'め',mo =>'も',
+ ya =>'や',yu =>'ゆ',yo =>'よ',
+ ra =>'ら',ri =>'り',ru =>'る',re =>'れ',ro =>'ろ',
+ wa =>'わ',wo =>'を',
+ n =>'ん',
+ );
+
+%ろまじ_norm = (
+ shi=>'si',
+ ji=>'zi',
+ chi=>'ti',tsu=>'tu',
+ fu=>'hu',
+ );
+
+# normalizes a romanization
+sub norm {
+ return $ろまじ_norm{$_[0]} if exists $ろまじ_norm{$_[0]};
+ return $_[0];
+}
+
+# compares two romanizations (OK, just test for true or false, order is the wrong one)
+sub rom_cmp {
+ my ($a,$b)=@_;
+ return norm($a) cmp norm($b);
+}
+
+=head2 The first exercise
+
+The first exercise shows a hiragana, and asks the user to write its pronunciation.
+It recognizes some romanizations, such as 'chi' for 'ti'. However, you should insert
+the Kunrei romanization ('ti', 'si', and so on).
+
+When you make a mistake, it shows you the correct pronunciation, and the hiragana corrisponding
+to what you wrote (if any).
+
+=cut
+
+# exercise 1: show a kana, ask for the pronunciation
+sub ex1 {
+ my @仮名=keys %平仮名_char;
+ my $i;my $res;my $old_flush=$|;
+
+ $|=1;
+
+ while (1) {
+ $i=int rand @仮名;
+ print "How do you pronounce $平仮名_char{$仮名[$i]}? ";
+ $res=<STDIN>;chomp $res;
+ if (!$res) {last}
+ if (!rom_cmp $res,$仮名[$i]) {
+ print "Right!\n\n";
+ } else {
+ print "Wrong, it is '$仮名[$i]'";
+ if (exists $平仮名_char{norm $res}) {
+ print ", $res is $平仮名_char{norm $res}\n\n";
+ } else {
+ print ", $res doesn't exist\n\n";
+ }
+ }
+ }
+ print "\n";
+ $|=$old_flush;
+}
+
+=head2 The second exercise
+
+The second exercise shows a pronunciation (Kunrei system) and C<$ANSWERS>
+(usually 5) choices of hiragana.
+
+When you make a mistake, it shows you the correct writing, and the pronunciation
+of the one you chose.
+
+=cut
+
+# exercise 2: show a pronunciation, ask which kana is the correct one
+sub ex2 {
+ my $ANSWERS=5;
+ my @仮名=keys %平仮名_char;
+ my ($i,$j,$k);my $res;
+ my @ans;
+
+ while (1) {
+ $i=int rand @仮名;
+ print "How do you write $仮名[$i]?\n";
+ @ans=();
+ for ($j=0;$j<$ANSWERS;$j++) {
+ $k=-1;
+ while ($k<0 || $k==$i) {
+ $k=int rand @仮名;
+ for (@ans) {if ($_ == $k) {$k=-1;last}}
+ }
+ push @ans,$k;
+ }
+ $ans[int rand $ANSWERS]=$i;
+ $j=1;for (@ans) { print "$j: $平仮名_char{$仮名[$_]} ";$j++ };print "\n";
+ $res=0;
+ while (($res<1) or ($res>$ANSWERS)) {
+ $res=<STDIN>;chomp $res;
+ if (!$res) {last}
+ if (($res<1) or ($res>$ANSWERS)) {print "Answer with a number between 1 and $ANSWERS\n"}
+ }
+ if (!$res) {last}
+ if ($ans[$res-1] == $i) {
+ print "Right!\n\n";
+ } else {
+ print "Wrong, it is $平仮名_char{$仮名[$i]}, $平仮名_char{$仮名[$ans[$res-1]]} is $仮名[$ans[$res-1]].\n\n";
+ }
+ }
+}
+
+=head2 Command-line
+
+C<-1> will run only the first exercise.
+C<-2> will run only the second exercise.
+Default is to run them is sequence.
+
+=cut
+
+ex1() unless $ARGV[0] && $ARGV[0] eq '-2';
+ex2() unless $ARGV[0] && $ARGV[0] eq '-1';