language_cards 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ **/*.swp
11
+ mkmf.log
12
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ before_install: gem install bundler -v 1.13.7
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in language_cards.gemspec
4
+ gemspec
5
+
6
+ gem 'simplecov', :require => false, :group => :test
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
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path(File.join('..', '..', 'lib'), __FILE__)
4
+
5
+ require 'language_cards'
6
+
7
+ LanguageCards.start
8
+
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,3 @@
1
+ module LanguageCards
2
+ VERSION = "0.0.1"
3
+ end
@@ -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: []