Speedup the terrain matching.

This commit is contained in:
Moritz Göbelbecker 2007-03-01 04:02:59 +00:00
parent 1c583b7f7c
commit a07d337c85
5 changed files with 26 additions and 13 deletions

View File

@ -620,7 +620,7 @@ private:
* @return returns true if "letter" matches the list or the list is empty, else false.
*/
bool terrain_matches(t_translation::t_letter letter, const t_translation::t_match &terrain) const
{ return terrain.terrain.empty()? true : t_translation::terrain_matches(letter, terrain); }
{ return terrain.is_empty ? true : t_translation::terrain_matches(letter, terrain); }
/**
* Checks whether a rule matches a given location in the map.

View File

@ -258,7 +258,7 @@ gamemap::location::DIRECTION gamemap::location::get_opposite_dir(gamemap::locati
}
}
gamemap::gamemap(const config& cfg, const std::string& data) : tiles_(1)
gamemap::gamemap(const config& cfg, const std::string& data) : tiles_(1), x_(-1), y_(-1)
{
LOG_G << "loading map: '" << data << "'\n";
const config::child_list& terrains = cfg.get_children("terrain");
@ -302,6 +302,8 @@ void gamemap::read(const std::string& data)
// post processing on the map
const int width = tiles_.size();
const int height = tiles_[0].size();
x_ = width;
y_ = height;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {

View File

@ -130,8 +130,8 @@ public:
void overlay(const gamemap& m, const config& rules, int x=0, int y=0);
//dimensions of the map.
int x() const { return tiles_.size(); }
int y() const { return tiles_.empty() ? 0 : tiles_.front().size(); }
int x() const { return x_; }
int y() const { return y_; }
//allows lookup of terrain at a particular location.
const t_translation::t_list& operator[](int index) const
@ -215,6 +215,9 @@ private:
mutable std::map<location, t_translation::t_letter> borderCache_;
mutable std::map<t_translation::t_letter, size_t> terrainFrequencyCache_;
int x_;
int y_;
};
//a utility function which parses ranges of locations

View File

@ -192,6 +192,7 @@ t_match::t_match(const std::string& str):
mask.resize(terrain.size());
masked_terrain.resize(terrain.size());
has_wildcard = t_translation::has_wildcard(terrain);
is_empty = terrain.empty();
for(size_t i = 0; i < terrain.size(); i++) {
mask[i] = t_translation::get_mask_(terrain[i]);
@ -205,6 +206,7 @@ t_match::t_match(const t_letter letter):
mask.resize(terrain.size());
masked_terrain.resize(terrain.size());
has_wildcard = t_translation::has_wildcard(terrain);
is_empty = terrain.empty();
for(size_t i = 0; i < terrain.size(); i++) {
mask[i] = t_translation::get_mask_(terrain[i]);
@ -502,7 +504,7 @@ bool terrain_matches(const t_letter src, const t_list& dest)
bool terrain_matches(const t_letter src, const t_match& dest)
{
if(dest.terrain.empty()) {
if(dest.is_empty) {
return false;
}
@ -516,26 +518,29 @@ bool terrain_matches(const t_letter src, const t_match& dest)
bool result = true;
// try to match the terrains if matched jump out of the loop.
for(size_t i = 0; i < dest.terrain.size(); ++i) {
int i = -1;
t_list::const_iterator end = dest.terrain.end();
for(t_list::const_iterator it = dest.terrain.begin(); it != end; it++) {
++i;
// match wildcard
if(dest.terrain[i] == star) {
if(*it == star) {
return result;
}
// match inverse symbol
if(dest.terrain[i] == inverse) {
if(*it == inverse) {
result = !result;
continue;
}
// full match
if(dest.terrain[i] == src) {
if(*it == src) {
return result;
}
// does the source wildcard match
if(src_has_wildcard && (dest.terrain[i] & src_mask) == masked_src) {
if(src_has_wildcard && (*it & src_mask) == masked_src) {
return result;
}
@ -546,8 +551,8 @@ bool terrain_matches(const t_letter src, const t_match& dest)
// if one of the 2 has a caret and we use a wildcard in the first part
// we fail eg *^ != A without wildcards no problem occurs eg A^ == A
if(src_has_wildcard || has_wildcard(dest.terrain[i])) {
if(match_ignore_layer_(src, dest.terrain[i])) {
if(src_has_wildcard || has_wildcard(*it)) {
if(match_ignore_layer_(src, *it)) {
return result;
}
}
@ -559,7 +564,9 @@ bool terrain_matches(const t_letter src, const t_match& dest)
bool has_wildcard(const t_letter letter)
{
return has_wildcard(t_list(1, letter));
if (get_mask_(letter) != WILDCARD_NONE)
return true;
return false;
}
bool has_wildcard(const t_list& list)

View File

@ -65,6 +65,7 @@ namespace t_translation {
t_list mask;
t_list masked_terrain;
bool has_wildcard;
bool is_empty;
};
/**