Split calculate_strength into a recursive and non-recursive portion - saves a lot of special checking

This commit is contained in:
Anna Rose 2011-06-24 11:32:50 -04:00
parent 81028d7070
commit 1a555b900c
2 changed files with 21 additions and 12 deletions

View File

@ -90,18 +90,21 @@ bool GameData::add_vertex(int x, int y, int r, int colour)
} }
// Oh the recursive recursion! float GameData::calculate_strength(Vertex* node)
float GameData::calculate_strength(Vertex* node, unsigned int depth, list<Vertex*>* visited)
{ {
if (visited == NULL) visited = new list<Vertex*>; list<Vertex*> visited;
visited->push_back(node);
list<Vertex*> all_nodes = get_colour(node->colour);
// Special case - a one-node tree just returns its own score! // Special case - a one-node tree just returns its own score!
list<Vertex*> all_nodes = get_colour(node->colour);
if (all_nodes.size() == 1) return (float)node->score; if (all_nodes.size() == 1) return (float)node->score;
return calculate_strength_r(node, 0, visited);
}
// Oh the recursive recursion!
float GameData::calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited)
{
// Find which vertices we need to visit from here // Find which vertices we need to visit from here
list<Edge> es = get_vertex_edges(node); list<Edge> es = get_vertex_edges(node);
list<Vertex*> to_visit; list<Vertex*> to_visit;
@ -113,19 +116,25 @@ float GameData::calculate_strength(Vertex* node, unsigned int depth, list<Vertex
// if this is true, we haven't visited the vertex on the other end of // if this is true, we haven't visited the vertex on the other end of
// this edge yet // this edge yet
if (e.a == node && if (e.a == node &&
find(visited->begin(), visited->end(), e.b) == visited->end()) find(visited.begin(), visited.end(), e.b) == visited.end())
{ {
to_visit.push_back(e.b); to_visit.push_back(e.b);
} }
else if (e.a == node && else if (e.a == node &&
find(visited->begin(), visited->end(), e.b) == visited->end()) find(visited.begin(), visited.end(), e.b) == visited.end())
{ {
to_visit.push_back(e.a); to_visit.push_back(e.a);
} }
} }
visited.push_back(node);
// This is the base case - this node has no unvisited neighbors // This is the base case - this node has no unvisited neighbors
if (to_visit.empty()) return (float)(node->score) / depth; if (to_visit.empty())
{
fprintf(stderr, "At a leaf, and score=%f, depth=%d\n", (float)node->score, depth);
return (float)(node->score) / depth;
}
// Else, iterate through to_visit and visit them all, summing their // Else, iterate through to_visit and visit them all, summing their
// effective strengths adjusted for depth. // effective strengths adjusted for depth.
@ -137,9 +146,8 @@ float GameData::calculate_strength(Vertex* node, unsigned int depth, list<Vertex
cursor != to_visit.end(); cursor++) cursor != to_visit.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
modscore += calculate_strength(v, depth+1, visited); modscore += calculate_strength_r(v, depth+1, visited);
} }
if (depth == 0) delete visited;
return modscore; return modscore;
} }

View File

@ -29,7 +29,8 @@ class GameData : public Graph
bool add_vertex(int x, int y, int r, int colour); bool add_vertex(int x, int y, int r, int colour);
private: private:
float calculate_strength(Vertex* node, unsigned int depth = 0, list<Vertex*>* visited = NULL); float calculate_strength(Vertex* node);
float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited);
Vertex* current; Vertex* current;
Turn player; Turn player;