language_cards 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +49 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/language_cards +8 -0
- data/bin/setup +8 -0
- data/cards/japanese-katakana-hiragana.yml +460 -0
- data/language_cards.gemspec +29 -0
- data/lib/language_cards/card_collection.rb +97 -0
- data/lib/language_cards/comp_bitz.rb +12 -0
- data/lib/language_cards/comparator.rb +61 -0
- data/lib/language_cards/language_cards.rb +18 -0
- data/lib/language_cards/mapping.rb +55 -0
- data/lib/language_cards/user_interface.rb +109 -0
- data/lib/language_cards/version.rb +3 -0
- data/lib/language_cards.rb +39 -0
- data/locales/en.yml +27 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6f7f8621d542935a3fd0ef4a0f3443adb400b770
|
4
|
+
data.tar.gz: c3e5c5271866b9b2ccc29715db06459847a27a86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: efa78c38cbf83cccef29b98897b2b2434f2c777d09b7b95850c2cc78bd663b85bbec2b3c7d27926c50b560014ad206bb3e4c1d4394d2ea3c30e50596ec296f68
|
7
|
+
data.tar.gz: 263f886122db25b28b0919d01d0bdb5fc451a584219788a46015a21c10bad4c09131c405dd623d6d16c5eea523d4db8cdf359295ee071879db7cf4814ef38211
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Daniel P. Clark
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# LanguageCards
|
2
|
+
|
3
|
+
This is a flash card game for guessing translations or keyboard learning. Currently implemented is
|
4
|
+
English Romaji to Japanese Hirigana/Katakana and typing exercises for each. Game experience will be improved upon!
|
5
|
+
|
6
|
+
Also if your interested in adding other flash cards for language learning, pull requests are welcome. Please
|
7
|
+
keep some sort of organized collection for sets of cards (for instance the Japanese-Language Proficiency Test
|
8
|
+
has different levels to complete, N1 through N5, which would each count as a collection).
|
9
|
+
|
10
|
+
Internationalization support is built in! Translators are welcome to make this game available in other languages.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'language_cards'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install language_cards
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
After installing the gem you can run the executable `language_cards`. If you clone the repo then use
|
31
|
+
`bin/language_cards`.
|
32
|
+
|
33
|
+
## Development
|
34
|
+
|
35
|
+
*Tests required moving forward with this project unless it's translation files.*
|
36
|
+
|
37
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
38
|
+
|
39
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/danielpclark/language_cards.
|
44
|
+
|
45
|
+
|
46
|
+
## License
|
47
|
+
|
48
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
49
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "language_cards"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/language_cards
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,460 @@
|
|
1
|
+
---
|
2
|
+
Japanese:
|
3
|
+
Katakana:
|
4
|
+
mapping:
|
5
|
+
- Romaji: Katakana
|
6
|
+
index:
|
7
|
+
- :k
|
8
|
+
- :v
|
9
|
+
- Katakana: Katakana
|
10
|
+
index:
|
11
|
+
- :v
|
12
|
+
- :v
|
13
|
+
a: ア
|
14
|
+
i: イ
|
15
|
+
u: ウ
|
16
|
+
e: エ
|
17
|
+
o: オ
|
18
|
+
"-": ー
|
19
|
+
xa: ァ
|
20
|
+
xi: ィ
|
21
|
+
xu: ゥ
|
22
|
+
xe: ェ
|
23
|
+
xo: ォ
|
24
|
+
ka: カ
|
25
|
+
ki: キ
|
26
|
+
ku: ク
|
27
|
+
ke: ケ
|
28
|
+
ko: コ
|
29
|
+
ca: カ
|
30
|
+
cu: ク
|
31
|
+
co: コ
|
32
|
+
ga: ガ
|
33
|
+
gi: ギ
|
34
|
+
gu: グ
|
35
|
+
ge: ゲ
|
36
|
+
go: ゴ
|
37
|
+
sa: サ
|
38
|
+
si: シ
|
39
|
+
su: ス
|
40
|
+
se: セ
|
41
|
+
so: ソ
|
42
|
+
za: ザ
|
43
|
+
zi: ジ
|
44
|
+
zu: ズ
|
45
|
+
ze: ゼ
|
46
|
+
zo: ゾ
|
47
|
+
ja: ジャ
|
48
|
+
ji: ジ
|
49
|
+
ju: ジュ
|
50
|
+
je: ジェ
|
51
|
+
jo: ジョ
|
52
|
+
ta: タ
|
53
|
+
ti: チ
|
54
|
+
tu: ツ
|
55
|
+
te: テ
|
56
|
+
to: ト
|
57
|
+
da: ダ
|
58
|
+
di: ヂ
|
59
|
+
du: ヅ
|
60
|
+
de: デ
|
61
|
+
do: ド
|
62
|
+
na: ナ
|
63
|
+
ni: ニ
|
64
|
+
nu: ヌ
|
65
|
+
ne: ネ
|
66
|
+
'no': ノ
|
67
|
+
ha: ハ
|
68
|
+
hi: ヒ
|
69
|
+
hu: フ
|
70
|
+
he: ヘ
|
71
|
+
ho: ホ
|
72
|
+
ba: バ
|
73
|
+
bi: ビ
|
74
|
+
bu: ブ
|
75
|
+
be: ベ
|
76
|
+
bo: ボ
|
77
|
+
pa: パ
|
78
|
+
pi: ピ
|
79
|
+
pu: プ
|
80
|
+
pe: ペ
|
81
|
+
po: ポ
|
82
|
+
va: ヴァ
|
83
|
+
vi: ヴィ
|
84
|
+
vu: ヴ
|
85
|
+
ve: ヴェ
|
86
|
+
vo: ヴォ
|
87
|
+
fa: ファ
|
88
|
+
fi: フィ
|
89
|
+
fu: フ
|
90
|
+
fe: フェ
|
91
|
+
fo: フォ
|
92
|
+
ma: マ
|
93
|
+
mi: ミ
|
94
|
+
mu: ム
|
95
|
+
me: メ
|
96
|
+
mo: モ
|
97
|
+
ya: ヤ
|
98
|
+
yi: イ
|
99
|
+
yu: ユ
|
100
|
+
ye: イェ
|
101
|
+
yo: ヨ
|
102
|
+
ra: ラ
|
103
|
+
ri: リ
|
104
|
+
ru: ル
|
105
|
+
re: レ
|
106
|
+
ro: ロ
|
107
|
+
la: ラ
|
108
|
+
li: リ
|
109
|
+
lu: ル
|
110
|
+
le: レ
|
111
|
+
lo: ロ
|
112
|
+
wa: ワ
|
113
|
+
wi: ウィ
|
114
|
+
wu: ウ
|
115
|
+
we: ウェ
|
116
|
+
wo: ヲ
|
117
|
+
nn: ン
|
118
|
+
n: ン
|
119
|
+
tsu: ツ
|
120
|
+
xka: ヵ
|
121
|
+
xke: ヶ
|
122
|
+
xwa: ヮ
|
123
|
+
xtsu: ッ
|
124
|
+
xya: ャ
|
125
|
+
xyu: ュ
|
126
|
+
xyo: ョ
|
127
|
+
kya: キャ
|
128
|
+
kyi: キィ
|
129
|
+
kyu: キュ
|
130
|
+
kye: キェ
|
131
|
+
kyo: キョ
|
132
|
+
gya: ギャ
|
133
|
+
gyi: ギィ
|
134
|
+
gyu: ギュ
|
135
|
+
gye: ギェ
|
136
|
+
gyo: ギョ
|
137
|
+
sya: シャ
|
138
|
+
syi: シィ
|
139
|
+
syu: シュ
|
140
|
+
sye: シェ
|
141
|
+
syo: ショ
|
142
|
+
sha: シャ
|
143
|
+
shi: シ
|
144
|
+
shu: シュ
|
145
|
+
she: シェ
|
146
|
+
sho: ショ
|
147
|
+
zya: ジャ
|
148
|
+
zyi: ジィ
|
149
|
+
zyu: ジュ
|
150
|
+
zye: ジェ
|
151
|
+
zyo: ジョ
|
152
|
+
jya: ジャ
|
153
|
+
jyi: ジィ
|
154
|
+
jyu: ジュ
|
155
|
+
jye: ジェ
|
156
|
+
jyo: ジョ
|
157
|
+
tya: チャ
|
158
|
+
tyi: チィ
|
159
|
+
tyu: チュ
|
160
|
+
tye: チェ
|
161
|
+
tyo: チョ
|
162
|
+
twa: トァ
|
163
|
+
twi: トィ
|
164
|
+
twu: トゥ
|
165
|
+
twe: トェ
|
166
|
+
two: トォ
|
167
|
+
dwa: ドァ
|
168
|
+
dwi: ドィ
|
169
|
+
dwu: ドゥ
|
170
|
+
dwe: ドェ
|
171
|
+
dwo: ドォ
|
172
|
+
cya: チャ
|
173
|
+
cyi: チィ
|
174
|
+
cyu: チュ
|
175
|
+
cye: チェ
|
176
|
+
cyo: チョ
|
177
|
+
cha: チャ
|
178
|
+
chi: チ
|
179
|
+
chu: チュ
|
180
|
+
che: チェ
|
181
|
+
cho: チョ
|
182
|
+
tha: テャ
|
183
|
+
thi: ティ
|
184
|
+
thu: テュ
|
185
|
+
the: テェ
|
186
|
+
tho: テョ
|
187
|
+
dya: ヂャ
|
188
|
+
dyi: ヂィ
|
189
|
+
dyu: ヂュ
|
190
|
+
dye: ヂェ
|
191
|
+
dyo: ヂョ
|
192
|
+
dha: デャ
|
193
|
+
dhi: ディ
|
194
|
+
dhu: デュ
|
195
|
+
dhe: デェ
|
196
|
+
dho: デョ
|
197
|
+
nya: ニャ
|
198
|
+
nyi: ニィ
|
199
|
+
nyu: ニュ
|
200
|
+
nye: ニェ
|
201
|
+
nyo: ニョ
|
202
|
+
hya: ヒャ
|
203
|
+
hyi: ヒィ
|
204
|
+
hyu: ヒュ
|
205
|
+
hye: ヒェ
|
206
|
+
hyo: ヒョ
|
207
|
+
bya: ビャ
|
208
|
+
byi: ビィ
|
209
|
+
byu: ビュ
|
210
|
+
bye: ビェ
|
211
|
+
byo: ビョ
|
212
|
+
pya: ピャ
|
213
|
+
pyi: ピィ
|
214
|
+
pyu: ピュ
|
215
|
+
pye: ピェ
|
216
|
+
pyo: ピョ
|
217
|
+
mya: ミャ
|
218
|
+
myi: ミィ
|
219
|
+
myu: ミュ
|
220
|
+
mye: ミェ
|
221
|
+
myo: ミョ
|
222
|
+
rya: リャ
|
223
|
+
ryi: リィ
|
224
|
+
ryu: リュ
|
225
|
+
rye: リェ
|
226
|
+
ryo: リョ
|
227
|
+
lya: リャ
|
228
|
+
lyi: リィ
|
229
|
+
lyu: リュ
|
230
|
+
lye: リェ
|
231
|
+
lyo: リョ
|
232
|
+
Hiragana:
|
233
|
+
mapping:
|
234
|
+
- Romaji: Hiragana
|
235
|
+
index:
|
236
|
+
- :k
|
237
|
+
- :v
|
238
|
+
- Hiragana: Hiragana
|
239
|
+
index:
|
240
|
+
- :v
|
241
|
+
- :v
|
242
|
+
a: あ
|
243
|
+
i: い
|
244
|
+
u: う
|
245
|
+
e: え
|
246
|
+
o: お
|
247
|
+
# "-":
|
248
|
+
# xa:
|
249
|
+
# xi:
|
250
|
+
# xu:
|
251
|
+
# xe:
|
252
|
+
# xo:
|
253
|
+
ka: か
|
254
|
+
ki: き
|
255
|
+
ku: く
|
256
|
+
ke: け
|
257
|
+
ko: こ
|
258
|
+
# ca:
|
259
|
+
# cu:
|
260
|
+
# co:
|
261
|
+
ga: が
|
262
|
+
gi: ぎ
|
263
|
+
gu: ぐ
|
264
|
+
ge: げ
|
265
|
+
go: ご
|
266
|
+
sa: さ
|
267
|
+
# si:
|
268
|
+
su: す
|
269
|
+
se: せ
|
270
|
+
so: そ
|
271
|
+
za: ざ
|
272
|
+
# zi:
|
273
|
+
zu: ず
|
274
|
+
ze: ぜ
|
275
|
+
zo: ぞ
|
276
|
+
ja: じゃ
|
277
|
+
ji: じ
|
278
|
+
ju: じゅ
|
279
|
+
# je:
|
280
|
+
jo: じょ
|
281
|
+
ta: た
|
282
|
+
# ti:
|
283
|
+
# tu:
|
284
|
+
te: て
|
285
|
+
to: と
|
286
|
+
da: だ
|
287
|
+
di: ぢ
|
288
|
+
du: づ
|
289
|
+
de: で
|
290
|
+
do: ど
|
291
|
+
na: な
|
292
|
+
ni: に
|
293
|
+
nu: ぬ
|
294
|
+
ne: ね
|
295
|
+
'no': の
|
296
|
+
ha: は
|
297
|
+
hi: ひ
|
298
|
+
# hu:
|
299
|
+
he: へ
|
300
|
+
ho: ほ
|
301
|
+
ba: ば
|
302
|
+
bi: び
|
303
|
+
bu: ぶ
|
304
|
+
be: べ
|
305
|
+
bo: ぼ
|
306
|
+
pa: ぱ
|
307
|
+
pi: ぴ
|
308
|
+
pu: ぷ
|
309
|
+
pe: ぺ
|
310
|
+
po: ぽ
|
311
|
+
# va:
|
312
|
+
# vi:
|
313
|
+
# vu:
|
314
|
+
# ve:
|
315
|
+
# vo:
|
316
|
+
# fa:
|
317
|
+
# fi:
|
318
|
+
fu: ふ
|
319
|
+
# fe:
|
320
|
+
# fo:
|
321
|
+
ma: ま
|
322
|
+
mi: み
|
323
|
+
mu: む
|
324
|
+
me: め
|
325
|
+
mo: も
|
326
|
+
ya: や
|
327
|
+
# yi:
|
328
|
+
yu: ゆ
|
329
|
+
# ye:
|
330
|
+
yo: よ
|
331
|
+
ra: ら
|
332
|
+
ri: り
|
333
|
+
ru: る
|
334
|
+
re: れ
|
335
|
+
ro: ろ
|
336
|
+
# la:
|
337
|
+
# li:
|
338
|
+
# lu:
|
339
|
+
# le:
|
340
|
+
# lo:
|
341
|
+
wa: わ
|
342
|
+
# wi:
|
343
|
+
# wu:
|
344
|
+
# we:
|
345
|
+
wo: を
|
346
|
+
# nn:
|
347
|
+
n: ん
|
348
|
+
tsu: つ
|
349
|
+
# xka:
|
350
|
+
# xke:
|
351
|
+
# xwa:
|
352
|
+
# xtsu:
|
353
|
+
# xya:
|
354
|
+
# xyu:
|
355
|
+
# xyo:
|
356
|
+
kya: きゃ
|
357
|
+
# kyi:
|
358
|
+
kyu: きゅ
|
359
|
+
# kye:
|
360
|
+
kyo: きょ
|
361
|
+
gya: ぎゃ
|
362
|
+
# gyi:
|
363
|
+
gyu: ぎゅ
|
364
|
+
# gye:
|
365
|
+
gyo: ぎょ
|
366
|
+
# sya:
|
367
|
+
# syi:
|
368
|
+
# syu:
|
369
|
+
# sye:
|
370
|
+
# syo:
|
371
|
+
sha: しゃ
|
372
|
+
shi: し
|
373
|
+
shu: しゅ
|
374
|
+
# she:
|
375
|
+
sho: しょ
|
376
|
+
# zya:
|
377
|
+
# zyi:
|
378
|
+
# zyu:
|
379
|
+
# zye:
|
380
|
+
# zyo:
|
381
|
+
# jya:
|
382
|
+
# jyi:
|
383
|
+
# jyu:
|
384
|
+
# jye:
|
385
|
+
# jyo:
|
386
|
+
# tya:
|
387
|
+
# tyi:
|
388
|
+
# tyu:
|
389
|
+
# tye:
|
390
|
+
# tyo:
|
391
|
+
# twa:
|
392
|
+
# twi:
|
393
|
+
# twu:
|
394
|
+
# twe:
|
395
|
+
# two:
|
396
|
+
# dwa:
|
397
|
+
# dwi:
|
398
|
+
# dwu:
|
399
|
+
# dwe:
|
400
|
+
# dwo:
|
401
|
+
# cya:
|
402
|
+
# cyi:
|
403
|
+
# cyu:
|
404
|
+
# cye:
|
405
|
+
# cyo:
|
406
|
+
cha: ちゃ
|
407
|
+
chi: ち
|
408
|
+
chu: ちゅ
|
409
|
+
# che:
|
410
|
+
cho: ちょ
|
411
|
+
# tha:
|
412
|
+
# thi:
|
413
|
+
# thu:
|
414
|
+
# the:
|
415
|
+
# tho:
|
416
|
+
# dya:
|
417
|
+
# dyi:
|
418
|
+
# dyu:
|
419
|
+
# dye:
|
420
|
+
# dyo:
|
421
|
+
# dha:
|
422
|
+
# dhi:
|
423
|
+
# dhu:
|
424
|
+
# dhe:
|
425
|
+
# dho:
|
426
|
+
nya: にゃ
|
427
|
+
# nyi:
|
428
|
+
nyu: にゅ
|
429
|
+
# nye:
|
430
|
+
nyo: にょ
|
431
|
+
hya: ひゃ
|
432
|
+
# hyi:
|
433
|
+
hyu: ひゅ
|
434
|
+
# hye:
|
435
|
+
hyo: ひょ
|
436
|
+
bya: びゃ
|
437
|
+
# byi:
|
438
|
+
byu: びゅ
|
439
|
+
# bye:
|
440
|
+
byo: びょ
|
441
|
+
pya: ぴゃ
|
442
|
+
# pyi:
|
443
|
+
pyu: ぴゅ
|
444
|
+
# pye:
|
445
|
+
pyo: ぴょ
|
446
|
+
mya: みゃ
|
447
|
+
# myi:
|
448
|
+
myu: みゅ
|
449
|
+
# mye:
|
450
|
+
myo: みょ
|
451
|
+
rya: りゃ
|
452
|
+
# ryi:
|
453
|
+
ryu: りゅ
|
454
|
+
# rye:
|
455
|
+
ryo: りょ
|
456
|
+
# lya:
|
457
|
+
# lyi:
|
458
|
+
# lyu:
|
459
|
+
# lye:
|
460
|
+
# lyo:
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'language_cards/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "language_cards"
|
8
|
+
spec.version = LanguageCards::VERSION
|
9
|
+
spec.authors = ["Daniel P. Clark"]
|
10
|
+
spec.email = ["6ftdan@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Flashcard game for language learning.}
|
13
|
+
spec.description = %q{Flashcard game for language learning. Make your own cards or translations as well.}
|
14
|
+
spec.homepage = "http://github.com/danielpclark/language_cards"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
|
21
|
+
spec.executables = ['language_cards']
|
22
|
+
spec.require_paths = ["lib","cards"]
|
23
|
+
|
24
|
+
spec.add_dependency "highline", "~> 1.7"
|
25
|
+
spec.add_dependency "i18n", "~> 0.7"
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
27
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.10"
|
29
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative 'comparator'
|
2
|
+
require_relative 'mapping'
|
3
|
+
|
4
|
+
module LanguageCards
|
5
|
+
class CardCollection
|
6
|
+
attr_reader :name
|
7
|
+
##
|
8
|
+
# RULE: Always compare by value regardless of key value ordering in mapping.
|
9
|
+
# (This allows for duplicate spellings of the same character translation)
|
10
|
+
def initialize hsh, name=nil
|
11
|
+
@hsh = hsh
|
12
|
+
@name = I18n.t "LanguageName.#{name}" if name
|
13
|
+
send :_build
|
14
|
+
@mappings = @hsh["mapping"]
|
15
|
+
if @mappings
|
16
|
+
@cards = @hsh.select {|k,v| !v.is_a? Mappings}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Recursively build class course names
|
22
|
+
def classes s=nil
|
23
|
+
s = @name.nil? ? nil : [s, @name].compact.join(JOIN)
|
24
|
+
@hsh.select do |k,v|
|
25
|
+
[CardCollection, Mappings].include? v.class
|
26
|
+
end.flat_map do |k,v|
|
27
|
+
v.send :classes, s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](value)
|
32
|
+
raise EmptyCollection unless collection?
|
33
|
+
@cards[value]
|
34
|
+
end
|
35
|
+
|
36
|
+
def rand
|
37
|
+
raise EmptyCollection unless collection?
|
38
|
+
v = @cards.keys.sample
|
39
|
+
@comparator.given(v, @cards[v])
|
40
|
+
end
|
41
|
+
|
42
|
+
def correct? input, comp_bitz
|
43
|
+
raise EmptyCollection unless collection?
|
44
|
+
@comparator.match? input, comp_bitz
|
45
|
+
end
|
46
|
+
|
47
|
+
def mapped_as
|
48
|
+
raise EmptyCollection unless collection?
|
49
|
+
@comparator.mapped_as
|
50
|
+
end
|
51
|
+
|
52
|
+
def children
|
53
|
+
@hsh.select {|k,v| v.is_a? CardCollection}.values.map do |cc|
|
54
|
+
{cc.name => cc}
|
55
|
+
end.inject(:merge)
|
56
|
+
end
|
57
|
+
|
58
|
+
def select_collection string
|
59
|
+
first, tail = string.split(JOIN, 2)
|
60
|
+
if collection?
|
61
|
+
@comparator = @mappings.select_mapping(first)
|
62
|
+
return self
|
63
|
+
else
|
64
|
+
children[first].select_collection tail
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def collection?
|
69
|
+
!!@cards
|
70
|
+
end
|
71
|
+
|
72
|
+
def cards
|
73
|
+
@cards || raise(I18n.t 'Errors.UpperCollection')
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
##
|
78
|
+
# Replace respective raw ruby object with our objects
|
79
|
+
def _build
|
80
|
+
if @hsh.has_key? "mapping"
|
81
|
+
@hsh["mapping"] = Mappings.new(@hsh["mapping"], self)
|
82
|
+
else
|
83
|
+
@hsh.tap do |h|
|
84
|
+
h.select {|k,v| v.is_a? Hash }.each do |k,v|
|
85
|
+
h[k] = self.class.new(v, k)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class EmptyCollection < StandardError
|
92
|
+
def initialize
|
93
|
+
super(I18n.t 'Errors.EmptyCollection')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LanguageCards
|
2
|
+
class CompBitz
|
3
|
+
attr_reader :display, :collection, :value, :mapping, :expected
|
4
|
+
def initialize options
|
5
|
+
@display = options.fetch(:display)
|
6
|
+
@collection = options.fetch(:collection)
|
7
|
+
@expected = options.fetch(:expected)
|
8
|
+
@value = options.fetch(:value)
|
9
|
+
@mapping = options.fetch(:mapping)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative 'comp_bitz'
|
2
|
+
|
3
|
+
module LanguageCards
|
4
|
+
class Comparator
|
5
|
+
def initialize mapping_key, mapping, collection
|
6
|
+
##
|
7
|
+
# @title should be a hash like {"Romaji"=>"Katakana"}
|
8
|
+
# @mapping should be an array like [:k, :v]
|
9
|
+
@mapped_as, @mapping = mapping[mapping_key].reduce
|
10
|
+
@collection = collection
|
11
|
+
end
|
12
|
+
|
13
|
+
def mapped_as
|
14
|
+
case @mapping.first
|
15
|
+
when :k
|
16
|
+
@mapped_as.keys
|
17
|
+
else
|
18
|
+
@mapped_as.values
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def given key, value
|
23
|
+
CompBitz.new(
|
24
|
+
display: choose_display(key, value),
|
25
|
+
collection: @collection,
|
26
|
+
expected: choose_expected(key, value),
|
27
|
+
value: value,
|
28
|
+
mapping: @mapping.first
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def match? input, comp_bitz
|
33
|
+
case comp_bitz.mapping
|
34
|
+
when :k
|
35
|
+
comp_bitz.value == comp_bitz.collection[input]
|
36
|
+
when :v
|
37
|
+
comp_bitz.value == input
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def choose_display key, value
|
43
|
+
case @mapping.last
|
44
|
+
when :k
|
45
|
+
key
|
46
|
+
when :v
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def choose_expected key, value
|
52
|
+
case @mapping.first
|
53
|
+
when :k
|
54
|
+
key
|
55
|
+
when :v
|
56
|
+
value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'card_collection'
|
2
|
+
require_relative 'user_interface'
|
3
|
+
|
4
|
+
module LanguageCards
|
5
|
+
class LanguageCards
|
6
|
+
def initialize
|
7
|
+
@CARDS = {}
|
8
|
+
Dir[File.join 'cards', '*.yml'].each do |c|
|
9
|
+
@CARDS.merge!(YAML.load(File.open(c).read))
|
10
|
+
end
|
11
|
+
@CARDS = CardCollection.new @CARDS
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
UserInterface.new.start(@CARDS)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module LanguageCards
|
2
|
+
class Mappings
|
3
|
+
def initialize mapping, collection=nil
|
4
|
+
@collection = collection
|
5
|
+
@mappings = {}
|
6
|
+
mapping.each do |h|
|
7
|
+
index = h.delete("index")
|
8
|
+
begin
|
9
|
+
a,b = h.reduce
|
10
|
+
rescue LocalJumpError
|
11
|
+
raise InvalidMapping
|
12
|
+
end
|
13
|
+
a = I18n.t "LanguageName.#{a}"
|
14
|
+
b = I18n.t "LanguageName.#{b}"
|
15
|
+
|
16
|
+
@mappings["#{a} => #{b}"] = {
|
17
|
+
h => index
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def select_mapping string
|
23
|
+
Comparator.new string, self, @collection
|
24
|
+
end
|
25
|
+
|
26
|
+
def classes s=nil
|
27
|
+
keys.map do |names|
|
28
|
+
[s, names].compact.join(JOIN)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def [] key
|
33
|
+
@mappings[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def order key # what was my intention in design here?
|
37
|
+
self[key].values.flatten
|
38
|
+
end
|
39
|
+
|
40
|
+
def keys
|
41
|
+
@mappings.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
@mappings.keys
|
46
|
+
end
|
47
|
+
|
48
|
+
class InvalidMapping < StandardError
|
49
|
+
def initialize
|
50
|
+
super(I18n.t 'Errors.InvalidMapping')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module LanguageCards
|
4
|
+
class UserInterface
|
5
|
+
def main_menu(courses:)
|
6
|
+
title = I18n.t 'Menu.Title'
|
7
|
+
<<-MAINMENU
|
8
|
+
#{'~' * SUBMENUWIDTH}
|
9
|
+
#{title}#{('v' + VERSION).rjust(SUBMENUWIDTH - title.length)}
|
10
|
+
#{'~' * SUBMENUWIDTH}
|
11
|
+
|
12
|
+
Select an option:
|
13
|
+
|
14
|
+
#{ courses.each.with_index.map {|item,index| "#{index + 1}: #{item}\n" }.join.chop }
|
15
|
+
#{I18n.t 'Menu.Exit'}
|
16
|
+
|
17
|
+
#{'~' * SUBMENUWIDTH}
|
18
|
+
MAINMENU
|
19
|
+
end
|
20
|
+
|
21
|
+
def score_menu(correct:, incorrect:)
|
22
|
+
score = "#{I18n.t 'Game.ScoreMenu.Score'}: #{correct.to_i} #{I18n.t 'Game.ScoreMenu.OutOf'} #{correct.to_i + incorrect.to_i}"
|
23
|
+
<<-SCOREMENU
|
24
|
+
#{'~' * SUBMENUWIDTH}
|
25
|
+
#{score + I18n.t('Menu.Exit').rjust(SUBMENUWIDTH - score.length)}
|
26
|
+
#{@last}
|
27
|
+
#{'~' * SUBMENUWIDTH}
|
28
|
+
SCOREMENU
|
29
|
+
end
|
30
|
+
|
31
|
+
def start(cards)
|
32
|
+
clear
|
33
|
+
|
34
|
+
CLI.say SPLASH_SCREEN
|
35
|
+
sleep 2
|
36
|
+
|
37
|
+
begin
|
38
|
+
loop do
|
39
|
+
clear
|
40
|
+
|
41
|
+
CLI.say main_menu(courses: cards.classes)
|
42
|
+
value = CLI.ask("").to_i - 1
|
43
|
+
courses = cards.classes
|
44
|
+
if (0..courses.length-1).include? value
|
45
|
+
collection = cards.select_collection(courses[value])
|
46
|
+
begin
|
47
|
+
loop do
|
48
|
+
clear
|
49
|
+
CLI.say score_menu(correct: @correct, incorrect: @incorrect)
|
50
|
+
comp_bitz = collection.rand
|
51
|
+
input = CLI.ask("#{I18n.t('Game.TypeThis')} #{collection.mapped_as.first}: #{comp_bitz.display}")
|
52
|
+
if collection.correct? input, comp_bitz
|
53
|
+
@correct = @correct.to_i + 1
|
54
|
+
@last = [
|
55
|
+
I18n.t('Game.Correct'),
|
56
|
+
"#{input} = #{comp_bitz.display}"
|
57
|
+
].join(" ")
|
58
|
+
else
|
59
|
+
@incorrect = @incorrect.to_i + 1
|
60
|
+
@last = [
|
61
|
+
I18n.t('Game.Incorrect'),
|
62
|
+
"#{input} != #{comp_bitz.display}",
|
63
|
+
I18n.t('Game.Its'),
|
64
|
+
"#{comp_bitz.expected}"
|
65
|
+
].join(" ")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue SystemExit, Interrupt
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
rescue SystemExit, Interrupt
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def clear
|
79
|
+
printf CLEAR
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
SPLASH_SCREEN = %q(
|
86
|
+
_ _ __ _ ____ _ _ _ ____ _______
|
87
|
+
| | / \ | \ | | / __ \ | | | | / \ / __ \ | _____|
|
88
|
+
| | / _ \ | \ | | / / \_\ | | | | / _ \ / / \_\ | |
|
89
|
+
| | / /_\ \ | |\ \| || | ___ | | | | / /_\ \ | | ___ | ^‒‒‒v
|
90
|
+
| | / _____ \ | | \ \ || | |_ || | | | / _____ \ | | |_ || .‒‒‒^
|
91
|
+
| |____ / / \ \ | | \ | \ \__/ | \ \_/ / / / \ \ \ \__/ || |_____
|
92
|
+
|______|/_/ \_\|_| \_| \____/_| \___/ /_/ \_\ \____/_||_______|
|
93
|
+
|
94
|
+
|
95
|
+
____ _ _____ _____ _____
|
96
|
+
/ __ \ / \ | __ \ | __ \ / ___/
|
97
|
+
/ / \_\ / _ \ | | \ \ | | \ \ / /__
|
98
|
+
| | / /_\ \ | |__/ / | | | | \___ \
|
99
|
+
| | _ / _____ \ | __ < | | | | \ \
|
100
|
+
\ \__/ / / / \ \ | | \ \ | |__/ / ___/ /
|
101
|
+
\____/ /_/ \_\|_| \_\ |_____/ /____/
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
by Daniel P. Clark
|
107
|
+
|
108
|
+
@6ftdan
|
109
|
+
)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'language_cards/version'
|
2
|
+
require 'language_cards/language_cards'
|
3
|
+
require 'yaml'
|
4
|
+
require 'i18n'
|
5
|
+
require 'highline'
|
6
|
+
|
7
|
+
##
|
8
|
+
# TODO:
|
9
|
+
# * Implement score-keeper
|
10
|
+
# * Race against the clock
|
11
|
+
# * Weighted random for better learning
|
12
|
+
# * Value to Value is simply keyboard practice and should be clocked
|
13
|
+
# * Finish building Hiragana cards (figure out duplicates for ja, ju, jo)
|
14
|
+
|
15
|
+
module LanguageCards
|
16
|
+
CLEAR = begin
|
17
|
+
require 'mkmf'
|
18
|
+
clear = case RbConfig::CONFIG['target_os']
|
19
|
+
when /mingw32|mswin/
|
20
|
+
MakeMakefile.find_executable('cls')
|
21
|
+
else
|
22
|
+
MakeMakefile.find_executable('clear')
|
23
|
+
end
|
24
|
+
clear ? `#{clear}` : "\e[3J\e[H\e[2J"
|
25
|
+
ensure
|
26
|
+
File.delete('mkmf.log')
|
27
|
+
end
|
28
|
+
|
29
|
+
CLI = HighLine.new
|
30
|
+
JOIN = " : "
|
31
|
+
|
32
|
+
SUBMENUWIDTH = 60
|
33
|
+
|
34
|
+
::I18n.load_path = Dir[File.join 'locales', '*.yml']
|
35
|
+
|
36
|
+
def self.start
|
37
|
+
LanguageCards.new.start
|
38
|
+
end
|
39
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
en:
|
2
|
+
Menu:
|
3
|
+
Title: Language Cards by @6ftdan
|
4
|
+
Choose: Choose your flash cards.
|
5
|
+
Exit: Press CTRL-C to quit.
|
6
|
+
Game:
|
7
|
+
TypeThis: Type the following in
|
8
|
+
Correct: Correct!
|
9
|
+
Incorrect: Wrong!
|
10
|
+
Its: it's
|
11
|
+
ScoreMenu:
|
12
|
+
Score: Your score is
|
13
|
+
OutOf: out of
|
14
|
+
Errors:
|
15
|
+
UpperCollection: Upper level collection container.\nYou need to use a deeper collection for cards.
|
16
|
+
InvalidMapping: >
|
17
|
+
Invalid mapping in YAML definition.
|
18
|
+
Their needs to be exactly two entries.
|
19
|
+
* one with an "index" key
|
20
|
+
* and one with one language name as the key and the other as a value
|
21
|
+
Fix your language mapping.
|
22
|
+
EmptyCollection: Invalid option on empty card collection!
|
23
|
+
LanguageName:
|
24
|
+
Japanese: Japanese
|
25
|
+
Romaji: Romaji
|
26
|
+
Katakana: Katakana
|
27
|
+
Hiragana: Hiragana
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: language_cards
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel P. Clark
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: highline
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.13'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.13'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '12.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '12.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.10'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.10'
|
83
|
+
description: Flashcard game for language learning. Make your own cards or translations
|
84
|
+
as well.
|
85
|
+
email:
|
86
|
+
- 6ftdan@gmail.com
|
87
|
+
executables:
|
88
|
+
- language_cards
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/language_cards
|
100
|
+
- bin/setup
|
101
|
+
- cards/japanese-katakana-hiragana.yml
|
102
|
+
- language_cards.gemspec
|
103
|
+
- lib/language_cards.rb
|
104
|
+
- lib/language_cards/card_collection.rb
|
105
|
+
- lib/language_cards/comp_bitz.rb
|
106
|
+
- lib/language_cards/comparator.rb
|
107
|
+
- lib/language_cards/language_cards.rb
|
108
|
+
- lib/language_cards/mapping.rb
|
109
|
+
- lib/language_cards/user_interface.rb
|
110
|
+
- lib/language_cards/version.rb
|
111
|
+
- locales/en.yml
|
112
|
+
homepage: http://github.com/danielpclark/language_cards
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
- cards
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.6.8
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: Flashcard game for language learning.
|
137
|
+
test_files: []
|