aboutsummaryrefslogtreecommitdiff
path: root/kana-train.pl
blob: dc1d4e74be374010603b0455c89b384f102a2d81 (plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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 = (
=>'',=>'',=>'',=>'',=>'',
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 =>'',
=>'',
       );
 
%ろまじ_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($acmp 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';