random_name_generator 1.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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