random_name_generator 1.2.2 → 2.0.0

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.
@@ -1,120 +0,0 @@
1
- require_relative 'rng_syllable'
2
-
3
- # RandomNameGenerator:
4
- #
5
- # Examples
6
- #
7
- # rng = RandomNameGenerator.new(RandomNameGenerator::GOBLIN)
8
- # puts rng.compose(3)
9
- #
10
- # By default RandomNameGenerator uses the Fantasy syllable file and creates a name with between 2 and 5 syllables.
11
- #
12
- # rng = RandomNameGenerator.new
13
- # puts rng.compose
14
- #
15
- # :reek:TooManyInstanceVariables
16
- # :reek:TooManyStatements
17
- class RandomNameGenerator
18
- dirname = File.dirname(__FILE__)
19
-
20
- ELVEN = File.new("#{dirname}/languages/elven.txt")
21
- FANTASY = File.new("#{dirname}/languages/fantasy.txt")
22
- GOBLIN = File.new("#{dirname}/languages/goblin.txt")
23
- ROMAN = File.new("#{dirname}/languages/roman.txt")
24
-
25
- ELVEN_RU = File.new("#{dirname}/languages/elven-ru.txt")
26
- FANTASY_RU = File.new("#{dirname}/languages/fantasy-ru.txt")
27
- GOBLIN_RU = File.new("#{dirname}/languages/goblin-ru.txt")
28
- ROMAN_RU = File.new("#{dirname}/languages/roman-ru.txt")
29
-
30
- attr_reader :pre, :pre_syllables, :sur_syllables, :mid_syllables
31
-
32
- def initialize(filename = RandomNameGenerator::FANTASY, random: Random.new)
33
- @pre = nil
34
- @file = File.new(filename)
35
- @rnd = random
36
- @pre_syllables = []
37
- @sur_syllables = []
38
- @mid_syllables = []
39
-
40
- refresh
41
- end
42
-
43
- # Public: Static factory method that instantiates a RandomNameGenerator in a random language.
44
- def self.flip_mode
45
- langs = [RandomNameGenerator::FANTASY,
46
- RandomNameGenerator::ELVEN,
47
- RandomNameGenerator::GOBLIN,
48
- RandomNameGenerator::ROMAN]
49
- new(langs.sample)
50
- end
51
-
52
- def self.flip_mode_cyrillic
53
- langs = [RandomNameGenerator::FANTASY_RU,
54
- RandomNameGenerator::ELVEN_RU,
55
- RandomNameGenerator::GOBLIN_RU,
56
- RandomNameGenerator::ROMAN_RU]
57
- new(langs.sample)
58
- end
59
-
60
- def compose(count = RandomNameGenerator.pick_number_of_syllables)
61
- @pre = pre_syllables.sample
62
- return @pre.to_s.capitalize if count < 2
63
-
64
- name = determine_middle_syllables(count - 2, pre)
65
- name << determine_last_syllable(name.last)
66
- name.map(&:to_s).join.capitalize
67
- end
68
-
69
- def self.pick_number_of_syllables
70
- [2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5].sample
71
- end
72
-
73
- def to_s
74
- "RandomNameGenerator (#{@file.path})"
75
- end
76
-
77
- private
78
-
79
- def determine_middle_syllables(count, pre)
80
- determine_next_syllables(count, pre, @mid_syllables)
81
- end
82
-
83
- def determine_last_syllable(next_to_last_syllable)
84
- determine_next_syllable(next_to_last_syllable, @sur_syllables)
85
- end
86
-
87
- def determine_next_syllables(count, pre, syllables)
88
- name = Array(pre)
89
- return name if count < 1
90
-
91
- next_syllable = pre
92
- count.times do
93
- next_syllable = determine_next_syllable(next_syllable, syllables)
94
- name << next_syllable
95
- end
96
- name
97
- end
98
-
99
- def determine_next_syllable(this_syllable, sampler)
100
- next_syllable = ''
101
- loop do
102
- next_syllable = sampler.sample(random: @rnd)
103
- break unless this_syllable.incompatible?(next_syllable)
104
- end
105
- next_syllable
106
- end
107
-
108
- def refresh
109
- @file.readlines.each do |line|
110
- syllable = RNGSyllable.new(line) unless line.empty?
111
- if syllable.prefix?
112
- @pre_syllables.push(syllable)
113
- elsif syllable.suffix?
114
- @sur_syllables.push(syllable)
115
- else
116
- @mid_syllables.push(syllable)
117
- end
118
- end
119
- end
120
- end
@@ -1,175 +0,0 @@
1
- # RNGSyllable: Class for managing properties of individual syllables with in language name file. Each line within a file
2
- # translates into a syllable object. The reason behind this class is to take over most of the complexity of parsing each
3
- # syllable, greatly simplifying the work done by RandomNameGenerator. This code is not meant to be called directly as a
4
- # part of standard usage.
5
- #
6
- # Examples
7
- #
8
- # syllable = RNGSyllable.new('-foo +c')
9
- #
10
- # This creates a foo syllable object that needs to be the first syllable and followed by a constant.
11
- #
12
- # For testing purposes, passing in another RNGSyllable object will create a clone:
13
- #
14
- # syllable_clone = RNGSyllable.new(syllable)
15
- #
16
- # SYLLABLE CLASSIFICATION:
17
- # Name is usually composed from 3 different class of syllables, which include prefix, middle part and suffix.
18
- # To declare syllable as a prefix in the file, insert "-" as a first character of the line.
19
- # To declare syllable as a suffix in the file, insert "+" as a first character of the line.
20
- # everything else is read as a middle part.
21
- #
22
- # NUMBER OF SYLLABLES:
23
- # Names may have any positive number of syllables. In case of 2 syllables, name will be composed from prefix and suffix.
24
- # In case of 1 syllable, name will be chosen from amongst the prefixes.
25
- # In case of 3 and more syllables, name will begin with prefix, is filled with middle parts and ended with suffix.
26
- #
27
- # ASSIGNING RULES:
28
- # I included a way to set 4 kind of rules for every syllable. To add rules to the syllables, write them right after the
29
- # syllable and SEPARATE WITH WHITESPACE. (example: "aad +v -c"). The order of rules is not important.
30
- #
31
- # RULES:
32
- # 1) +v means that next syllable must definitely start with a vowel.
33
- # 2) +c means that next syllable must definitely start with a consonant.
34
- # 3) -v means that this syllable can only be added to another syllable, that ends with a vowel.
35
- # 4) -c means that this syllable can only be added to another syllable, that ends with a consonant.
36
- #
37
- # :reek:TooManyMethods
38
- # :reek:TooManyInstanceVariables
39
- class RNGSyllable
40
- attr_reader :raw, :syllable, :next_syllable_requirement, :previous_syllable_requirement
41
-
42
- VOWELS ||= %w[i y ɨ ʉ ɯ u ɪ ʏ ʊ ɯ ʊ e ø ɘ ɵ ɤ o ø ə ɵ ɤ o ɛ œ ɜ ɞ ʌ ɔ æ ɐ ɞ a ɶ ä ɒ ɑ].freeze
43
- CONSONANTS ||= %w[b ɓ ʙ β c d ɗ ɖ ð f g h j k l ł m ɱ n ɳ p q r s t v w x y z].freeze
44
-
45
- def initialize(args)
46
- @raw = args
47
- @syllable = ''
48
- @is_prefix = false
49
- @is_suffix = false
50
- @next_syllable_requirement = :letter
51
- @previous_syllable_requirement = :letter
52
-
53
- if args.is_a?(RNGSyllable) then
54
- parse_args(args.raw)
55
- else
56
- parse_args(args)
57
- end
58
- end
59
-
60
- def incompatible?(next_syllable)
61
- (next_incompatible?(next_syllable) || previous_incompatible?(next_syllable))
62
- end
63
-
64
- def compatible?(next_syllable)
65
- !incompatible?(next_syllable)
66
- end
67
-
68
- def prefix?
69
- @is_prefix
70
- end
71
-
72
- def suffix?
73
- @is_suffix
74
- end
75
-
76
- def consonant_first?
77
- CONSONANTS.include?(syllable[0])
78
- end
79
-
80
- def vowel_first?
81
- VOWELS.include?(syllable[0])
82
- end
83
-
84
- def consonant_last?
85
- CONSONANTS.include?(syllable[-1])
86
- end
87
-
88
- def vowel_last?
89
- VOWELS.include?(syllable[-1])
90
- end
91
-
92
- def next_syllable_universal?
93
- @next_syllable_requirement == :letter
94
- end
95
-
96
- def next_syllable_must_start_with_vowel?
97
- @next_syllable_requirement == :vowel
98
- end
99
-
100
- def next_syllable_must_start_with_consonant?
101
- @next_syllable_requirement == :consonant
102
- end
103
-
104
- def previous_syllable_universal?
105
- @previous_syllable_requirement == :letter
106
- end
107
-
108
- def previous_syllable_must_end_with_vowel?
109
- @previous_syllable_requirement == :vowel
110
- end
111
-
112
- def previous_syllable_must_end_with_consonant?
113
- @previous_syllable_requirement == :consonant
114
- end
115
-
116
- def to_s
117
- @syllable
118
- end
119
-
120
- def to_str
121
- @syllable
122
- end
123
-
124
- private
125
-
126
- # :reek:FeatureEnvy
127
- def parse_args(args)
128
- args = args.to_s.strip.downcase.split(' ')
129
- parse_syllable(args[0])
130
- parse_flags(args[1..-1])
131
- end
132
-
133
- def parse_syllable(syll)
134
- raise ArgumentError 'Empty String is not allowed.' if syll.empty?
135
-
136
- captures = /([+-]?)(.+)/.match(syll).captures
137
- parse_prefix(captures[0])
138
- @syllable = captures[1]
139
- end
140
-
141
- def parse_prefix(prefix)
142
- if prefix.eql?('-')
143
- @is_prefix = true
144
- elsif prefix.eql?('+')
145
- @is_suffix = true
146
- end
147
- end
148
-
149
- def parse_flags(flags)
150
- if flags.include?('+v')
151
- @next_syllable_requirement = :vowel
152
- elsif flags.include?('+c')
153
- @next_syllable_requirement = :consonant
154
- end
155
- if flags.include?('-v')
156
- @previous_syllable_requirement = :vowel
157
- elsif flags.include?('-c')
158
- @previous_syllable_requirement = :consonant
159
- end
160
- end
161
-
162
- def next_incompatible?(next_syllable)
163
- vnc = (next_syllable_must_start_with_vowel? && next_syllable.consonant_first?)
164
- cnv = (next_syllable_must_start_with_consonant? && next_syllable.vowel_first?)
165
-
166
- (vnc || cnv)
167
- end
168
-
169
- def previous_incompatible?(next_syllable)
170
- vlc = (vowel_last? && next_syllable.previous_syllable_must_end_with_consonant?)
171
- clv = (consonant_last? && next_syllable.previous_syllable_must_end_with_vowel?)
172
-
173
- (vlc || clv)
174
- end
175
- end