diff --git a/gamedata.cpp b/gamedata.cpp index 951b49e..e7699ca 100644 --- a/gamedata.cpp +++ b/gamedata.cpp @@ -1,5 +1,10 @@ #include "gamedata.h" #include "mathutils.h" +#include "debug.h" +#include +#include + +using std::list; int GameData::PLAYER1_COLOUR = 0x4a483f; int GameData::PLAYER2_COLOUR = 0x090c7a; @@ -58,6 +63,10 @@ bool GameData::add_vertex(int x, int y, int r, int colour) (player == PLAYER2 && !player2_played)) { Graph::add_vertex(x, y, r, colour, 10); +#ifdef DEBUG + fprintf(stderr, "debug: GameData::add_vertex(): strength=%d\n", + calculate_strength(*(vertices.rbegin()))); +#endif if (player == PLAYER1) player1_played = true; if (player == PLAYER2) player2_played = true; toggle_turn(); @@ -68,9 +77,69 @@ bool GameData::add_vertex(int x, int y, int r, int colour) if (Graph::add_vertex(x, y, r, colour, 10, current)) { +#ifdef DEBUG + fprintf(stderr, "debug: GameData::add_vertex(): strength=%d\n", + calculate_strength(*(vertices.rbegin()))); +#endif + clear_current_vertex(); toggle_turn(); return true; } return false; } + + +// Oh the recursive recursion! +unsigned int GameData::calculate_strength(Vertex* node, unsigned int depth, list* visited) +{ + if (visited == NULL) visited = new list; + visited->push_back(node); + + list all_nodes = get_colour(node->colour); + + // Special case - a one-node tree just returns its own score! + if (all_nodes.size() == 1) return node->score; + + + // Find which vertices we need to visit from here + list es = get_vertex_edges(node); + list to_visit; + + for (list::iterator cursor = es.begin(); cursor != es.end(); + cursor++) + { + Edge e = *cursor; + // if this is true, we haven't visited the vertex on the other end of + // this edge yet + if (e.a == node && + find(visited->begin(), visited->end(), e.b) == visited->end()) + { + to_visit.push_back(e.b); + } + else if (e.a == node && + find(visited->begin(), visited->end(), e.b) == visited->end()) + { + to_visit.push_back(e.a); + } + } + + // This is the base case - this node has no unvisited neighbors + if (to_visit.empty()) return node->score / depth; + + // Else, iterate through to_visit and visit them all, summing their + // effective strengths adjusted for depth. + // Since our trees are acyclic, this can't loop. + int modscore = node->score; + if (depth > 0) modscore /= depth; + + for (list::iterator cursor = to_visit.begin(); + cursor != to_visit.end(); cursor++) + { + Vertex* v = *cursor; + modscore += calculate_strength(v, depth+1, visited); + } + + if (depth == 0) delete visited; + return modscore; +} diff --git a/gamedata.h b/gamedata.h index 979b007..7f6c8bf 100644 --- a/gamedata.h +++ b/gamedata.h @@ -29,6 +29,8 @@ class GameData : public Graph bool add_vertex(int x, int y, int r, int colour); private: + unsigned int calculate_strength(Vertex* node, unsigned int depth = 0, list* visited = NULL); + Vertex* current; Turn player; bool player1_played; diff --git a/graph.cpp b/graph.cpp index 9608c0c..1823eca 100644 --- a/graph.cpp +++ b/graph.cpp @@ -106,7 +106,7 @@ bool Graph::add_vertex(int x, int y, int r, int colour, int score, Vertex* src) vertices.push_back(v); #ifdef DEBUG - fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, r=%d\n", v->x, v->y, v->r); + fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, r=%d, score=%d\n", v->x, v->y, v->r, v->score); #endif return true; @@ -121,3 +121,33 @@ Vertex::Vertex(int x, int y, int r, int colour, int score) this->colour = colour; this->score = score; } + + +list Graph::get_colour(int colour) +{ + list answer; + + for (list::iterator cursor = vertices.begin(); + cursor != vertices.end(); cursor++) + { + Vertex* v = *cursor; + if (v->colour == colour) answer.push_back(v); + } + + return answer; +} + + +list Graph::get_vertex_edges(Vertex* v) +{ + list answer; + + for (list::iterator cursor = edges.begin(); + cursor != edges.end(); cursor++) + { + Edge e = *cursor; + if (e.a == v || e.b == v) answer.push_back(e); + } + + return answer; +} diff --git a/graph.h b/graph.h index 04b3151..e94c379 100644 --- a/graph.h +++ b/graph.h @@ -48,6 +48,8 @@ class Graph list get_vertices() const { return vertices; } list get_edges() const { return edges; } + list get_colour(int colour); + list get_vertex_edges(Vertex* v); bool point_in_vertex(int x, int y, int size); Vertex * vertex_at(int x, int y);