wl_lib_0.1.3_1c94dc7c/src/wl-random-names.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
with Ada.Characters.Handling;
with Ada.Text_IO;

package body WL.Random.Names is

   ------------------
   -- Load_Lexicon --
   ------------------

   function Load_Lexicon
     (Vowels_Path     : String;
      Consonants_Path : String)
      return Name_Generator
   is
   begin
      return Gen : Name_Generator do
         Load_Lexicon (Gen, Vowels_Path, Consonants_Path);
      end return;
   end Load_Lexicon;

   ------------------
   -- Load_Lexicon --
   ------------------

   procedure Load_Lexicon
     (Generator       :    out Name_Generator;
      Vowels_Path     : String;
      Consonants_Path : String)
   is
      procedure Load_Info
        (Path   : String;
         Target : in out Lexeme_Info_Vectors.Vector'Class);

      ---------------
      -- Load_Info --
      ---------------

      procedure Load_Info
        (Path   : String;
         Target : in out Lexeme_Info_Vectors.Vector'Class)
      is
         use Ada.Text_IO;
         File : File_Type;
      begin
         Open (File, In_File, Path);
         while not End_Of_File (File) loop
            declare
               Full_Line : constant String := Get_Line (File);
               Last_CR   : constant Boolean :=
                             Full_Line'Length > 0
                                 and then Character'Pos
                                   (Full_Line (Full_Line'Last)) = 13;
               Line      : constant String :=
                             (if Last_CR
                              then Full_Line
                                (Full_Line'First .. Full_Line'Last - 1)
                              else Full_Line);
               Lex  : constant String := Line (Line'First + 1 .. Line'Last);
               Flags : constant Natural :=
                         Natural'Value (Line (Line'First .. Line'First));
               Info  : Lexeme_Info;
            begin
               Info.Can_End := Flags mod 2 = 1;
               Info.Can_Begin := (Flags / 2) mod 2 = 1;
               Info.Can_Middle := (Flags / 4) mod 2 = 1;
               Info.Lexeme (1 .. Lex'Length) := Lex;
               Target.Append (Info);
            end;
         end loop;
         Close (File);
      end Load_Info;

   begin
      Load_Info (Vowels_Path, Generator.Vowels);
      Load_Info (Consonants_Path, Generator.Consonants);
   end Load_Lexicon;

   -----------------
   -- Random_Name --
   -----------------

   function Random_Name
     (Generator : Name_Generator)
      return String
   is
      Next_Is_Vowel : Boolean := Random_Number (1, 2) = 1;
      Syllable_Count : constant Positive := Random_Number (3, 5);
      Name_Length    : Natural := 0;
      Name           : String (1 .. Syllable_Count * 3);
   begin
      for I in 1 .. Syllable_Count loop
         loop
            declare
               Info : constant Lexeme_Info :=
                        (if Next_Is_Vowel
                         then Generator.Vowels
                           (Random_Number (1, Generator.Vowels.Last_Index))
                         else Generator.Consonants
                           (Random_Number
                              (1, Generator.Consonants.Last_Index)));
               OK   : Boolean;
            begin
               if I = 1 then
                  OK := Info.Can_Begin;
               elsif I = Syllable_Count then
                  OK := Info.Can_End;
               else
                  OK := Info.Can_Middle;
               end if;

               if OK then
                  for I in Info.Lexeme'Range loop
                     exit when Info.Lexeme (I) = ' ';
                     Name_Length := Name_Length + 1;
                     Name (Name_Length) := Info.Lexeme (I);
                  end loop;
                  exit;
               end if;
            end;
         end loop;

         Next_Is_Vowel := not Next_Is_Vowel;

      end loop;

      Name (1) := Ada.Characters.Handling.To_Upper (Name (1));
      return Name (1 .. Name_Length);

   end Random_Name;

end WL.Random.Names;