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