Made markovian name generation play well with UTF-8 names.
This commit is contained in:
parent
4d8664be25
commit
c9cae23009
2 changed files with 30 additions and 25 deletions
52
src/race.cpp
52
src/race.cpp
|
@ -5,12 +5,13 @@
|
|||
|
||||
namespace {
|
||||
|
||||
void add_prefixes(const std::string& str, size_t length, markov_prefix_map& res)
|
||||
void add_prefixes(const wide_string& str, size_t length, markov_prefix_map& res)
|
||||
{
|
||||
for(size_t i = 0; i <= str.size(); ++i) {
|
||||
const size_t start = i > length ? i - length : 0;
|
||||
const std::string key = str.substr(start,i-start);
|
||||
const char c = i != str.size() ? str[i] : 0;
|
||||
//const wide_string key = str.substr(start, i-start);
|
||||
const wide_string key(str.begin() + start, str.begin() + i);
|
||||
const wchar_t c = i != str.size() ? str[i] : 0;
|
||||
res[key].push_back(c);
|
||||
}
|
||||
}
|
||||
|
@ -20,18 +21,18 @@ markov_prefix_map markov_prefixes(const std::vector<std::string>& items, size_t
|
|||
markov_prefix_map res;
|
||||
|
||||
for(std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i) {
|
||||
add_prefixes(*i,length,res);
|
||||
add_prefixes(string_to_wstring(*i),length,res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string markov_generate_name(const markov_prefix_map& prefixes, size_t chain_size, size_t max_len)
|
||||
wide_string markov_generate_name(const markov_prefix_map& prefixes, size_t chain_size, size_t max_len)
|
||||
{
|
||||
if(chain_size == 0)
|
||||
return "";
|
||||
return wide_string();
|
||||
|
||||
std::string prefix, res;
|
||||
wide_string prefix, res;
|
||||
|
||||
while(res.size() < max_len) {
|
||||
const markov_prefix_map::const_iterator i = prefixes.find(prefix);
|
||||
|
@ -39,7 +40,7 @@ std::string markov_generate_name(const markov_prefix_map& prefixes, size_t chain
|
|||
return res;
|
||||
}
|
||||
|
||||
const char c = i->second[get_random()%i->second.size()];
|
||||
const wchar_t c = i->second[get_random()%i->second.size()];
|
||||
if(c == 0) {
|
||||
return res;
|
||||
}
|
||||
|
@ -62,23 +63,26 @@ std::string markov_generate_name(const markov_prefix_map& prefixes, size_t chain
|
|||
// name has end-of-string as a possible next character in the
|
||||
// markov prefix map. If no valid ending is found, use the
|
||||
// originally generated name.
|
||||
std::string originalRes = res;
|
||||
wide_string originalRes = res;
|
||||
int prefixLen;
|
||||
while (res.size() > 0) {
|
||||
prefixLen = chain_size < res.size() ? chain_size : res.size();
|
||||
prefix = res.substr(res.size() - prefixLen, prefixLen);
|
||||
const markov_prefix_map::const_iterator i = prefixes.find(prefix);
|
||||
if (i == prefixes.end() || i->second.empty()) {
|
||||
return res;
|
||||
}
|
||||
if (std::find(i->second.begin(), i->second.end(), 0)
|
||||
!= i->second.end()) {
|
||||
// This ending is valid.
|
||||
return res;
|
||||
}
|
||||
// The current ending is invalid, remove the last character
|
||||
// and retry.
|
||||
res.erase(res.size() - 1);
|
||||
prefixLen = chain_size < res.size() ? chain_size : res.size();
|
||||
//prefix = res.substr(res.size() - prefixLen, prefixLen);
|
||||
prefix = wide_string(res.end() - prefixLen, res.end());
|
||||
|
||||
const markov_prefix_map::const_iterator i = prefixes.find(prefix);
|
||||
if (i == prefixes.end() || i->second.empty()) {
|
||||
return res;
|
||||
}
|
||||
if (std::find(i->second.begin(), i->second.end(), 0)
|
||||
!= i->second.end()) {
|
||||
// This ending is valid.
|
||||
return res;
|
||||
}
|
||||
// The current ending is invalid, remove the last character
|
||||
// and retry.
|
||||
//res.erase(res.size() - 1);
|
||||
res.pop_back();
|
||||
}
|
||||
// No valid ending at all could be found. This generally should
|
||||
// not happen, unless the chain length is very long or the
|
||||
|
@ -111,7 +115,7 @@ const std::string& unit_race::name() const { return name_; }
|
|||
|
||||
std::string unit_race::generate_name(unit_race::GENDER gender) const
|
||||
{
|
||||
return markov_generate_name(next_[gender],chain_size_,12);
|
||||
return wstring_to_string(markov_generate_name(next_[gender],chain_size_,12));
|
||||
}
|
||||
|
||||
int unit_race::num_traits() const { return ntraits_; }
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "language.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
typedef std::map<std::string,std::vector<char> > markov_prefix_map;
|
||||
typedef std::map<wide_string, std::vector<wchar_t> > markov_prefix_map;
|
||||
|
||||
class unit_race
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue