From 07fc8c67c1a45b1f72b4f9098ebf6c7e2a55eb29 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Mon, 27 Jun 2011 18:10:24 -0400 Subject: [PATCH] Removed the concept of edges in favor of a proper tree-style approach, with each vertex knowing about its neighbors. This seems to have broken both Grah::crosses_edge() and Graph::remove_vertex. and the move radius circle doesn't draw any more. Go team. --- drawutils.cpp | 1 + gamedata.cpp | 4 +- graph.cpp | 117 +++++++++++++----------------------------------- graph.h | 23 ++-------- sdlrenderer.cpp | 28 ++++++------ 5 files changed, 53 insertions(+), 120 deletions(-) diff --git a/drawutils.cpp b/drawutils.cpp index 3e99de6..f0c7701 100644 --- a/drawutils.cpp +++ b/drawutils.cpp @@ -52,6 +52,7 @@ bool DrawUtils::draw(SDL_Surface* dest, SDL_Surface* drawable, int x, int y, return true; } +#include "debug.h" void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint16 width, Uint32 colour) { float dx, dy, len; diff --git a/gamedata.cpp b/gamedata.cpp index 11adaa6..d8af9cb 100644 --- a/gamedata.cpp +++ b/gamedata.cpp @@ -134,7 +134,7 @@ float GameData::calculate_strength(Vertex* node) float GameData::calculate_strength_r(Vertex* node, unsigned int depth, list& visited) { // Find which vertices we need to visit from here - list neighbors = get_neighbors(node); + list neighbors = node->neighbors; list to_visit; visited.push_back(node); @@ -184,7 +184,7 @@ int GameData::get_range(Vertex* node) else if (mode == MODE_ATTACK) { int range = 200; - list neighbors = get_neighbors(node); + list neighbors = node->neighbors; for(list::iterator cursor = neighbors.begin(); cursor != neighbors.end(); cursor++) diff --git a/graph.cpp b/graph.cpp index 2094fa5..47c23e3 100644 --- a/graph.cpp +++ b/graph.cpp @@ -61,15 +61,21 @@ bool Graph::vertex_would_overlap(int x, int y, int r) } -bool Graph::crosses_edge(Edge e) +bool Graph::crosses_edge(Vertex* a, Vertex* b) { - for (list::iterator cursor = edges.begin(); - cursor != edges.end(); cursor++) + for (list::iterator cursor = vertices.begin(); + cursor != vertices.end(); cursor++) { - Edge c = *cursor; - if (MathUtils::lines_intersect(c.a->x, c.a->y, c.b->x, c.b->y, - e.a->x, e.a->y, e.b->x, e.b->y)) - return true; + Vertex* v = *cursor; + for (list::iterator subcursor = v->neighbors.begin(); + subcursor != v->neighbors.end(); subcursor++) + { + Vertex* w = *cursor; + + if (MathUtils::lines_intersect(a->x, a->y, b->x, b->y, + v->x, v->y, w->x, w->y)) + return true; + } } return false; @@ -92,20 +98,17 @@ bool Graph::add_vertex(int x, int y, int r, int colour, int score, Vertex* src) if (src != NULL) { - Edge e; - e.a = src; - e.b = v; - - if (planar && crosses_edge(e)) + if (planar && crosses_edge(v, src)) { #ifdef DEBUG - fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to edge collision: x1=%d, y1=%d, x2=%d, y2=%d\n", e.a->x, e.a->y, e.b->x, e.b->y); + fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to edge collision: x1=%d, y1=%d, x2=%d, y2=%d\n", v->x, v->y, src->x, src->y); #endif delete v; return false; } - edges.push_back(e); + v->neighbors.push_back(src); + src->neighbors.push_back(v); } vertices.push_back(v); @@ -133,58 +136,24 @@ list Graph::get_colour(int colour) } -list Graph::get_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; -} - - -list Graph::get_neighbors(Vertex* v) -{ - list answer; - - for (list::iterator cursor = edges.begin(); - cursor != edges.end(); cursor++) - { - Edge e = *cursor; - if (e.a == v) answer.push_back(e.b); - else if (e.b == v) answer.push_back(e.a); - } - - return answer; -} - - void Graph::remove_vertex(Vertex* target) { - list dead_edges = get_edges(target); - - for (list::iterator cursor = dead_edges.begin(); - cursor != dead_edges.end(); cursor++) + list::iterator cursor; + + for (cursor = target->neighbors.begin(); cursor != target->neighbors.end(); + cursor++) { - Edge e = *cursor; - list::iterator to_del = find(edges.begin(), edges.end(), e); - - if (to_del != edges.end()) - { - edges.erase(to_del); - } + Vertex* neighbor = *cursor; + list::iterator subcursor = find(target->neighbors.begin(), + target->neighbors.end(), + target); + assert(subcursor != target->neighbors.end()); + target->neighbors.erase(subcursor); } - - list::iterator to_del = find(vertices.begin(), vertices.end(), - target); - - assert(to_del != vertices.end()); - vertices.erase(to_del); + + cursor = find(vertices.begin(), vertices.end(), target); + assert(cursor != vertices.end()); + vertices.erase(cursor); delete target; } @@ -197,27 +166,3 @@ Vertex::Vertex(int x, int y, int r, int colour, int score) this->colour = colour; this->score = score; } - - -Edge::Edge() -{ - a = NULL; - b = NULL; - score = 0; -} - - -Edge::Edge(Vertex* a, Vertex* b, int score) -{ - this->a = a; - this->b = b; - this->score = score; -} - - -bool Edge::operator==(const Edge e) const -{ - return (this->a == e.a && - this->b == e.b && - this->score == e.score); -} diff --git a/graph.h b/graph.h index a49dd08..0fb767d 100644 --- a/graph.h +++ b/graph.h @@ -1,5 +1,5 @@ /* Represents an undirected graph. - * Also contains the vertex and edge classes + * Also contains the vertex class * These are not quite traditional graph theory graphs, because they also have * cartesian coordinates, and can do some math to ensure planarity is preserved * (that is, planarity in the existant layout, not being isomorphic to a @@ -31,21 +31,10 @@ class Vertex int r; int colour; int score; + + list neighbors; }; -class Edge -{ - public: - Edge(); - Edge(Vertex* a, Vertex* b, int score = 0); - - Vertex* a; - Vertex* b; - int score; - - bool operator==(const Edge e) const; - bool operator!=(const Edge e) const { return !(*this == e); } -}; class Graph { @@ -54,10 +43,7 @@ class Graph virtual ~Graph(); list get_vertices() const { return vertices; } - list get_edges() const { return edges; } list get_colour(int colour); - list get_edges(Vertex* v); - list get_neighbors(Vertex* v); bool point_in_vertex(int x, int y); Vertex * vertex_at(int x, int y); @@ -70,11 +56,10 @@ class Graph protected: list vertices; - list edges; private: bool vertex_would_overlap(int x, int y, int r); - bool crosses_edge(Edge e); + bool crosses_edge(Vertex* a, Vertex* b); bool planar; }; diff --git a/sdlrenderer.cpp b/sdlrenderer.cpp index 1b442c9..2a0384c 100644 --- a/sdlrenderer.cpp +++ b/sdlrenderer.cpp @@ -49,31 +49,33 @@ void SDLRenderer::render(GameData& data) break; } + // Background image first DrawUtils::draw(display, background, 0, 0); list vertices = data.get_vertices(); - list edges = data.get_edges(); + // Now paint on the targeting circle if (data.get_current_vertex() != NULL) { Vertex* v = data.get_current_vertex(); - DrawUtils::draw_circle_filled(display, v->x, v->y, range, range_colour); + DrawUtils::draw_circle_filled(display, v->x, v->y, range, + range_colour); } + // Now paint each vertex, and any edges that it needs for (list::iterator cursor = vertices.begin(); cursor != vertices.end(); cursor++) { - Vertex v = *(*cursor); - DrawUtils::draw_circle_filled(display, v.x, v.y, v.r, - v.colour); - } - - for (list::iterator cursor = edges.begin(); - cursor != edges.end(); cursor++) - { - Edge e = *cursor; - DrawUtils::draw_line(display, e.a->x, e.a->y, e.b->x, e.b->y, 2, - e.a->colour); + Vertex* v = *cursor; + DrawUtils::draw_circle_filled(display, v->x, v->y, v->r, + v->colour); + for (list::iterator subcursor = v->neighbors.begin(); + subcursor != v->neighbors.end(); subcursor++) + { + Vertex* v1 = *subcursor; + DrawUtils::draw_line(display, v->x, v->y, v1->x, v1->y, 2, + v->colour); + } } SDL_Flip(display);