language_cards 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/cards/{japanese-hiragana.yml → en/japanese-hiragana.yml} +0 -0
- data/cards/en/japanese-kanji-jlpt-n5.yml +107 -0
- data/cards/{japanese-katakana.yml → en/japanese-katakana.yml} +0 -0
- data/language_cards.gemspec +12 -12
- data/lib/language_cards.rb +7 -2
- data/lib/language_cards/controllers/application_controller.rb +27 -0
- data/lib/language_cards/controllers/game.rb +51 -55
- data/lib/language_cards/controllers/main_menu.rb +14 -19
- data/lib/language_cards/helpers/view_helper.rb +8 -0
- data/lib/language_cards/language_cards.rb +11 -41
- data/lib/language_cards/user_interface.rb +19 -4
- data/lib/language_cards/version.rb +1 -1
- data/lib/language_cards/view/game.erb +1 -1
- data/lib/language_cards/view/main_menu.erb +1 -1
- data/lib/language_cards/yaml_loader.rb +49 -0
- metadata +10 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 409fa54cd14dc132b49083d8e4a26cd768803b13aff44e822da5c23cd5898e9a
|
|
4
|
+
data.tar.gz: ba9fcbcf3df0a95c6b7984772c90a21560beefa4790058b277dbce27515b6924
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83285da9cb6ac703432739dc0f20ed8155bc84e73891f171b8aab07d9744b41da30ba997b5e6a8266cba55186216e31a417718ea84d45dcf9b7a8e7793568d93
|
|
7
|
+
data.tar.gz: b310a242bb5e3299bedbc306829becbab0f82bb602a4884bde516ad52356b833670ac9542c8433347dcdc43c7845b8403b2729bf345cc162c403debfd616cae4
|
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
--- # https://www.jlptstudy.net/N5/?kanji-list
|
|
2
|
+
Japanese:
|
|
3
|
+
Kanji (JLPT Level N5):
|
|
4
|
+
mapping: { Kanji: [Hiragana, English] }
|
|
5
|
+
一: [ひと, ひとつ, one, only, even, 1]
|
|
6
|
+
七: [なな, seven, 7]
|
|
7
|
+
万: [よろず, ten thousand]
|
|
8
|
+
三: [さん, three, 3]
|
|
9
|
+
上: [うえ, above, up]
|
|
10
|
+
下: [した, below, down, descend, give, low, inferior]
|
|
11
|
+
中: [なか, in, inside, middle, mean, center]
|
|
12
|
+
九: [ここの, nine, 9]
|
|
13
|
+
二: [に, two, 2]
|
|
14
|
+
五: [ご, five, 5]
|
|
15
|
+
人: [ひと, people, person, man, human being, other people, mankind]
|
|
16
|
+
今: [いま, now]
|
|
17
|
+
休: [きゅう, rest, day off, retire, sleep]
|
|
18
|
+
会: [かい, gathering, meeting, meet, party, association, interview, join]
|
|
19
|
+
何: [なに, なん, what]
|
|
20
|
+
先: [さき, before, ahead, previous, future, precedence]
|
|
21
|
+
入: [いり, enter, insert]
|
|
22
|
+
八: [はち, eight, 8]
|
|
23
|
+
六: [ろく, six, 6]
|
|
24
|
+
円: [えん, circle, yen, round]
|
|
25
|
+
出: [で, exit, leave]
|
|
26
|
+
分: [ぶん, part, minute of time, segment, share, degree, one's lot, duty, understand, know, rate, 1%, chances, shaku/100]
|
|
27
|
+
前: [まえ, in front, before]
|
|
28
|
+
北: [きた, north]
|
|
29
|
+
十: [じゅう, ten, 10]
|
|
30
|
+
千: [せん, thousand, 1000]
|
|
31
|
+
午: [うま, noon, sign of the horse, 11AM-1PM, seventh sign of Chinese zodiac]
|
|
32
|
+
半: [はん, half, middle, odd number, semi-, part-]
|
|
33
|
+
南: [みなみ, south]
|
|
34
|
+
友: [とも, friend]
|
|
35
|
+
口: [くち, mouth]
|
|
36
|
+
古: [ふる, old]
|
|
37
|
+
右: [みぎ, right]
|
|
38
|
+
名: [な, name, noted, distinguished, reputation]
|
|
39
|
+
四: [よん, four, 4]
|
|
40
|
+
国: [くに, country, state, region, province, home, hometown, homeland, home country, land, earth]
|
|
41
|
+
土: [つち, soil, earth, ground, Turkey]
|
|
42
|
+
外: [そと, outside, outside of]
|
|
43
|
+
多: [さわ, many, frequent, much]
|
|
44
|
+
大: [おお, large, big]
|
|
45
|
+
天: [てん, heavens, sky, imperial]
|
|
46
|
+
女: [おんな, woman, female]
|
|
47
|
+
子: [こ, child, sign of the rat, 11PM-1AM, first sign of Chinese zodiac]
|
|
48
|
+
学: [がく, study, learning, science]
|
|
49
|
+
安: [あん, cheap, relax, low, quiet, rested, contented, peaceful]
|
|
50
|
+
小: [しょう, little, small]
|
|
51
|
+
少: [すくな, few, little]
|
|
52
|
+
山: [やま, mountain]
|
|
53
|
+
川: [かわ, stream, river]
|
|
54
|
+
左: [ひだり, left]
|
|
55
|
+
年: [とし, year, counter for years, age]
|
|
56
|
+
店: [みせ, store, shop]
|
|
57
|
+
後: [あと, behind, back, later]
|
|
58
|
+
手: [て, hand]
|
|
59
|
+
新: [しん, new]
|
|
60
|
+
日: [ひ, day, sun, Japan, counter for days, sunshine, sunlight, case, event]
|
|
61
|
+
時: [じ, time, hour]
|
|
62
|
+
書: [しょ, write]
|
|
63
|
+
月: [つき, month, moon]
|
|
64
|
+
木: [き, tree, wood]
|
|
65
|
+
本: [もと, book, present, main, 'true', real, counter for long cylindrical things]
|
|
66
|
+
来: [き, come, due, next, cause, become]
|
|
67
|
+
東: [ひがし, east]
|
|
68
|
+
校: [-こう, exam, school, printing, proof, correction]
|
|
69
|
+
母: [はは, mama, mother]
|
|
70
|
+
毎: [まい, every]
|
|
71
|
+
気: [いき, spirit, mind, air, atmosphere, mood]
|
|
72
|
+
水: [みず, water]
|
|
73
|
+
火: [ひ, fire]
|
|
74
|
+
父: [ちち, father]
|
|
75
|
+
生: [なま, life, genuine, birth]
|
|
76
|
+
男: [おとこ, male]
|
|
77
|
+
白: [しろ, white]
|
|
78
|
+
百: [もも, hundred, 100]
|
|
79
|
+
目: [め, eye, class, look, insight, experience, care, favor]
|
|
80
|
+
社: [やしろ, company, firm, office, association, shrine]
|
|
81
|
+
空: [そら, empty, sky, void, vacant, vacuum]
|
|
82
|
+
立: [たて, stand up]
|
|
83
|
+
耳: [みみ, ear]
|
|
84
|
+
聞: [きき, hear, ask, listen]
|
|
85
|
+
花: [はな, flower]
|
|
86
|
+
行: [こう, going, journey]
|
|
87
|
+
西: [にし, west, Spain]
|
|
88
|
+
見: [み, see, hopes, chances, idea, opinion, look at, visible]
|
|
89
|
+
言: [げん, say]
|
|
90
|
+
話: [はなし, tale, talk]
|
|
91
|
+
語: [ご, word, speech, language]
|
|
92
|
+
読: [よみ, read]
|
|
93
|
+
買: [かい, buy]
|
|
94
|
+
足: [あし, leg, foot, be sufficient, counter for pairs of footwear]
|
|
95
|
+
車: [くるま, car]
|
|
96
|
+
週: [しゅう, week]
|
|
97
|
+
道: [みち, road-way, street, district, journey, course, moral, teachings]
|
|
98
|
+
金: [きん, gold]
|
|
99
|
+
長: [なが, long, leader]
|
|
100
|
+
間: [ま, interval, space]
|
|
101
|
+
雨: [あめ, rain]
|
|
102
|
+
電: [でん, electricity]
|
|
103
|
+
食: [しょく, eat, food]
|
|
104
|
+
飲: [いん, drink, smoke, take]
|
|
105
|
+
駅: [えき, station]
|
|
106
|
+
高: [こう, tall, high, expensive]
|
|
107
|
+
魚: [さかな, fish]
|
|
File without changes
|
data/language_cards.gemspec
CHANGED
|
@@ -4,27 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
4
4
|
require 'language_cards/version'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name =
|
|
7
|
+
spec.name = 'language_cards'
|
|
8
8
|
spec.version = LanguageCards::VERSION
|
|
9
|
-
spec.authors = [
|
|
10
|
-
spec.email = [
|
|
9
|
+
spec.authors = ['Daniel P. Clark']
|
|
10
|
+
spec.email = ['6ftdan@gmail.com']
|
|
11
11
|
|
|
12
12
|
spec.summary = %q{Flashcard game for language learning.}
|
|
13
13
|
spec.description = %q{Flashcard game for language learning. Make your own cards or translations as well.}
|
|
14
|
-
spec.homepage =
|
|
15
|
-
spec.license =
|
|
14
|
+
spec.homepage = 'http://github.com/danielpclark/language_cards'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
16
|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
spec.executables = ['language_cards']
|
|
22
|
-
spec.require_paths = [
|
|
22
|
+
spec.require_paths = ['lib','cards']
|
|
23
23
|
|
|
24
|
-
spec.add_dependency
|
|
25
|
-
spec.add_dependency
|
|
26
|
-
spec.add_dependency
|
|
27
|
-
spec.add_development_dependency
|
|
28
|
-
spec.add_development_dependency
|
|
29
|
-
spec.add_development_dependency
|
|
24
|
+
spec.add_dependency 'highline', '~> 1.7'
|
|
25
|
+
spec.add_dependency 'i18n', '~> 0.7'
|
|
26
|
+
spec.add_dependency 'slop', '~> 4.6'
|
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
|
29
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
|
30
30
|
end
|
data/lib/language_cards.rb
CHANGED
|
@@ -2,17 +2,22 @@ require 'language_cards/version'
|
|
|
2
2
|
require 'language_cards/language_cards'
|
|
3
3
|
require 'yaml'
|
|
4
4
|
require 'i18n'
|
|
5
|
+
require 'slop'
|
|
5
6
|
require 'highline'
|
|
6
|
-
require 'elixirize'
|
|
7
7
|
|
|
8
8
|
##
|
|
9
9
|
# TODO:
|
|
10
10
|
# * Implement score-keeper
|
|
11
11
|
# * Race against the clock
|
|
12
12
|
# * Weighted random for better learning
|
|
13
|
-
# * Value to Value is simply keyboard practice and should be clocked
|
|
14
13
|
|
|
15
14
|
module LanguageCards
|
|
15
|
+
OPTS = Slop.parse do |args|
|
|
16
|
+
args.string '-l', '--language', 'language (default: en)', default: 'en'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
CARD_LANGUAGE = OPTS[:language]
|
|
20
|
+
|
|
16
21
|
module ESC
|
|
17
22
|
CLEAR = (ERASE_SCOLLBACK = "\e[3J") + (CURSOR_HOME = "\e[H") + (ERASE_DISPLAY = "\e[2J")
|
|
18
23
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module LanguageCards
|
|
2
|
+
module Controllers
|
|
3
|
+
class ApplicationController
|
|
4
|
+
include Helpers::ViewHelper
|
|
5
|
+
|
|
6
|
+
def initialize(opts = {})
|
|
7
|
+
@opts = opts
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def render(_binding)
|
|
11
|
+
view = ERB.new IO.read File.expand_path("../view/#{snake name}.erb", __dir__)
|
|
12
|
+
|
|
13
|
+
view.result(_binding)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
attr_reader :opts
|
|
18
|
+
def name
|
|
19
|
+
self.class.name.split('::').last
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def errors
|
|
23
|
+
Array(opts[:errors])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,72 +1,68 @@
|
|
|
1
|
+
require 'language_cards/controllers/application_controller'
|
|
2
|
+
|
|
1
3
|
module LanguageCards
|
|
2
4
|
module Controllers
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
include Helpers::ViewHelper
|
|
6
|
-
include Helpers::GameHelper
|
|
5
|
+
class Game < ApplicationController
|
|
6
|
+
include Helpers::GameHelper
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def render(correct:, incorrect:, title:, timer:, last:)
|
|
9
|
+
_score = t('Game.ScoreMenu.Score') + ": %0.2d%%" % calc_score(correct, incorrect)
|
|
10
|
+
_timer = [((t('Timer.Timer') + ": " + timer.ha) if timer.time?), nil, timer.h]
|
|
11
|
+
_mexit = t 'Menu.Exit'
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
ᐅ ERB.method :new
|
|
16
|
-
view.result(binding)
|
|
17
|
-
end
|
|
13
|
+
super(binding)
|
|
14
|
+
end
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
def process(cards, mode)
|
|
17
|
+
ic = struct_data.new(cards, mode)
|
|
18
|
+
ic.get_input
|
|
19
|
+
{
|
|
20
|
+
correct: ic.valid?,
|
|
21
|
+
last: ic.valid? ? ic.correct_msg : ic.incorrect_msg
|
|
22
|
+
}
|
|
23
|
+
end
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
def struct_data
|
|
26
|
+
Struct.new(:card_set, :mode) do
|
|
27
|
+
def input
|
|
28
|
+
@input
|
|
29
|
+
end
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
def get_input
|
|
32
|
+
@input ||= CLI.ask("#{I18n.t('Game.TypeThis')}: #{display}")
|
|
33
|
+
end
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
def card
|
|
36
|
+
@card ||= card_set.sample.current
|
|
37
|
+
end
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
def display
|
|
40
|
+
"#{card}"
|
|
41
|
+
end
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
43
|
+
def expected
|
|
44
|
+
case mode
|
|
45
|
+
when :translate
|
|
46
|
+
card.translation
|
|
47
|
+
when :typing_practice
|
|
48
|
+
"#{card}"
|
|
49
|
+
else
|
|
50
|
+
raise "Invalid mode in Game Controller!"
|
|
55
51
|
end
|
|
52
|
+
end
|
|
56
53
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
def correct_msg
|
|
55
|
+
"#{I18n.t('Game.Correct')} #{input} = #{display}"
|
|
56
|
+
end
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
def incorrect_msg
|
|
59
|
+
output = "#{I18n.t('Game.Incorrect')} #{input} != #{display}"
|
|
60
|
+
output << " #{I18n.t('Game.Its')} #{expected.join(', ')}" if mode == :translate
|
|
61
|
+
output
|
|
62
|
+
end
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
end
|
|
64
|
+
def valid?
|
|
65
|
+
card_set.match? input
|
|
70
66
|
end
|
|
71
67
|
end
|
|
72
68
|
end
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
+
require 'language_cards/controllers/application_controller'
|
|
2
|
+
|
|
1
3
|
module LanguageCards
|
|
2
4
|
module Controllers
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
_toggle = "m: " + t('Menu.ToggleGameMode')
|
|
15
|
-
_courses = courses.each.with_index.map {|item,index| "#{index + 1}: #{item}" }
|
|
16
|
-
_mexit = t 'Menu.Exit'
|
|
5
|
+
class MainMenu < ApplicationController
|
|
6
|
+
def render(courses:, mode:)
|
|
7
|
+
_title = t 'Menu.Title'
|
|
8
|
+
_select = t 'Menu.Choose'
|
|
9
|
+
_mode = t('Menu.GameMode') + case mode.peek
|
|
10
|
+
when :translate then t 'Menu.ModeTranslate'
|
|
11
|
+
when :typing_practice then t 'Menu.ModeTyping'
|
|
12
|
+
end
|
|
13
|
+
_toggle = "m: " + t('Menu.ToggleGameMode')
|
|
14
|
+
_courses = courses.each.with_index.map {|item,index| "#{index + 1}: #{item}" }
|
|
15
|
+
_mexit = t 'Menu.Exit'
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
ᐅ( IO.method :read ).
|
|
20
|
-
ᐅ ERB.method :new
|
|
21
|
-
view.result(binding)
|
|
22
|
-
end
|
|
17
|
+
super(binding)
|
|
23
18
|
end
|
|
24
19
|
end
|
|
25
20
|
end
|
|
@@ -23,6 +23,14 @@ module LanguageCards
|
|
|
23
23
|
def humanize string
|
|
24
24
|
"#{string}".split('_').map(&:capitalize).join(' ')
|
|
25
25
|
end
|
|
26
|
+
|
|
27
|
+
def snake string
|
|
28
|
+
"#{string}".gsub(/(.)([A-Z])/, '\1_\2').downcase
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def wordwrap words
|
|
32
|
+
"#{words}".gsub(/(.{1,#{SUBMENUWIDTH - 7}})(\s+|\Z)/, "\\1\n\t").strip
|
|
33
|
+
end
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
36
|
end
|
|
@@ -1,55 +1,25 @@
|
|
|
1
1
|
require 'language_cards/menu_node'
|
|
2
|
-
|
|
2
|
+
require 'language_cards/yaml_loader'
|
|
3
|
+
require 'language_cards/user_interface'
|
|
3
4
|
|
|
4
5
|
module LanguageCards
|
|
5
6
|
class LanguageCards
|
|
6
7
|
def initialize
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# TODO: Extract out YAML file loading behavior to methods via SRP.
|
|
10
|
-
File.join('..','..').
|
|
11
|
-
ᐅ(File.method(:expand_path), __dir__ ).
|
|
12
|
-
ᐅ(File.method(:join), 'cards', '*.yml').
|
|
13
|
-
ᐅ(Dir.method :[] ).
|
|
14
|
-
+(
|
|
15
|
-
if ENV['HOME']
|
|
16
|
-
File.expand_path(ENV['HOME']).
|
|
17
|
-
ᐅ(File.method(:join), '.language_cards', 'cards', '*.yml').
|
|
18
|
-
ᐅ Dir.method :[]
|
|
19
|
-
else
|
|
20
|
-
[]
|
|
21
|
-
end
|
|
22
|
-
).
|
|
23
|
-
each do |c|
|
|
24
|
-
next unless yaml_data = c.ᐅ(File.method :open).ᐅ(~:read).ᐅ(YAML.method :load)
|
|
25
|
-
for language in yaml_data.keys do
|
|
26
|
-
# Merges sub-items for languages
|
|
27
|
-
if @CARDS.has_key? language
|
|
28
|
-
@CARDS[language] = \
|
|
29
|
-
yaml_data[language].
|
|
30
|
-
ᐅ(method :Hash).
|
|
31
|
-
ᐅ @CARDS[language].
|
|
32
|
-
ᐅ(method :Hash).
|
|
33
|
-
method(:merge)
|
|
34
|
-
else
|
|
35
|
-
# Merges top scope languages
|
|
36
|
-
{ language => yaml_data[language] }.
|
|
37
|
-
ᐅ @CARDS.method :merge!
|
|
38
|
-
end
|
|
39
|
-
end
|
|
8
|
+
self.cards = builder(YAMLLoader.new.load)
|
|
9
|
+
end
|
|
40
10
|
|
|
41
|
-
|
|
11
|
+
def start
|
|
12
|
+
UserInterface.new(cards).start
|
|
13
|
+
end
|
|
42
14
|
|
|
43
|
-
|
|
44
|
-
|
|
15
|
+
private
|
|
16
|
+
attr_accessor :cards
|
|
17
|
+
def builder(cards_yaml)
|
|
18
|
+
cards_yaml.each_with_object([]) do |(language, values), memo|
|
|
45
19
|
values.each do |category_with_card_set|
|
|
46
20
|
memo << MenuNode.new(language, category_with_card_set)
|
|
47
21
|
end
|
|
48
22
|
end
|
|
49
23
|
end
|
|
50
|
-
|
|
51
|
-
def start
|
|
52
|
-
@CARDS.ᐅ(UserInterface.method :new).ᐅ ~:start
|
|
53
|
-
end
|
|
54
24
|
end
|
|
55
25
|
end
|
|
@@ -11,7 +11,7 @@ module LanguageCards
|
|
|
11
11
|
include Controllers
|
|
12
12
|
def initialize cards
|
|
13
13
|
@cards = cards
|
|
14
|
-
@courses = cards
|
|
14
|
+
@courses = process_courses(cards)
|
|
15
15
|
@mode = [:translate, :typing_practice].cycle
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@ module LanguageCards
|
|
|
26
26
|
loop do
|
|
27
27
|
clear
|
|
28
28
|
|
|
29
|
-
CLI.say MainMenu.render courses: courses, mode: mode
|
|
29
|
+
CLI.say MainMenu.new(opts).render courses: courses, mode: mode
|
|
30
30
|
|
|
31
31
|
value = CLI.ask("")
|
|
32
32
|
|
|
@@ -40,17 +40,18 @@ module LanguageCards
|
|
|
40
40
|
title = "#{collection.title} (#{humanize mode.peek})"
|
|
41
41
|
collection = collection.mode(mode.peek) # Mode<CardSet> < Game
|
|
42
42
|
|
|
43
|
+
game = Game.new(opts)
|
|
43
44
|
timer = Timer.new
|
|
44
45
|
begin # Game Loop
|
|
45
46
|
loop do
|
|
46
47
|
clear
|
|
47
48
|
timer.mark
|
|
48
|
-
CLI.say
|
|
49
|
+
CLI.say game.render correct: correct,
|
|
49
50
|
incorrect: incorrect,
|
|
50
51
|
title: title,
|
|
51
52
|
timer: timer,
|
|
52
53
|
last: last
|
|
53
|
-
result =
|
|
54
|
+
result = game.process(collection, collection.mode)
|
|
54
55
|
result[:correct] ? correct! : incorrect!
|
|
55
56
|
last = result[:last]
|
|
56
57
|
end
|
|
@@ -65,6 +66,10 @@ module LanguageCards
|
|
|
65
66
|
|
|
66
67
|
private
|
|
67
68
|
attr_reader :mode, :cards, :correct, :incorrect, :courses
|
|
69
|
+
def opts
|
|
70
|
+
@opts ||= {}
|
|
71
|
+
end
|
|
72
|
+
|
|
68
73
|
def correct!
|
|
69
74
|
@correct = @correct.to_i + 1
|
|
70
75
|
end
|
|
@@ -72,6 +77,16 @@ module LanguageCards
|
|
|
72
77
|
def incorrect!
|
|
73
78
|
@incorrect = @incorrect.to_i + 1
|
|
74
79
|
end
|
|
80
|
+
|
|
81
|
+
def process_courses(cards)
|
|
82
|
+
courses = cards.flat_map {|i| i.label.join(' - ') }
|
|
83
|
+
|
|
84
|
+
if courses.empty?
|
|
85
|
+
opts[:errors] = ["No Flash Cards found for language: #{CARD_LANGUAGE}"]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
courses
|
|
89
|
+
end
|
|
75
90
|
end
|
|
76
91
|
end
|
|
77
92
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module LanguageCards
|
|
2
|
+
class YAMLLoader
|
|
3
|
+
def initialize
|
|
4
|
+
@language = CARD_LANGUAGE
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def load
|
|
8
|
+
cards = {}
|
|
9
|
+
|
|
10
|
+
cards_yaml.each do |c|
|
|
11
|
+
next unless yaml_data = YAML.load(File.open(c).read)
|
|
12
|
+
for language in yaml_data.keys do
|
|
13
|
+
# Merges sub-items for languages
|
|
14
|
+
if cards.has_key? language
|
|
15
|
+
cards[language] = Hash( cards[language] ).merge( Hash(yaml_data[language]) )
|
|
16
|
+
else
|
|
17
|
+
# Merges in new top scope languages
|
|
18
|
+
cards.merge!({ language => yaml_data[language] })
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
cards
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
attr_reader :language
|
|
28
|
+
|
|
29
|
+
def application_path
|
|
30
|
+
File.expand_path(File.join('..','..'), __dir__)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def cards_yaml
|
|
34
|
+
application_path_cards_yaml + home_path_cards_yaml
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def application_path_cards_yaml
|
|
38
|
+
Dir[File.join(application_path, 'cards', language, '*.yml')]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def home_path_cards_yaml
|
|
42
|
+
if ENV['HOME']
|
|
43
|
+
Dir[File.join(ENV['HOME'], '.language_cards', 'cards', language, '*.yml')]
|
|
44
|
+
else
|
|
45
|
+
[]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: language_cards
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel P. Clark
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-04-
|
|
11
|
+
date: 2018-04-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: highline
|
|
@@ -39,19 +39,19 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0.7'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: slop
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '4.6'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '4.6'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: bundler
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -113,10 +113,12 @@ files:
|
|
|
113
113
|
- bin/console
|
|
114
114
|
- bin/language_cards
|
|
115
115
|
- bin/setup
|
|
116
|
-
- cards/japanese-hiragana.yml
|
|
117
|
-
- cards/japanese-
|
|
116
|
+
- cards/en/japanese-hiragana.yml
|
|
117
|
+
- cards/en/japanese-kanji-jlpt-n5.yml
|
|
118
|
+
- cards/en/japanese-katakana.yml
|
|
118
119
|
- language_cards.gemspec
|
|
119
120
|
- lib/language_cards.rb
|
|
121
|
+
- lib/language_cards/controllers/application_controller.rb
|
|
120
122
|
- lib/language_cards/controllers/game.rb
|
|
121
123
|
- lib/language_cards/controllers/main_menu.rb
|
|
122
124
|
- lib/language_cards/grapheme_builder.rb
|
|
@@ -134,6 +136,7 @@ files:
|
|
|
134
136
|
- lib/language_cards/version.rb
|
|
135
137
|
- lib/language_cards/view/game.erb
|
|
136
138
|
- lib/language_cards/view/main_menu.erb
|
|
139
|
+
- lib/language_cards/yaml_loader.rb
|
|
137
140
|
- locales/en.yml
|
|
138
141
|
homepage: http://github.com/danielpclark/language_cards
|
|
139
142
|
licenses:
|