Planeshift
|
00001 /* 00002 * namegenerator.h by Andrew Mann <amann tccgi.com> 00003 * 00004 * Copyright (C) 2003 Atomic Blue ([email protected], http://www.atomicblue.org) 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation (version 2 of the License) 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #ifndef __NAMEGENERATOR_H__ 00020 #define __NAMEGENERATOR_H__ 00021 00022 00023 #include <csutil/parray.h> 00024 #include <csutil/randomgen.h> 00025 00026 struct iObjectRegistry; 00027 00033 /* Name generation functions. 00034 * These classes allow for generation of random names. 00035 * 00036 * The current implementation uses a table of phonetic spellings for the english language. 00037 * 00038 * Usage: 00039 * 00040 * Create a new NameGenerationSystem() after the database connection has been established. 00041 * Call NameGenerationSystem::GenerateName(TYPE,csString *namebuffer,max_low,max_high). 00042 * On return, the passed csString will be filled with the name as requested. 00043 * 00044 * The type should be one of the enum below. Currently: 00045 * NAMEGENERATOR_FEMALE_FIRST_NAME 00046 * NAMEGENERATOR_MALE_FIRST_NAME 00047 * NAMEGENERATOR_FAMILY_NAME 00048 * 00049 * max_low and max_high are not hard maximums. Rather, a random number is picked between low and high. As name generation progresses, if 00050 * the length of the name exceeds this number, and ending sequence is added. The resulting string will be 1-9 characters longer than the 00051 * number picked. 00052 * 00053 * Some rough guidelines and notes: 00054 * 00055 * Male names seem to come out much better when shorter. Try max_low = 3 and max_high = 5 for male first names. 00056 * Female names seem to work well with max_low=7 max_high=7 . 00057 * Surnames (family names) work ok with 8,10 . 00058 * 00059 * 00060 * 00061 */ 00062 00063 00064 /* This implementation works by classifying phonetic bits according to 5 properties: 00065 * Likelyness to begin a name 00066 * Likelyness to end a name 00067 * Likelyness to appear in the middle of a name 00068 * Begins in a vowel 00069 * Ends in a vowel 00070 * 00071 * The last two properties are not strictly tied to vowels, but generally follow that pattern. They help the name generator 00072 * decide which sequences can appear next to each other without resulting in unpronouncable names. 00073 * 00074 * The first three values are determined by running a list of a particular type of name (male first names for example) through a 00075 * filter that searches for occurances of each phonetic bit and adjusts the weight accordingly. 00076 * The current filter is written in perl. 00077 * 00078 */ 00079 00080 00081 00082 enum { 00083 NAMEGENERATOR_FEMALE_FIRST_NAME=0, 00084 NAMEGENERATOR_MALE_FIRST_NAME, 00085 NAMEGENERATOR_FAMILY_NAME, 00086 NAMEGENERATOR_MAX 00087 }; 00088 00089 00090 #define PHONIC_PREJOINER 0x01 00091 #define PHONIC_POSTJOINER 0x02 00092 00093 00094 class PhonicEntry 00095 { 00096 public: 00097 PhonicEntry(); 00098 PhonicEntry(char *ph,float b_p,float e_p,float m_p,unsigned int fl); 00099 ~PhonicEntry(); 00100 00101 public: 00102 char phonic[6]; 00103 float begin_probability,end_probability,middle_probability; 00104 unsigned int flags; 00105 }; 00106 00107 00108 class NameGenerator 00109 { 00110 public: 00111 NameGenerator(iDocumentNode* node); 00112 ~NameGenerator(); 00113 00114 void GenerateName(csString &namebuffer,int length_low,int length_high); 00115 00116 private: 00117 float begin_total,end_total,prejoin_total,nonprejoin_total; 00118 int entry_count; 00119 csPDelArray<PhonicEntry> entries; 00120 csRandomGen *randomgen; 00121 00122 PhonicEntry *GetRandomBeginner(); 00123 PhonicEntry *GetRandomEnder(bool prejoiner); 00124 PhonicEntry *GetRandomPreJoiner(); 00125 PhonicEntry *GetRandomNonPreJoiner(); 00126 00127 }; 00128 00129 class NameGenerationSystem 00130 { 00131 public: 00132 NameGenerationSystem(); 00133 ~NameGenerationSystem(); 00134 00138 bool LoadDatabase( iObjectRegistry* objectReg ); 00142 void GenerateName(int generator_type,csString &namebuffer,int length_low,int length_high); 00143 00144 private: 00145 NameGenerator *generators[NAMEGENERATOR_MAX]; 00146 }; 00147 00150 #endif 00151