1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // Totro-inspired random name generator, clean room implementation
18 module iv
.namegen
/*is aliced*/;
25 public struct NameGen
{
27 enum { Vowel
= 0, Consonant
= 1 }
35 static struct Syllable
{
38 ubyte code
; // WordXXX mask
42 bool opEqual (in Syllable sy
) const @safe pure nothrow @nogc {
43 return (this.code
== sy
.code
&& this.count
== sy
.count
&& this.str == sy
.str);
46 @property string
str () const @trusted pure nothrow @nogc {
48 while (sz
< sytext
.length
&& sytext
[sz
]) ++sz
;
49 return cast(string
)sytext
[0..sz
];
52 debug @property string
codeStr () const @trusted pure nothrow @nogc {
54 case WordBeg
: return "WordBeg";
55 case WordMid
: return "WordMid";
56 case WordEnd
: return "WordEnd";
57 case WordBeg|WordMid
: return "WordBeg|WordMid";
58 case WordBeg|WordEnd
: return "WordBeg|WordEnd";
59 case WordBeg|WordMid|WordEnd
: return "WordBeg|WordMid|WordEnd";
60 case WordMid|WordEnd
: return "WordMid|WordEnd";
61 default: return "FUCKED";
67 static immutable Syllable
[26] totroSyllsV
= [
68 {sytext
:"'\0", count
:1, code
:WordMid
},
69 {sytext
:"y\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
70 {sytext
:"aa\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
71 {sytext
:"ae\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
72 {sytext
:"ai\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
73 {sytext
:"ao\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
74 {sytext
:"au\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
75 {sytext
:"ea\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
76 {sytext
:"ee\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
77 {sytext
:"eo\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
78 {sytext
:"eu\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
79 {sytext
:"ia\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
80 {sytext
:"ii\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
81 {sytext
:"io\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
82 {sytext
:"iu\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
83 {sytext
:"oa\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
84 {sytext
:"oe\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
85 {sytext
:"oi\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
86 {sytext
:"oo\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
87 {sytext
:"ou\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
88 {sytext
:"eau", count
:1, code
:WordBeg|WordMid|WordEnd
},
89 {sytext
:"a\0", count
:12, code
:WordBeg|WordMid|WordEnd
},
90 {sytext
:"e\0", count
:12, code
:WordBeg|WordMid|WordEnd
},
91 {sytext
:"i\0", count
:12, code
:WordBeg|WordMid|WordEnd
},
92 {sytext
:"o\0", count
:12, code
:WordBeg|WordMid|WordEnd
},
93 {sytext
:"u\0", count
:12, code
:WordBeg|WordMid|WordEnd
},
95 static immutable Syllable
[51] totroSyllsC
= [
96 {sytext
:"x\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
97 {sytext
:"y\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
98 {sytext
:"z\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
99 {sytext
:"ch\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
100 {sytext
:"ck\0", count
:1, code
:WordMid|WordEnd
},
101 {sytext
:"cl\0", count
:1, code
:WordBeg|WordMid
},
102 {sytext
:"cr\0", count
:1, code
:WordBeg|WordMid
},
103 {sytext
:"fl\0", count
:1, code
:WordBeg|WordMid
},
104 {sytext
:"gh\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
105 {sytext
:"gl\0", count
:1, code
:WordBeg|WordMid
},
106 {sytext
:"kl\0", count
:1, code
:WordBeg|WordMid
},
107 {sytext
:"ll\0", count
:1, code
:WordBeg|WordMid
},
108 {sytext
:"nk\0", count
:1, code
:WordMid|WordEnd
},
109 {sytext
:"ph\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
110 {sytext
:"pl\0", count
:1, code
:WordBeg|WordMid
},
111 {sytext
:"pr\0", count
:1, code
:WordBeg|WordMid
},
112 {sytext
:"qu\0", count
:1, code
:WordBeg|WordMid
},
113 {sytext
:"rk\0", count
:1, code
:WordMid|WordEnd
},
114 {sytext
:"sc\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
115 {sytext
:"sh\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
116 {sytext
:"sk\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
117 {sytext
:"sl\0", count
:1, code
:WordBeg|WordMid
},
118 {sytext
:"sr\0", count
:1, code
:WordBeg|WordMid
},
119 {sytext
:"ss\0", count
:1, code
:WordMid|WordEnd
},
120 {sytext
:"st\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
121 {sytext
:"th\0", count
:1, code
:WordBeg|WordMid|WordEnd
},
122 {sytext
:"tr\0", count
:1, code
:WordBeg|WordMid
},
123 {sytext
:"wh\0", count
:1, code
:WordBeg|WordMid
},
124 {sytext
:"str", count
:1, code
:WordBeg|WordMid
},
125 {sytext
:"br\0", count
:2, code
:WordBeg|WordMid
},
126 {sytext
:"dr\0", count
:2, code
:WordBeg|WordMid
},
127 {sytext
:"fr\0", count
:2, code
:WordBeg|WordMid
},
128 {sytext
:"gr\0", count
:2, code
:WordBeg|WordMid
},
129 {sytext
:"kr\0", count
:2, code
:WordBeg|WordMid
},
130 {sytext
:"b\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
131 {sytext
:"c\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
132 {sytext
:"d\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
133 {sytext
:"f\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
134 {sytext
:"g\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
135 {sytext
:"h\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
136 {sytext
:"j\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
137 {sytext
:"k\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
138 {sytext
:"l\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
139 {sytext
:"m\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
140 {sytext
:"n\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
141 {sytext
:"p\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
142 {sytext
:"r\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
143 {sytext
:"s\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
144 {sytext
:"t\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
145 {sytext
:"v\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
146 {sytext
:"w\0", count
:3, code
:WordBeg|WordMid|WordEnd
},
149 Syllable
[][2] sylls
= [totroSyllsV
, totroSyllsC
];
150 uint[2] totals
= [81, 90];
152 static uint defaultUni (uint max
) @trusted nothrow @nogc {
153 import iv
.prng
.pcg32
;
155 static bool inited
= false;
157 import iv
.prng
.seeder
;
158 prng
.seed(getUlongSeed
, 42);
161 uint res
= prng
.front
%max
; // this is not uniform, but i don't care
166 uint rand (uint min
, uint max
) const @trusted nothrow @nogc {
167 return (genRand
is null ?
defaultUni(max
-min
+1) : genRand(max
-min
+1))+min
;
171 // generate random number, [0..max); max is never uint.max or 0
172 uint delegate (uint max
) @trusted nothrow @nogc genRand
;
175 sylls
[0] = totroSyllsV
.dup
;
176 sylls
[1] = totroSyllsC
.dup
;
182 static immutable Syllable
[56] swSyllsV
= [
183 {sytext
:"ui\0", count
:1, code
:WordMid
},
184 {sytext
:"aea", count
:1, code
:WordBeg
},
185 {sytext
:"ooo", count
:1, code
:WordBeg
},
186 {sytext
:"uee", count
:2, code
:WordMid
},
187 {sytext
:"oe\0", count
:2, code
:WordBeg
},
188 {sytext
:"aee", count
:2, code
:WordBeg
},
189 {sytext
:"aeo", count
:2, code
:WordBeg
},
190 {sytext
:"eeo", count
:2, code
:WordMid
},
191 {sytext
:"oa\0", count
:2, code
:WordBeg
},
192 {sytext
:"eu\0", count
:3, code
:WordMid
},
193 {sytext
:"io\0", count
:3, code
:WordMid
},
194 {sytext
:"ou\0", count
:4, code
:WordMid
},
195 {sytext
:"uo\0", count
:4, code
:WordMid
},
196 {sytext
:"eeu", count
:4, code
:WordMid
},
197 {sytext
:"ooe", count
:4, code
:WordBeg
},
198 {sytext
:"ooi", count
:4, code
:WordBeg
},
199 {sytext
:"ou\0", count
:5, code
:WordBeg
},
200 {sytext
:"eea", count
:5, code
:WordMid
},
201 {sytext
:"aei", count
:5, code
:WordBeg
},
202 {sytext
:"oi\0", count
:6, code
:WordBeg
},
203 {sytext
:"eee", count
:6, code
:WordMid
},
204 {sytext
:"au\0", count
:8, code
:WordMid
},
205 {sytext
:"eei", count
:9, code
:WordMid
},
206 {sytext
:"oee", count
:12, code
:WordMid
},
207 {sytext
:"ie\0", count
:14, code
:WordMid
},
208 {sytext
:"ii\0", count
:14, code
:WordMid
},
209 {sytext
:"aee", count
:15, code
:WordMid
},
210 {sytext
:"eo\0", count
:15, code
:WordMid
},
211 {sytext
:"oo\0", count
:16, code
:WordMid
},
212 {sytext
:"ei\0", count
:16, code
:WordMid
},
213 {sytext
:"oe\0", count
:17, code
:WordMid
},
214 {sytext
:"oa\0", count
:22, code
:WordMid
},
215 {sytext
:"ea\0", count
:25, code
:WordMid
},
216 {sytext
:"aa\0", count
:29, code
:WordMid
},
217 {sytext
:"ae\0", count
:49, code
:WordBeg
},
218 {sytext
:"ai\0", count
:51, code
:WordMid
},
219 {sytext
:"oo\0", count
:54, code
:WordBeg
},
220 {sytext
:"ae\0", count
:55, code
:WordMid
},
221 {sytext
:"ue\0", count
:61, code
:WordMid
},
222 {sytext
:"ia\0", count
:64, code
:WordMid
},
223 {sytext
:"ua\0", count
:69, code
:WordMid
},
224 {sytext
:"ao\0", count
:86, code
:WordMid
},
225 {sytext
:"oi\0", count
:91, code
:WordMid
},
226 {sytext
:"o\0", count
:106, code
:WordBeg
},
227 {sytext
:"e\0", count
:113, code
:WordBeg
},
228 {sytext
:"o\0", count
:130, code
:WordEnd
},
229 {sytext
:"ee\0", count
:152, code
:WordMid
},
230 {sytext
:"i\0", count
:165, code
:WordEnd
},
231 {sytext
:"e\0", count
:455, code
:WordEnd
},
232 {sytext
:"a\0", count
:477, code
:WordBeg
},
233 {sytext
:"u\0", count
:815, code
:WordMid
},
234 {sytext
:"a\0", count
:890, code
:WordEnd
},
235 {sytext
:"o\0", count
:1322, code
:WordMid
},
236 {sytext
:"i\0", count
:1481, code
:WordMid
},
237 {sytext
:"e\0", count
:2376, code
:WordMid
},
238 {sytext
:"a\0", count
:2637, code
:WordMid
},
240 static immutable Syllable
[389] swSyllsC
= [
241 {sytext
:"ntg", count
:1, code
:WordMid
},
242 {sytext
:"yc\0", count
:1, code
:WordMid
},
243 {sytext
:"xg\0", count
:1, code
:WordMid
},
244 {sytext
:"xw\0", count
:1, code
:WordMid
},
245 {sytext
:"tm\0", count
:1, code
:WordMid
},
246 {sytext
:"td\0", count
:1, code
:WordMid
},
247 {sytext
:"sq\0", count
:1, code
:WordMid
},
248 {sytext
:"thh", count
:1, code
:WordMid
},
249 {sytext
:"rrc", count
:1, code
:WordMid
},
250 {sytext
:"yg\0", count
:1, code
:WordMid
},
251 {sytext
:"rdv", count
:1, code
:WordMid
},
252 {sytext
:"ndb", count
:1, code
:WordMid
},
253 {sytext
:"trd", count
:1, code
:WordBeg
},
254 {sytext
:"bv\0", count
:1, code
:WordMid
},
255 {sytext
:"vpr", count
:1, code
:WordMid
},
256 {sytext
:"shr", count
:1, code
:WordMid
},
257 {sytext
:"xhr", count
:1, code
:WordMid
},
258 {sytext
:"dm\0", count
:1, code
:WordMid
},
259 {sytext
:"ndw", count
:1, code
:WordMid
},
260 {sytext
:"sv\0", count
:1, code
:WordMid
},
261 {sytext
:"yd\0", count
:1, code
:WordMid
},
262 {sytext
:"tg\0", count
:1, code
:WordMid
},
263 {sytext
:"ndp", count
:1, code
:WordMid
},
264 {sytext
:"rrn", count
:1, code
:WordMid
},
265 {sytext
:"lfb", count
:1, code
:WordMid
},
266 {sytext
:"sck", count
:1, code
:WordMid
},
267 {sytext
:"bs\0", count
:1, code
:WordMid
},
268 {sytext
:"kdg", count
:1, code
:WordMid
},
269 {sytext
:"ss\0", count
:1, code
:WordMid
},
270 {sytext
:"ntp", count
:1, code
:WordMid
},
271 {sytext
:"xq\0", count
:1, code
:WordMid
},
272 {sytext
:"thv", count
:1, code
:WordMid
},
273 {sytext
:"tb\0", count
:1, code
:WordMid
},
274 {sytext
:"sm\0", count
:1, code
:WordMid
},
275 {sytext
:"ntb", count
:1, code
:WordMid
},
276 {sytext
:"trc", count
:1, code
:WordBeg
},
277 {sytext
:"xs\0", count
:1, code
:WordMid
},
278 {sytext
:"ntc", count
:1, code
:WordMid
},
279 {sytext
:"thw", count
:1, code
:WordMid
},
280 {sytext
:"vg\0", count
:1, code
:WordMid
},
281 {sytext
:"ntd", count
:1, code
:WordMid
},
282 {sytext
:"yt\0", count
:1, code
:WordMid
},
283 {sytext
:"trh", count
:1, code
:WordBeg
},
284 {sytext
:"ryg", count
:1, code
:WordBeg
},
285 {sytext
:"xtr", count
:1, code
:WordMid
},
286 {sytext
:"rrb", count
:1, code
:WordMid
},
287 {sytext
:"sh\0", count
:1, code
:WordMid
},
288 {sytext
:"ryc", count
:1, code
:WordBeg
},
289 {sytext
:"tsy", count
:1, code
:WordMid
},
290 {sytext
:"bk\0", count
:1, code
:WordMid
},
291 {sytext
:"bg\0", count
:1, code
:WordMid
},
292 {sytext
:"lfq", count
:1, code
:WordMid
},
293 {sytext
:"lfg", count
:1, code
:WordMid
},
294 {sytext
:"vv\0", count
:1, code
:WordMid
},
295 {sytext
:"nds", count
:1, code
:WordMid
},
296 {sytext
:"tt\0", count
:1, code
:WordMid
},
297 {sytext
:"rkc", count
:1, code
:WordMid
},
298 {sytext
:"ntw", count
:1, code
:WordMid
},
299 {sytext
:"tck", count
:1, code
:WordMid
},
300 {sytext
:"bb\0", count
:1, code
:WordMid
},
301 {sytext
:"bll", count
:1, code
:WordMid
},
302 {sytext
:"lfn", count
:1, code
:WordMid
},
303 {sytext
:"rkg", count
:1, code
:WordMid
},
304 {sytext
:"rkq", count
:2, code
:WordMid
},
305 {sytext
:"xck", count
:2, code
:WordMid
},
306 {sytext
:"xv\0", count
:2, code
:WordMid
},
307 {sytext
:"ydr", count
:2, code
:WordMid
},
308 {sytext
:"ttr", count
:2, code
:WordMid
},
309 {sytext
:"vc\0", count
:2, code
:WordMid
},
310 {sytext
:"ts\0", count
:2, code
:WordMid
},
311 {sytext
:"trb", count
:2, code
:WordBeg
},
312 {sytext
:"sw\0", count
:2, code
:WordMid
},
313 {sytext
:"tw\0", count
:2, code
:WordMid
},
314 {sytext
:"ryn", count
:2, code
:WordBeg
},
315 {sytext
:"vs\0", count
:2, code
:WordMid
},
316 {sytext
:"yb\0", count
:2, code
:WordMid
},
317 {sytext
:"xt\0", count
:2, code
:WordMid
},
318 {sytext
:"str", count
:2, code
:WordMid
},
319 {sytext
:"kpr", count
:2, code
:WordMid
},
320 {sytext
:"khr", count
:2, code
:WordMid
},
321 {sytext
:"nts", count
:2, code
:WordMid
},
322 {sytext
:"xk\0", count
:2, code
:WordMid
},
323 {sytext
:"rkv", count
:2, code
:WordMid
},
324 {sytext
:"nth", count
:2, code
:WordMid
},
325 {sytext
:"rrl", count
:2, code
:WordMid
},
326 {sytext
:"bhr", count
:2, code
:WordMid
},
327 {sytext
:"ryd", count
:2, code
:WordBeg
},
328 {sytext
:"thc", count
:2, code
:WordMid
},
329 {sytext
:"bdr", count
:2, code
:WordMid
},
330 {sytext
:"sc\0", count
:2, code
:WordMid
},
331 {sytext
:"sl\0", count
:2, code
:WordMid
},
332 {sytext
:"tc\0", count
:2, code
:WordMid
},
333 {sytext
:"rym", count
:2, code
:WordBeg
},
334 {sytext
:"rrg", count
:2, code
:WordMid
},
335 {sytext
:"kq\0", count
:2, code
:WordMid
},
336 {sytext
:"lfl", count
:2, code
:WordMid
},
337 {sytext
:"lfm", count
:2, code
:WordMid
},
338 {sytext
:"thb", count
:2, code
:WordMid
},
339 {sytext
:"vsy", count
:2, code
:WordMid
},
340 {sytext
:"sg\0", count
:2, code
:WordMid
},
341 {sytext
:"lfp", count
:2, code
:WordMid
},
342 {sytext
:"yw\0", count
:2, code
:WordMid
},
343 {sytext
:"rkb", count
:2, code
:WordMid
},
344 {sytext
:"trl", count
:2, code
:WordBeg
},
345 {sytext
:"ryh", count
:2, code
:WordBeg
},
346 {sytext
:"sn\0", count
:2, code
:WordMid
},
347 {sytext
:"rrq", count
:2, code
:WordMid
},
348 {sytext
:"nhr", count
:2, code
:WordMid
},
349 {sytext
:"ysy", count
:2, code
:WordMid
},
350 {sytext
:"thd", count
:2, code
:WordMid
},
351 {sytext
:"ndv", count
:2, code
:WordMid
},
352 {sytext
:"vq\0", count
:2, code
:WordMid
},
353 {sytext
:"db\0", count
:2, code
:WordMid
},
354 {sytext
:"ndh", count
:2, code
:WordMid
},
355 {sytext
:"tk\0", count
:2, code
:WordMid
},
356 {sytext
:"rdp", count
:2, code
:WordMid
},
357 {sytext
:"yck", count
:2, code
:WordMid
},
358 {sytext
:"bdg", count
:2, code
:WordMid
},
359 {sytext
:"dd\0", count
:2, code
:WordMid
},
360 {sytext
:"rrt", count
:2, code
:WordMid
},
361 {sytext
:"kll", count
:2, code
:WordMid
},
362 {sytext
:"thp", count
:2, code
:WordMid
},
363 {sytext
:"xm\0", count
:2, code
:WordMid
},
364 {sytext
:"ntt", count
:2, code
:WordMid
},
365 {sytext
:"xb\0", count
:2, code
:WordMid
},
366 {sytext
:"ds\0", count
:2, code
:WordMid
},
367 {sytext
:"tq\0", count
:2, code
:WordMid
},
368 {sytext
:"rdc", count
:2, code
:WordMid
},
369 {sytext
:"lfv", count
:2, code
:WordMid
},
370 {sytext
:"ym\0", count
:2, code
:WordMid
},
371 {sytext
:"rll", count
:2, code
:WordMid
},
372 {sytext
:"xdr", count
:2, code
:WordMid
},
373 {sytext
:"lfd", count
:2, code
:WordMid
},
374 {sytext
:"rrk", count
:2, code
:WordMid
},
375 {sytext
:"ytr", count
:3, code
:WordMid
},
376 {sytext
:"dk\0", count
:3, code
:WordMid
},
377 {sytext
:"vt\0", count
:3, code
:WordMid
},
378 {sytext
:"dll", count
:3, code
:WordMid
},
379 {sytext
:"tdr", count
:3, code
:WordMid
},
380 {sytext
:"thq", count
:3, code
:WordMid
},
381 {sytext
:"vh\0", count
:3, code
:WordMid
},
382 {sytext
:"ryk", count
:3, code
:WordBeg
},
383 {sytext
:"yh\0", count
:3, code
:WordMid
},
384 {sytext
:"npr", count
:3, code
:WordMid
},
385 {sytext
:"btr", count
:3, code
:WordMid
},
386 {sytext
:"dl\0", count
:3, code
:WordMid
},
387 {sytext
:"vm\0", count
:3, code
:WordMid
},
388 {sytext
:"vdg", count
:3, code
:WordMid
},
389 {sytext
:"lft", count
:3, code
:WordMid
},
390 {sytext
:"thn", count
:3, code
:WordMid
},
391 {sytext
:"kh\0", count
:3, code
:WordMid
},
392 {sytext
:"lfc", count
:3, code
:WordMid
},
393 {sytext
:"ndt", count
:3, code
:WordMid
},
394 {sytext
:"yn\0", count
:3, code
:WordMid
},
395 {sytext
:"trn", count
:3, code
:WordBeg
},
396 {sytext
:"dt\0", count
:3, code
:WordMid
},
397 {sytext
:"ryt", count
:3, code
:WordBeg
},
398 {sytext
:"vb\0", count
:3, code
:WordMid
},
399 {sytext
:"vtr", count
:3, code
:WordMid
},
400 {sytext
:"lfk", count
:3, code
:WordMid
},
401 {sytext
:"ddr", count
:3, code
:WordMid
},
402 {sytext
:"bw\0", count
:4, code
:WordMid
},
403 {sytext
:"bt\0", count
:4, code
:WordMid
},
404 {sytext
:"tht", count
:4, code
:WordMid
},
405 {sytext
:"kg\0", count
:4, code
:WordMid
},
406 {sytext
:"rrw", count
:4, code
:WordMid
},
407 {sytext
:"rrm", count
:4, code
:WordMid
},
408 {sytext
:"rdw", count
:4, code
:WordMid
},
409 {sytext
:"ksy", count
:4, code
:WordMid
},
410 {sytext
:"ndl", count
:4, code
:WordMid
},
411 {sytext
:"sk\0", count
:4, code
:WordMid
},
412 {sytext
:"rdn", count
:4, code
:WordMid
},
413 {sytext
:"rdt", count
:4, code
:WordMid
},
414 {sytext
:"rdm", count
:4, code
:WordMid
},
415 {sytext
:"thm", count
:4, code
:WordMid
},
416 {sytext
:"ntk", count
:4, code
:WordMid
},
417 {sytext
:"dn\0", count
:4, code
:WordMid
},
418 {sytext
:"dc\0", count
:4, code
:WordMid
},
419 {sytext
:"rrh", count
:4, code
:WordMid
},
420 {sytext
:"rkd", count
:4, code
:WordMid
},
421 {sytext
:"rdh", count
:4, code
:WordMid
},
422 {sytext
:"dh\0", count
:4, code
:WordMid
},
423 {sytext
:"nv\0", count
:4, code
:WordMid
},
424 {sytext
:"bm\0", count
:4, code
:WordMid
},
425 {sytext
:"vhr", count
:4, code
:WordMid
},
426 {sytext
:"lfw", count
:4, code
:WordMid
},
427 {sytext
:"trs", count
:4, code
:WordBeg
},
428 {sytext
:"rdb", count
:4, code
:WordMid
},
429 {sytext
:"rks", count
:4, code
:WordMid
},
430 {sytext
:"kb\0", count
:4, code
:WordMid
},
431 {sytext
:"ryb", count
:4, code
:WordBeg
},
432 {sytext
:"rkt", count
:4, code
:WordMid
},
433 {sytext
:"kw\0", count
:5, code
:WordMid
},
434 {sytext
:"vw\0", count
:5, code
:WordMid
},
435 {sytext
:"vd\0", count
:5, code
:WordMid
},
436 {sytext
:"trr", count
:5, code
:WordBeg
},
437 {sytext
:"trk", count
:5, code
:WordBeg
},
438 {sytext
:"ndc", count
:5, code
:WordMid
},
439 {sytext
:"xl\0", count
:5, code
:WordMid
},
440 {sytext
:"nck", count
:5, code
:WordMid
},
441 {sytext
:"rkw", count
:5, code
:WordMid
},
442 {sytext
:"kd\0", count
:5, code
:WordMid
},
443 {sytext
:"rrs", count
:5, code
:WordMid
},
444 {sytext
:"nsy", count
:5, code
:WordMid
},
445 {sytext
:"lsy", count
:5, code
:WordMid
},
446 {sytext
:"bn\0", count
:5, code
:WordMid
},
447 {sytext
:"nll", count
:5, code
:WordMid
},
448 {sytext
:"lfh", count
:5, code
:WordMid
},
449 {sytext
:"thk", count
:5, code
:WordMid
},
450 {sytext
:"ndd", count
:5, code
:WordMid
},
451 {sytext
:"ndm", count
:5, code
:WordMid
},
452 {sytext
:"kt\0", count
:5, code
:WordMid
},
453 {sytext
:"ktr", count
:5, code
:WordMid
},
454 {sytext
:"lpr", count
:5, code
:WordMid
},
455 {sytext
:"trt", count
:6, code
:WordBeg
},
456 {sytext
:"ryl", count
:6, code
:WordBeg
},
457 {sytext
:"ndk", count
:6, code
:WordMid
},
458 {sytext
:"km\0", count
:6, code
:WordMid
},
459 {sytext
:"ntm", count
:6, code
:WordMid
},
460 {sytext
:"rkn", count
:6, code
:WordMid
},
461 {sytext
:"thl", count
:6, code
:WordMid
},
462 {sytext
:"rkh", count
:6, code
:WordMid
},
463 {sytext
:"rkm", count
:6, code
:WordMid
},
464 {sytext
:"bd\0", count
:6, code
:WordMid
},
465 {sytext
:"tl\0", count
:6, code
:WordMid
},
466 {sytext
:"bc\0", count
:6, code
:WordMid
},
467 {sytext
:"rds", count
:6, code
:WordMid
},
468 {sytext
:"yr\0", count
:7, code
:WordMid
},
469 {sytext
:"ndg", count
:7, code
:WordMid
},
470 {sytext
:"rdd", count
:7, code
:WordMid
},
471 {sytext
:"ng\0", count
:7, code
:WordMid
},
472 {sytext
:"rrr", count
:7, code
:WordMid
},
473 {sytext
:"kdr", count
:7, code
:WordMid
},
474 {sytext
:"ntl", count
:7, code
:WordMid
},
475 {sytext
:"nw\0", count
:7, code
:WordMid
},
476 {sytext
:"rkk", count
:7, code
:WordMid
},
477 {sytext
:"yk\0", count
:7, code
:WordMid
},
478 {sytext
:"ryr", count
:7, code
:WordBeg
},
479 {sytext
:"ks\0", count
:7, code
:WordMid
},
480 {sytext
:"bh\0", count
:7, code
:WordMid
},
481 {sytext
:"nh\0", count
:7, code
:WordMid
},
482 {sytext
:"kc\0", count
:8, code
:WordMid
},
483 {sytext
:"lv\0", count
:8, code
:WordMid
},
484 {sytext
:"rdl", count
:8, code
:WordMid
},
485 {sytext
:"kk\0", count
:8, code
:WordMid
},
486 {sytext
:"vk\0", count
:9, code
:WordMid
},
487 {sytext
:"rdg", count
:9, code
:WordMid
},
488 {sytext
:"lll", count
:9, code
:WordMid
},
489 {sytext
:"lq\0", count
:9, code
:WordMid
},
490 {sytext
:"vl\0", count
:9, code
:WordMid
},
491 {sytext
:"rkl", count
:9, code
:WordMid
},
492 {sytext
:"bl\0", count
:9, code
:WordMid
},
493 {sytext
:"yl\0", count
:9, code
:WordMid
},
494 {sytext
:"nb\0", count
:10, code
:WordMid
},
495 {sytext
:"xr\0", count
:10, code
:WordMid
},
496 {sytext
:"lck", count
:10, code
:WordMid
},
497 {sytext
:"kl\0", count
:10, code
:WordMid
},
498 {sytext
:"ldg", count
:10, code
:WordMid
},
499 {sytext
:"nc\0", count
:11, code
:WordMid
},
500 {sytext
:"vn\0", count
:11, code
:WordMid
},
501 {sytext
:"pr\0", count
:12, code
:WordMid
},
502 {sytext
:"rdk", count
:12, code
:WordMid
},
503 {sytext
:"rv\0", count
:12, code
:WordMid
},
504 {sytext
:"hr\0", count
:12, code
:WordMid
},
505 {sytext
:"kn\0", count
:12, code
:WordMid
},
506 {sytext
:"lw\0", count
:12, code
:WordMid
},
507 {sytext
:"lhr", count
:13, code
:WordMid
},
508 {sytext
:"rck", count
:13, code
:WordMid
},
509 {sytext
:"rhr", count
:13, code
:WordMid
},
510 {sytext
:"lg\0", count
:14, code
:WordMid
},
511 {sytext
:"sr\0", count
:14, code
:WordMid
},
512 {sytext
:"lfr", count
:14, code
:WordMid
},
513 {sytext
:"rh\0", count
:14, code
:WordMid
},
514 {sytext
:"thr", count
:15, code
:WordMid
},
515 {sytext
:"br\0", count
:15, code
:WordMid
},
516 {sytext
:"q\0", count
:15, code
:WordMid
},
517 {sytext
:"lf\0", count
:15, code
:WordMid
},
518 {sytext
:"rsy", count
:15, code
:WordMid
},
519 {sytext
:"ld\0", count
:16, code
:WordMid
},
520 {sytext
:"x\0", count
:16, code
:WordMid
},
521 {sytext
:"rs\0", count
:16, code
:WordMid
},
522 {sytext
:"rpr", count
:16, code
:WordMid
},
523 {sytext
:"rc\0", count
:16, code
:WordMid
},
524 {sytext
:"rq\0", count
:17, code
:WordMid
},
525 {sytext
:"rg\0", count
:17, code
:WordMid
},
526 {sytext
:"rkr", count
:18, code
:WordMid
},
527 {sytext
:"ldr", count
:18, code
:WordMid
},
528 {sytext
:"lh\0", count
:18, code
:WordMid
},
529 {sytext
:"ns\0", count
:19, code
:WordMid
},
530 {sytext
:"th\0", count
:20, code
:WordMid
},
531 {sytext
:"sy\0", count
:20, code
:WordMid
},
532 {sytext
:"lb\0", count
:20, code
:WordMid
},
533 {sytext
:"rb\0", count
:20, code
:WordMid
},
534 {sytext
:"ndr", count
:20, code
:WordMid
},
535 {sytext
:"ltr", count
:20, code
:WordMid
},
536 {sytext
:"tr\0", count
:20, code
:WordBeg
},
537 {sytext
:"kr\0", count
:20, code
:WordMid
},
538 {sytext
:"lt\0", count
:21, code
:WordMid
},
539 {sytext
:"rw\0", count
:22, code
:WordMid
},
540 {sytext
:"ck\0", count
:22, code
:WordMid
},
541 {sytext
:"ntr", count
:22, code
:WordMid
},
542 {sytext
:"vr\0", count
:22, code
:WordMid
},
543 {sytext
:"ls\0", count
:22, code
:WordMid
},
544 {sytext
:"ry\0", count
:23, code
:WordBeg
},
545 {sytext
:"nm\0", count
:23, code
:WordMid
},
546 {sytext
:"nt\0", count
:23, code
:WordMid
},
547 {sytext
:"rt\0", count
:24, code
:WordMid
},
548 {sytext
:"nd\0", count
:24, code
:WordMid
},
549 {sytext
:"lc\0", count
:27, code
:WordMid
},
550 {sytext
:"rtr", count
:29, code
:WordMid
},
551 {sytext
:"w\0", count
:30, code
:WordMid
},
552 {sytext
:"rdr", count
:31, code
:WordMid
},
553 {sytext
:"lm\0", count
:31, code
:WordMid
},
554 {sytext
:"nl\0", count
:33, code
:WordMid
},
555 {sytext
:"dg\0", count
:33, code
:WordMid
},
556 {sytext
:"rm\0", count
:34, code
:WordMid
},
557 {sytext
:"ln\0", count
:35, code
:WordMid
},
558 {sytext
:"nk\0", count
:36, code
:WordMid
},
559 {sytext
:"rn\0", count
:37, code
:WordMid
},
560 {sytext
:"ght", count
:46, code
:WordMid
},
561 {sytext
:"g\0", count
:52, code
:WordMid
},
562 {sytext
:"d\0", count
:52, code
:WordEnd
},
563 {sytext
:"rhy", count
:52, code
:WordBeg
},
564 {sytext
:"rd\0", count
:54, code
:WordMid
},
565 {sytext
:"h\0", count
:54, code
:WordMid
},
566 {sytext
:"tyr", count
:55, code
:WordBeg
},
567 {sytext
:"g\0", count
:55, code
:WordEnd
},
568 {sytext
:"c\0", count
:56, code
:WordEnd
},
569 {sytext
:"f\0", count
:57, code
:WordBeg
},
570 {sytext
:"v\0", count
:58, code
:WordMid
},
571 {sytext
:"thr", count
:59, code
:WordBeg
},
572 {sytext
:"cyn", count
:62, code
:WordBeg
},
573 {sytext
:"zs\0", count
:65, code
:WordMid
},
574 {sytext
:"sr\0", count
:67, code
:WordBeg
},
575 {sytext
:"dr\0", count
:67, code
:WordMid
},
576 {sytext
:"x\0", count
:69, code
:WordEnd
},
577 {sytext
:"rch", count
:70, code
:WordMid
},
578 {sytext
:"f\0", count
:72, code
:WordMid
},
579 {sytext
:"try", count
:72, code
:WordBeg
},
580 {sytext
:"dry", count
:75, code
:WordBeg
},
581 {sytext
:"rl\0", count
:79, code
:WordMid
},
582 {sytext
:"rk\0", count
:80, code
:WordMid
},
583 {sytext
:"nr\0", count
:81, code
:WordMid
},
584 {sytext
:"tr\0", count
:85, code
:WordMid
},
585 {sytext
:"nn\0", count
:85, code
:WordMid
},
586 {sytext
:"b\0", count
:95, code
:WordMid
},
587 {sytext
:"g\0", count
:99, code
:WordBeg
},
588 {sytext
:"z\0", count
:110, code
:WordBeg
},
589 {sytext
:"d\0", count
:110, code
:WordBeg
},
590 {sytext
:"kr\0", count
:111, code
:WordBeg
},
591 {sytext
:"b\0", count
:112, code
:WordBeg
},
592 {sytext
:"p\0", count
:114, code
:WordBeg
},
593 {sytext
:"q\0", count
:114, code
:WordBeg
},
594 {sytext
:"lk\0", count
:115, code
:WordMid
},
595 {sytext
:"sky", count
:116, code
:WordBeg
},
596 {sytext
:"y\0", count
:116, code
:WordEnd
},
597 {sytext
:"sh\0", count
:119, code
:WordBeg
},
598 {sytext
:"d\0", count
:134, code
:WordMid
},
599 {sytext
:"lr\0", count
:136, code
:WordMid
},
600 {sytext
:"c\0", count
:149, code
:WordMid
},
601 {sytext
:"ll\0", count
:155, code
:WordMid
},
602 {sytext
:"r\0", count
:166, code
:WordBeg
},
603 {sytext
:"y\0", count
:167, code
:WordMid
},
604 {sytext
:"m\0", count
:171, code
:WordMid
},
605 {sytext
:"h\0", count
:172, code
:WordBeg
},
606 {sytext
:"k\0", count
:173, code
:WordBeg
},
607 {sytext
:"r\0", count
:174, code
:WordEnd
},
608 {sytext
:"w\0", count
:181, code
:WordBeg
},
609 {sytext
:"c\0", count
:187, code
:WordBeg
},
610 {sytext
:"f\0", count
:204, code
:WordEnd
},
611 {sytext
:"rr\0", count
:222, code
:WordMid
},
612 {sytext
:"t\0", count
:224, code
:WordEnd
},
613 {sytext
:"s\0", count
:226, code
:WordMid
},
614 {sytext
:"k\0", count
:248, code
:WordEnd
},
615 {sytext
:"h\0", count
:254, code
:WordEnd
},
616 {sytext
:"j\0", count
:260, code
:WordBeg
},
617 {sytext
:"l\0", count
:282, code
:WordEnd
},
618 {sytext
:"t\0", count
:285, code
:WordMid
},
619 {sytext
:"s\0", count
:329, code
:WordBeg
},
620 {sytext
:"k\0", count
:332, code
:WordMid
},
621 {sytext
:"l\0", count
:476, code
:WordBeg
},
622 {sytext
:"t\0", count
:492, code
:WordBeg
},
623 {sytext
:"n\0", count
:535, code
:WordBeg
},
624 {sytext
:"l\0", count
:536, code
:WordMid
},
625 {sytext
:"m\0", count
:586, code
:WordBeg
},
626 {sytext
:"n\0", count
:780, code
:WordMid
},
627 {sytext
:"r\0", count
:795, code
:WordMid
},
628 {sytext
:"s\0", count
:903, code
:WordEnd
},
629 {sytext
:"n\0", count
:1723, code
:WordEnd
},
631 sylls
[0] = swSyllsV
.dup
;
632 sylls
[1] = swSyllsC
.dup
;
633 totals
= [11979, 16732];
636 bool checkCorrectness() () const @safe nothrow @nogc {
637 foreach (immutable aidx
; 0..sylls
.length
) {
638 if (sylls
[aidx
].length
< 1 || sylls
[aidx
].length
> 0xffff) {
642 if (totals
[aidx
] < 1 || totals
[aidx
] > 0x00ff_ffffu
) {
647 foreach (immutable sy
; sylls
[aidx
]) {
648 if (sy
.code
< 1 || sy
.code
> 7 || sy
.sytext
[0] == 0) {
654 if (hasCodes
!= (WordBeg|WordMid|WordEnd
)) {
662 void clear () @safe nothrow @nogc {
663 sylls
[0] = sylls
[1] = null;
664 totals
[0] = totals
[1] = 0;
667 string
next (int minsyl
=2, int maxsyl
=8) const @trusted nothrow
671 assert(minsyl
<= maxsyl
);
674 auto leng
= rand(minsyl
, maxsyl
);
675 uint iscons
= rand(0, 1);
676 auto res
= new char[](leng
*3);
678 foreach (immutable i
; 0..leng
) {
679 // WARNING: may hang if no termination vowel/consonants are present
680 const(Syllable
)* sy
= null;
682 uint count
= rand(1, totals
[iscons
]);
683 //try { writefln("count=%s, total=%s", count, totals[iscons]); } catch (Exception) {}
684 foreach (immutable idx
; 0..sylls
[iscons
].length
) {
685 auto cc
= sylls
[iscons
][idx
].count
;
689 sy
= &sylls
[iscons
][idx
];
693 if (sy
is null) assert(0, "internal error");
695 if (i
== 0) cde
= WordBeg
;
696 else if (i
== leng
-1) cde
= WordEnd
;
697 if ((sy
.code
&cde
) == 0) sy
= null;
700 foreach (immutable char ch
; sy
.sytext
) {
708 if (res
[0] >= 'a' && res
[0] <= 'z') res
[0] -= 32;
709 return cast(string
)res
[0..respos
];
713 // ////////////////////////////////////////////////////////////////////////// //
714 private void parseText() (const(char)[] text
) {
715 enum MaxSyllableLen
= 2;
716 static assert(MaxSyllableLen
> 0 && MaxSyllableLen
< Syllable
.sytext
.length
, "invalid max syllable length");
718 static usize
isvowel() (immutable char ch
) {
720 ((ch
== 'a' || ch
== 'e' || ch
== 'i' || ch
== 'o' || ch
== 'u') ||
721 (ch
== 'A' || ch
== 'E' || ch
== 'I' || ch
== 'O' || ch
== 'U') ? Vowel
: Consonant
);
724 static bool isalpha() (immutable char ch
) {
726 (ch
>= 'A' && ch
<= 'Z') ||
727 (ch
>= 'a' && ch
<= 'z');
730 while (text
.length
> 0) {
733 while (pos
< text
.length
&& !isalpha(text
[pos
])) ++pos
;
734 if (pos
>= text
.length
) break;
737 while (pos
< text
.length
&& isalpha(text
[pos
])) ++pos
;
738 auto word
= text
[0..pos
];
740 //writeln("[", word, "]");
745 while (word
.length
> 0) {
747 auto vowel
= isvowel(word
[0]);
749 while (pos
< word
.length
&& pos
< MaxSyllableLen
&& isvowel(word
[pos
]) == vowel
) ++pos
;
750 if (pos
== word
.length
) sy
.code |
= WordEnd
;
751 sy
.sytext
[] = 0; // clear array
752 sy
.sytext
[0..pos
] = word
[0..pos
]; // copy syllable
753 foreach (ref ch
; sy
.sytext
) if (ch
>= 'A' && ch
<= 'Z') ch
+= 32;
754 //{ import std.conv : to; writeln("SYL: [", to!string(sy.sytext.ptr), "]"); }
755 // add/fix syllable info
756 if (totals
[vowel
] >= 0x00ff_ffffu
) throw new Exception("too many syllables");
759 foreach (ref sx
; sylls
[vowel
]) {
760 import core
.stdc
.string
: strcmp
;
761 if (sy
.code
== sx
.code
&& strcmp(sy
.sytext
.ptr
, sx
.sytext
.ptr
) == 0) {
767 if (doAdd
) sylls
[vowel
] ~= sy
;
775 public void loadText() (const(char)[] text
) {
776 import std
.algorithm
: sort
;
778 scope(failure
) clear();
780 if (!checkCorrectness()) throw new Exception("incorrect resulting set");
781 foreach (immutable idx
; 0..sylls
.length
) sort
!((ref a
, ref b
) => a
.count
< b
.count
)(sylls
[idx
]);
784 void saveToStream(ST
) (auto ref ST fo
) if (isWriteableStream
!ST
) {
785 fo
.rawWriteExact("SYLLDATA");
786 fo
.writeNum
!ubyte(0); // version
787 foreach (immutable aidx
; 0..sylls
.length
) {
788 fo
.writeNum
!ushort(cast(ushort)sylls
[aidx
].length
); // count
789 foreach (immutable sy
; sylls
[aidx
]) {
790 fo
.writeNum
!ubyte(cast(ubyte)sy
.str.length
);
791 fo
.rawWriteExact(sy
.str);
792 uint cc
= sy
.count|
(sy
.code
<<24);
793 fo
.writeNum
!uint(cc
);
798 void loadFromStream(ST
) (auto ref ST st
) if (isReadableStream
!ST
) {
800 scope(failure
) clear();
802 st
.rawReadExact(sign
);
803 if (sign
!= "SYLLDATA") throw new Exception("invalid signature");
804 if (st
.readNum
!ubyte() != 0) throw new Exception("invalid version");
805 foreach (immutable aidx
; 0..sylls
.length
) {
806 auto len
= st
.readNum
!ushort();
807 if (len
< 1) throw new Exception("invalid length");
808 sylls
[aidx
].length
= len
;
809 foreach (ref sy
; sylls
[aidx
]) {
810 auto slen
= st
.readNum
!ubyte();
811 if (slen
< 1 || slen
> 3) throw new Exception("invalid syllable length");
813 st
.rawReadExact(sy
.sytext
[0..slen
]);
814 uint cc
= st
.readNum
!uint();
815 sy
.code
= (cc
>>24)&0xff;
816 if (sy
.code
< 1 || sy
.code
> 7) throw new Exception("invalid syllable code");
817 sy
.count
= cc
&0x00ff_ffffu
;
818 if (sy
.count
< 1) throw new Exception("invalid syllable count");
819 uint ntot
= cast(uint)(totals
[aidx
]+sy
.count
);
820 if (ntot
<= totals
[aidx
] || ntot
> 0x00ff_ffffu
) throw new Exception("invalid syllable total");
824 if (!checkCorrectness()) throw new Exception("invalid syllable data");
827 string
infoStr() () const {
829 return format("%s vowels and %s consonants grouped into {%s, %s} rules", totals
[Vowel
], totals
[Consonant
], sylls
[Vowel
].length
, sylls
[Consonant
].length
);
833 import std
.stdio
: File
;
834 void dumpToFile (File fo
, string name
="table") {
835 fo
.writeln(" // [", totals
[0], ", ", totals
[1], "]");
836 foreach (immutable sidx
; 0..sylls
.length
) {
837 fo
.writeln(" static immutable Syllable[", sylls
[sidx
].length
, "] ", name
, (sidx ?
"C" : "V"), " = [");
838 foreach (immutable sy
; sylls
[sidx
]) {
840 if (s
.length
< 3) s
~= `\0`;
841 fo
.writeln(" {sytext:\"", s
, "\", count:", sy
.count
, ", code:", sy
.codeStr
, "},");
850 version(test_namegen
)
854 //ng.loadFromStream(File("names.syl"));
855 //ng.loadText(readText("names.txt"));
856 //ng.saveToStream(File("names.syl", "w"));
857 writeln("==========="); foreach (immutable _
; 0..10) writeln(ng
.next
, " ", ng
.next
);
859 writeln("==========="); foreach (immutable _
; 0..10) writeln(ng
.next
, " ", ng
.next
);
861 writeln("==========="); foreach (immutable _
; 0..10) writeln(ng
.next
, " ", ng
.next
);