+ Reply to Thread
Results 1 to 3 of 3

Thread: Java: Random Name Generator

  1. #1
    Sinipull's Avatar
    Sinipull is offline Programming Expert
    Join Date
    Jun 2009
    Location
    Tallinn, Estonia, Estonia
    Posts
    382
    Rep Power
    13

    Java: Random Name Generator

    Description: This class generates random names from syllables, and provides programmer a simple way to set a group of rules for generator to avoid unpronounceable and bizarre names.

    SYLLABLE FILE REQUIREMENTS/FORMAT:
    1) all syllables are separated by line break.
    2) Syllable should not contain or start with whitespace, as this character is ignored and only first part of the syllable is read.
    3) + and - characters are used to set rules, and using them in other way, may result in unpredictable results.
    4) Empty lines are ignored.

    SYLLABLE CLASSIFICATION:
    Name is usually composed from 3 different class of syllables, which include prefix, middle part and suffix.
    To declare syllable a prefix in the file, insert "-" as a first character of the line.
    To declare syllable a suffix in the file, insert "+" as a first character of the line.
    everything else is read as middle part.

    NUMBER OF SYLLABLES:
    Names may have any positive number of syllables. In case of 2 syllables, name will be composed from prefix and suffix.
    In case of 1 syllable, name will be chosen from amongst the prefixes.
    In case of 3 and more syllables, name will begin with prefix, is filled with middle parts and ended with suffix.

    ASSIGNING RULES:

    I included a way to set 4 kind of rules for every syllable. To add rules to the syllables, write them right after the syllable and SEPARATE WITH WHITESPACE. (example: "aad +v -c"). The order of rules is not important.

    RULES:

    1) +v means that next syllable must definitely start with a wovel.
    2) +c means that next syllable must definitely start with a consonant.
    3) -v means that this syllable can only added to another syllable, that ends with a wovel.
    4) -c means that this syllable can only added to another syllable, that ends with a consonant.
    So, our example: "aad +v -c" means that "aad" can only be after consonant and next syllable must start with wovel.
    Beware of creating logical mistakes, like providing only syllables ending with consonants, but expecting only wovels, which will be detected and RuntimeException will be thrown.

    TO START:
    Create a new NameGenerator object, provide the syllable file, and create names using compose() method.

    EXAMPLE SYLLABLE FILE (Roman Names):
    Code:
    -a
    -al
    -au +c
    -an
    -ba
    -be
    -bi
    -br +v
    -da
    -di
    -do
    -du
    -e
    -eu +c
    -fa
    bi
    be
    bo
    bu
    nul +v
    gu
    da
    au +c -c
    fri
    gus
    +tus
    +lus
    +lius
    +nus
    +es
    +ius -c
    +cus
    +tor
    +cio
    +tin
    and results:

    Code:
    Aubicio
    Bebecus
    Batin
    Baes
    Alboes
    Dubilius
    Banus
    Alcus
    Beguslius
    Dinules
    Dubecio
    Beguses
    Belus
    Bibinus
    Dibilius
    Dacus
    Antin
    Braulius
    Dobotor
    Eucio
    Dutus
    EXAMPLE SYLLABLE FILE (Elven Names):
    Code:
    -Ael
    -Aer
    -af
    -ah
    -am
    -ama
    -an
    -ang +v
    -ansr +v
    -cael
    -dae +c
    -dho
    -eir
    -fi
    -fir
    -la
    -seh
    -sel
    -ev
    -fis
    -hu
    -ha
    -gar
    -gil
    -ka
    -kan
    -ya
    -za
    -zy
    -mara
    -mai +c
    -lue +c
    -ny
    -she
    -sum
    -syl
    ae +c -c
    ael -c
    dar
    deth +v
    dre -v
    drim -v
    dul
    ean -c
    el
    emar
    hal
    iat -c
    mah
    ten
    que -v +c
    ria
    rail
    ther
    thus
    thi
    san
    +ael -c
    +dar
    +deth
    +dre
    +drim
    +dul
    +ean -c
    +el
    +emar
    +nes
    +nin
    +oth
    +hal
    +iat
    +mah
    +ten
    +ther
    +thus
    +thi
    +ran
    +ath
    +ess
    +san
    +yth
    +las
    +lian
    +evar
    and results:
    Code:
    Amaelran
    Kaemaroth
    Shedul
    Kathi
    Aftenlas
    Ansraellas
    Angevar
    Aerten
    Caeltennes
    Ladreevar
    Aerlas
    Evel
    Maiquelian
    Evraildar
    Ahlas
    Zyran
    Ahsanten
    Shethernes
    Sylsan
    Sheran
    Hutenmah
    Fimahlian
    Nyoth
    Kanael
    Luedullian
    Fiemardeth
    Syldul
    Seldar
    And here's the code. Enjoy
    Code:
    package ee.joonas;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    
    /**
     * This class is released under GNU general public license
     * 
     * Description: This class generates random names from syllables, and provides programmer a 
     * simple way to set a group of rules for generator to avoid unpronounceable and bizarre names. 
     * 
     * SYLLABLE FILE REQUIREMENTS/FORMAT: 
     * 1) all syllables are separated by line break. 
     * 2) Syllable should not contain or start with whitespace, as this character is ignored and only first part of the syllable is read. 
     * 3) + and - characters are used to set rules, and using them in other way, may result in unpredictable results.
     * 4) Empty lines are ignored.
     * 
     * SYLLABLE CLASSIFICATION:
     * Name is usually composed from 3 different class of syllables, which include prefix, middle part and suffix. 
     * To declare syllable as a prefix in the file, insert "-" as a first character of the line.  
     * To declare syllable as a suffix in the file, insert "+" as a first character of the line.  
     * everything else is read as a middle part.
     * 
     * NUMBER OF SYLLABLES: 
     * Names may have any positive number of syllables. In case of 2 syllables, name will be composed from prefix and suffix. 
     * In case of 1 syllable, name will be chosen from amongst the prefixes.
     * In case of 3 and more syllables, name will begin with prefix, is filled with middle parts and ended with suffix.
     * 
     * ASSIGNING RULES:
     * I included a way to set 4 kind of rules for every syllable. To add rules to the syllables, write them right after the 
     * syllable and SEPARATE WITH WHITESPACE. (example: "aad +v -c"). The order of rules is not important.
     * 
     * RULES:
     * 1) +v means that next syllable must definitely start with a Vowel.
     * 2) +c means that next syllable must definitely start with a consonant.
     * 3) -v means that this syllable can only be added to another syllable, that ends with a Vowel.
     * 4) -c means that this syllable can only be added to another syllable, that ends with a consonant.
     * So, our example: "aad +v -c" means that "aad" can only be after consonant and next syllable must start with Vowel.
     * Beware of creating logical mistakes, like providing only syllables ending with consonants, but expecting only Vowels, which will be detected 
     * and RuntimeException will be thrown.
     * 
     * TO START:
     * Create a new NameGenerator object, provide the syllable file, and create names using compose() method.
     * 
     *
     */
    public class NameGenerator {
        ArrayList<String> pre = new ArrayList<String>();
        ArrayList<String> mid = new ArrayList<String>();
        ArrayList<String> sur = new ArrayList<String>();
        
        final private static char[] Vowels = {'a', 'e', 'i', 'o', 'u', '&#228;', '&#246;', '&#245;', '&#252;', 'y'};
        final private static char[] consonants = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p',    'q', 'r', 's', 't', 'v', 'w', 'x', 'y'};
        
        private String fileName;
        
        /**
         * Create new random name generator object. refresh() is automatically called.
         * @param fileName insert file name, where syllables are located
         * @throws IOException
         */
        public NameGenerator(String fileName) throws IOException{
            this.fileName = fileName;
            refresh();
        }
        
        /**
         * Change the file. refresh() is automatically called during the process.
         * @param fileName insert the file name, where syllables are located.
         * @throws IOException
         */
        public void changeFile(String fileName) throws IOException{
            if(fileName == null) throw new IOException("File name cannot be null");
            this.fileName = fileName;
            refresh();
        }
        
        /**
         * Refresh names from file. No need to call that method, if you are not changing the file during the operation of program, as this method
         * is called every time file name is changed or new NameGenerator object created.
         * @throws IOException
         */
        public void refresh() throws IOException{
            
            FileReader input = null;
            BufferedReader bufRead;
            String line;
            
            input = new FileReader(fileName);
            
            bufRead = new BufferedReader(input);
            line="";   
                  
            while(line != null){        
                line = bufRead.readLine();        
                if(line != null && !line.equals("")){
                    if(line.charAt(0) == '-'){
                        pre.add(line.substring(1).toLowerCase());                    
                    }
                    else if(line.charAt(0) == '+'){
                        sur.add(line.substring(1).toLowerCase());                    
                    }
                    else{ 
                        mid.add(line.toLowerCase());                    
                    }
                }
            }        
            bufRead.close();
        }
            
        private String upper(String s){
            return s.substring(0,1).toUpperCase().concat(s.substring(1));
        }
        
        private boolean containsConsFirst(ArrayList<String> array){
            for(String s: array){
                if(consonantFirst(s)) return true;
            }
            return false;
        }
        
        private boolean containsVocFirst(ArrayList<String> array){
            for(String s: array){
                if(VowelFirst(s)) return true;
            }
            return false;
        }
        
        private boolean allowCons(ArrayList<String> array){
            for(String s: array){
                if(hatesPreviousVowels(s) || hatesPreviousConsonants(s) == false) return true;
            }
            return false;
        }
        
        private boolean allowVocs(ArrayList<String> array){
            for(String s: array){
                if(hatesPreviousConsonants(s) || hatesPreviousVowels(s) == false) return true;
            }
            return false;
        }
        
        private boolean expectsVowel(String s){
            if(s.substring(1).contains("+v")) return true;
            else return false;
        }
        private boolean expectsConsonant(String s){
            if(s.substring(1).contains("+c")) return true;
            else return false;        
        }
        private boolean hatesPreviousVowels(String s){
            if(s.substring(1).contains("-c")) return true;
            else return false;
        }
        private boolean hatesPreviousConsonants(String s){
            if(s.substring(1).contains("-v")) return true;
            else return false;        
        }    
        
        private String pureSyl(String s){
            s = s.trim();
            if(s.charAt(0) == '+' || s.charAt(0) == '-') s = s.substring(1);
            return s.split(" ")[0];
        }
        
        private boolean VowelFirst(String s){
            return (String.copyValueOf(Vowels).contains(String.valueOf(s.charAt(0)).toLowerCase()));        
        }
        
        private boolean consonantFirst(String s){
            return (String.copyValueOf(consonants).contains(String.valueOf(s.charAt(0)).toLowerCase()));        
        }
        
        private boolean VowelLast(String s){
            return (String.copyValueOf(Vowels).contains(String.valueOf(s.charAt(s.length()-1)).toLowerCase()));        
        }
        
        private boolean consonantLast(String s){
            return (String.copyValueOf(consonants).contains(String.valueOf(s.charAt(s.length()-1)).toLowerCase()));        
        }
        
        
        /**
         * Compose a new name.
         * @param syls The number of syllables used in name.
         * @return Returns composed name as a String
         * @throws RuntimeException when logical mistakes are detected inside chosen file, and program is unable to complete the name.
         */
        public String compose(int syls){
            if(syls > 2 && mid.size() == 0) throw new RuntimeException("You are trying to create a name with more than 3 parts, which requires middle parts, " +
                    "which you have none in the file "+fileName+". You should add some. Every word, which doesn't have + or - for a prefix is counted as a middle part.");
            if(pre.size() == 0) throw new RuntimeException("You have no prefixes to start creating a name. add some and use \"-\" prefix, to identify it as a prefix for a name. (example: -asd)");
            if(sur.size() == 0) throw new RuntimeException("You have no suffixes to end a name. add some and use \"+\" prefix, to identify it as a suffix for a name. (example: +asd)");
            if(syls < 1) throw new RuntimeException("compose(int syls) can't have less than 1 syllable");
            int expecting = 0; // 1 for Vowel, 2 for consonant
            int last = 0; // 1 for Vowel, 2 for consonant
            String name;
            int a = (int)(Math.random() * pre.size());
            
            if(VowelLast(pureSyl(pre.get(a)))) last = 1;
            else last = 2;
            
            if(syls > 2){
                if(expectsVowel(pre.get(a))){ 
                    expecting = 1;                
                    if(containsVocFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with Vowel, " +
                            "but there is none. You should add one, or remove requirement for one.. "); 
                }
                if(expectsConsonant(pre.get(a))){ 
                    expecting = 2;                
                    if(containsConsFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with consonant, " +
                    "but there is none. You should add one, or remove requirement for one.. "); 
                }
            }
            else{
                if(expectsVowel(pre.get(a))){ 
                    expecting = 1;                
                    if(containsVocFirst(sur) == false) throw new RuntimeException("Expecting \"suffix\" part starting with Vowel, " +
                            "but there is none. You should add one, or remove requirement for one.. "); 
                }
                if(expectsConsonant(pre.get(a))){ 
                    expecting = 2;                
                    if(containsConsFirst(sur) == false) throw new RuntimeException("Expecting \"suffix\" part starting with consonant, " +
                    "but there is none. You should add one, or remove requirement for one.. "); 
                }
            }
            if(VowelLast(pureSyl(pre.get(a))) && allowVocs(mid) == false) throw new RuntimeException("Expecting \"middle\" part that allows last character of prefix to be a Vowel, " +
            "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the prefix used, was : \""+pre.get(a)+"\", which" +
            "means there should be a part available, that has \"-v\" requirement or no requirements for previous syllables at all.");
            
            if(consonantLast(pureSyl(pre.get(a))) && allowCons(mid) == false) throw new RuntimeException("Expecting \"middle\" part that allows last character of prefix to be a consonant, " +
            "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the prefix used, was : \""+pre.get(a)+"\", which" +
            "means there should be a part available, that has \"-c\" requirement or no requirements for previous syllables at all.");
            
            int b[] = new int[syls];
            for(int i = 0; i<b.length-2; i++){
                            
                do{
                    b[i] = (int)(Math.random() * mid.size());
                    //System.out.println("exp " +expecting+" VowelF:"+VowelFirst(mid.get(b[i]))+" syl: "+mid.get(b[i]));
                }            
                while(expecting == 1 && VowelFirst(pureSyl(mid.get(b[i]))) == false || expecting == 2 && consonantFirst(pureSyl(mid.get(b[i]))) == false 
                        || last == 1 && hatesPreviousVowels(mid.get(b[i])) || last == 2 && hatesPreviousConsonants(mid.get(b[i])));
                
                expecting = 0;
                if(expectsVowel(mid.get(b[i]))){ 
                    expecting = 1;                
                    if(i < b.length-3 && containsVocFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with Vowel, " +
                            "but there is none. You should add one, or remove requirement for one.. "); 
                    if(i == b.length-3 && containsVocFirst(sur) == false) throw new RuntimeException("Expecting \"suffix\" part starting with Vowel, " +
                    "but there is none. You should add one, or remove requirement for one.. "); 
                }
                if(expectsConsonant(mid.get(b[i]))){ 
                    expecting = 2;                
                    if(i < b.length-3 && containsConsFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with consonant, " +
                    "but there is none. You should add one, or remove requirement for one.. "); 
                    if(i == b.length-3 && containsConsFirst(sur) == false) throw new RuntimeException("Expecting \"suffix\" part starting with consonant, " +
                    "but there is none. You should add one, or remove requirement for one.. "); 
                }
                if(VowelLast(pureSyl(mid.get(b[i]))) && allowVocs(mid) == false && syls > 3) throw new RuntimeException("Expecting \"middle\" part that allows last character of last syllable to be a Vowel, " +
                        "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the part used, was : \""+mid.get(b[i])+"\", which " +
                        "means there should be a part available, that has \"-v\" requirement or no requirements for previous syllables at all."); 
                        
                if(consonantLast(pureSyl(mid.get(b[i]))) && allowCons(mid) == false && syls > 3) throw new RuntimeException("Expecting \"middle\" part that allows last character of last syllable to be a consonant, " +
                        "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the part used, was : \""+mid.get(b[i])+"\", which " +
                        "means there should be a part available, that has \"-c\" requirement or no requirements for previous syllables at all.");
                if(i == b.length-3){                
                    if(VowelLast(pureSyl(mid.get(b[i]))) && allowVocs(sur) == false) throw new RuntimeException("Expecting \"suffix\" part that allows last character of last syllable to be a Vowel, " +
                            "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the part used, was : \""+mid.get(b[i])+"\", which " +
                            "means there should be a suffix available, that has \"-v\" requirement or no requirements for previous syllables at all."); 
                            
                    if(consonantLast(pureSyl(mid.get(b[i]))) && allowCons(sur) == false) throw new RuntimeException("Expecting \"suffix\" part that allows last character of last syllable to be a consonant, " +
                            "but there is none. You should add one, or remove requirements that cannot be fulfilled.. the part used, was : \""+mid.get(b[i])+"\", which " +
                            "means there should be a suffix available, that has \"-c\" requirement or no requirements for previous syllables at all.");
                }
                if(VowelLast(pureSyl(mid.get(b[i])))) last = 1;
                else last = 2;
            }        
            
            int c;
            do{
                c = (int)(Math.random() * sur.size());                    
            }            
            while(expecting == 1 && VowelFirst(pureSyl(sur.get(c))) == false || expecting == 2 && consonantFirst(pureSyl(sur.get(c))) == false 
                    || last == 1 && hatesPreviousVowels(sur.get(c)) || last == 2 && hatesPreviousConsonants(sur.get(c)));
            
            name = upper(pureSyl(pre.get(a).toLowerCase()));        
            for(int i = 0; i<b.length-2; i++){
                name = name.concat(pureSyl(mid.get(b[i]).toLowerCase()));            
            }
            if(syls > 1)
                name = name.concat(pureSyl(sur.get(c).toLowerCase()));
            return name;        
        }    
    }
    Download:
    UPLOAD.EE - Download NameGenerator.java

    EDIT: Fixed a bug, that caused program to think suffixes and prefixes starting with c or v were rules.
    Last edited by Sinipull; 11-08-2011 at 10:09 AM.

  2. CODECALL Circuit advertisement
    Join Date
    Always
    Location
    Advertising world
    Posts
    Many

     
  3. #2
    TheSnail is offline Newbie
    Join Date
    Oct 2010
    Posts
    1
    Rep Power
    0

    Re: Java: Random Name Generator

    Okay, this is a stupid question.. but how do I get the path to my assets folder? I've copied one of your example files and put the .txt in /assets, but every time I call new NameGenerator("assets/example.txt").compose(x) I get a FileNotFoundException.

    I love your code, btw.. very convenient! If only I could figure this out!

  4. #3
    DevFromParis is offline Newbie
    Join Date
    May 2011
    Posts
    1
    Rep Power
    0

    Re: Java: Random Name Generator

    Cool.

    I had interesting result :

    Anus
    Africio
    Fagucio
    Eucus
    Betus
    Aulus
    Danulius
    Balius
    Dicus
    Betor

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Beginner Random insult generator!
    By Demon in forum Visual Basic Tutorials
    Replies: 3
    Last Post: 10-05-2010, 03:35 AM
  2. Random Password Generator
    By Sauce in forum Visual Basic Programming
    Replies: 13
    Last Post: 06-25-2009, 02:57 PM
  3. random number generator
    By chili5 in forum JavaScript and CSS
    Replies: 4
    Last Post: 06-01-2008, 04:55 AM
  4. Random Name Generator
    By DevilsCharm in forum C and C++
    Replies: 1
    Last Post: 11-07-2007, 09:38 PM
  5. How do I program a random generator?
    By eddiewillers in forum General Programming
    Replies: 4
    Last Post: 07-24-2007, 12:26 PM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts