+ Reply to Thread
Results 1 to 1 of 1

Thread: Java: Random Name Generator

  1. #1
    Programmer Sinipull will become famous soon enough Sinipull's Avatar
    Join Date
    Jun 2009
    Location
    Estonia
    Age
    21
    Posts
    168

    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 vocal.
    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 vocal.
    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 vocal.
    Beware of creating logical mistakes, like providing only syllables ending with consonants, but expecting only vocals, which will be detected and RuntimeException will be thrown.

    TO START:
    Create a new GenName 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:
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    
    /**
     * 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 vocal.
     * 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 vocal.
     * 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 vocal.
     * Beware of creating logical mistakes, like providing only syllables ending with consonants, but expecting only vocals, which will be detected 
     * and RuntimeException will be thrown.
     * 
     * TO START:
     * Create a new GenName object, provide the syllable file, and create names using compose() method.
     * 
     * @author Joonas Vali, August 2009. 
     *
     */
    public class GenName {
    	ArrayList<String> pre = new ArrayList<String>();
    	ArrayList<String> mid = new ArrayList<String>();
    	ArrayList<String> sur = new ArrayList<String>();
    	
    	private static char[] vocals = {'a', 'e', 'i', 'o', 'u', 'õ', 'ä', 'ö', 'ü', 'y'};
    	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 GenName(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 GenName 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(vocalFirst(s)) return true;
    		}
    		return false;
    	}
    	
    	private boolean allowCons(ArrayList<String> array){
    		for(String s: array){
    			if(hatesPreviousVocals(s) || hatesPreviousConsonants(s) == false) return true;
    		}
    		return false;
    	}
    	
    	private boolean allowVocs(ArrayList<String> array){
    		for(String s: array){
    			if(hatesPreviousConsonants(s) || hatesPreviousVocals(s) == false) return true;
    		}
    		return false;
    	}
    	
    	private boolean expectsVocal(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 hatesPreviousVocals(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 vocalFirst(String s){
    		return (String.copyValueOf(vocals).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 vocalLast(String s){
    		return (String.copyValueOf(vocals).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 vocal, 2 for consonant
    		int last = 0; // 1 for vocal, 2 for consonant
    		String name;
    		int a = (int)(Math.random() * pre.size());
    		
    		if(vocalLast(pureSyl(pre.get(a)))) last = 1;
    		else last = 2;
    		
    		if(syls > 2){
    			if(expectsVocal(pre.get(a))){ 
    				expecting = 1;				
    				if(containsVocFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with vocal, " +
    						"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(expectsVocal(pre.get(a))){ 
    				expecting = 1;				
    				if(containsVocFirst(sur) == false) throw new RuntimeException("Expecting \"suffix\" part starting with vocal, " +
    						"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(vocalLast(pureSyl(pre.get(a))) && allowVocs(mid) == false) throw new RuntimeException("Expecting \"middle\" part that allows last character of prefix to be a vocal, " +
    		"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+" vocalF:"+vocalFirst(mid.get(b[i]))+" syl: "+mid.get(b[i]));
    			}			
    			while(expecting == 1 && vocalFirst(pureSyl(mid.get(b[i]))) == false || expecting == 2 && consonantFirst(pureSyl(mid.get(b[i]))) == false 
    					|| last == 1 && hatesPreviousVocals(mid.get(b[i])) || last == 2 && hatesPreviousConsonants(mid.get(b[i])));
    			
    			expecting = 0;
    			if(expectsVocal(mid.get(b[i]))){ 
    				expecting = 1;				
    				if(i < b.length-3 && containsVocFirst(mid) == false) throw new RuntimeException("Expecting \"middle\" part starting with vocal, " +
    						"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 vocal, " +
    				"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(vocalLast(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 vocal, " +
    					"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(vocalLast(pureSyl(mid.get(b[i]))) && allowVocs(sur) == false) throw new RuntimeException("Expecting \"suffix\" part that allows last character of last syllable to be a vocal, " +
    						"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(vocalLast(pureSyl(mid.get(b[i])))) last = 1;
    			else last = 2;
    		}		
    		
    		int c;
    		do{
    			c = (int)(Math.random() * sur.size());					
    		}			
    		while(expecting == 1 && vocalFirst(pureSyl(sur.get(c))) == false || expecting == 2 && consonantFirst(pureSyl(sur.get(c))) == false 
    				|| last == 1 && hatesPreviousVocals(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 GenName.java

    EDIT: Fixed a bug, that caused program to think suffixes and prefixes starting with c or v were rules.
    Last edited by Sinipull; 08-06-2009 at 04:25 AM.

+ 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. Tutorial: Starting Java Using Netbeans
    By Jordan in forum Java Tutorials
    Replies: 4
    Last Post: 02-27-2010, 05:20 PM
  2. Need Help Creating A Random Generator
    By KingCrimson250 in forum PHP Forum
    Replies: 4
    Last Post: 06-21-2009, 11:08 AM
  3. Kill process by command name
    By mop in forum Linux Installation & Configuration
    Replies: 4
    Last Post: 02-16-2009, 07:21 PM
  4. random number generator
    By chili5 in forum JavaScript and CSS
    Replies: 4
    Last Post: 06-01-2008, 06:55 AM
  5. How do I program a random generator?
    By eddiewillers in forum General Programming
    Replies: 4
    Last Post: 07-24-2007, 02:26 PM

Bookmarks

Bookmarks

     
        Algorithms and Data Structures

        Java tutorials

        Algorithms Forum

Posting Permissions

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