treewars/graph.cpp

172 lines
3.7 KiB
C++
Raw Normal View History

#include "graph.h"
#include "mathutils.h"
#include "debug.h"
#include <list>
#include <algorithm>
#include <cassert>
using std::list;
Vertex::~Vertex() {}
Graph::Graph(bool planar)
{
this->planar = planar;
}
Graph::~Graph()
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
delete v;
}
}
// In 3-space, this will be less useful, because we'll be clicking on the
// objects themselves... but we'll cross that bridge when we get there
bool Graph::point_in_vertex(int x, int y, int z)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r)
return true;
}
return false;
}
Vertex * Graph::vertex_at(int x, int y, int z)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r) return v;
}
return NULL;
}
bool Graph::vertex_would_overlap(int x, int y, int z, int r)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r + r)
return true;
}
return false;
}
bool Graph::crosses_edge(Vertex* a, Vertex* b)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
for (list<Vertex*>::iterator subcursor = v->neighbors.begin();
subcursor != v->neighbors.end(); subcursor++)
{
2011-06-28 00:32:29 +00:00
Vertex* w = *subcursor;
if (MathUtils::lines_intersect(a->x, a->y, b->x, b->y,
v->x, v->y, w->x, w->y))
return true;
}
}
return false;
}
bool Graph::add_vertex(Vertex* v, Vertex* src)
{
// Make sure the nodes won't overlap
if (vertex_would_overlap(v->x, v->y, v->z, v->r))
{
#ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to vertex collision: x=%d, y=%d, z=%d, r=%d\n", v->x, v->y, v->z, v->r);
#endif
return false;
}
if (src != NULL)
{
if (planar && crosses_edge(v, src))
{
#ifdef DEBUG
2011-06-29 02:14:55 +00:00
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
return false;
}
v->neighbors.push_back(src);
src->neighbors.push_back(v);
}
vertices.push_back(v);
#ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, z=%d, r=%d, score=%d, colour=%x\n", v->x, v->y, v->z, v->r, v->score, v->colour);
#endif
return true;
}
list<Vertex*> Graph::get_colour(int colour)
{
list<Vertex*> answer;
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (v->colour == colour) answer.push_back(v);
}
return answer;
}
void Graph::remove_vertex(Vertex* target)
{
list<Vertex*>::iterator cursor;
for (cursor = target->neighbors.begin(); cursor != target->neighbors.end();
cursor++)
{
2011-06-28 03:05:14 +00:00
list<Vertex*>::iterator subcursor = find((*cursor)->neighbors.begin(),
(*cursor)->neighbors.end(),
target);
assert(subcursor != (*cursor)->neighbors.end());
(*cursor)->neighbors.erase(subcursor);
}
cursor = find(vertices.begin(), vertices.end(), target);
assert(cursor != vertices.end());
vertices.erase(cursor);
delete target;
}
Vertex::Vertex(int x, int y, int z, int r, int colour, int score)
{
this->x = x;
this->y = y;
this->z = z;
this->r = r;
this->colour = colour;
this->score = score;
}