2011-06-23 21:28:49 +00:00
|
|
|
#include "gamedata.h"
|
|
|
|
#include "mathutils.h"
|
2011-06-24 15:03:40 +00:00
|
|
|
#include "debug.h"
|
|
|
|
#include <list>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
using std::list;
|
2011-06-23 21:28:49 +00:00
|
|
|
|
|
|
|
int GameData::PLAYER1_COLOUR = 0x4a483f;
|
|
|
|
int GameData::PLAYER2_COLOUR = 0x090c7a;
|
|
|
|
|
|
|
|
GameData::GameData()
|
|
|
|
: Graph(true)
|
|
|
|
{
|
|
|
|
current = NULL;
|
|
|
|
player = PLAYER1;
|
|
|
|
}
|
|
|
|
|
|
|
|
GameData::~GameData() { }
|
|
|
|
|
|
|
|
void GameData::toggle_turn()
|
|
|
|
{
|
|
|
|
if (player == PLAYER1) player = PLAYER2;
|
|
|
|
else if (player == PLAYER2) player = PLAYER1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameData::do_vertex(int x, int y, int r)
|
|
|
|
{
|
|
|
|
int colour;
|
|
|
|
if (player == PLAYER1) colour = PLAYER1_COLOUR;
|
|
|
|
if (player == PLAYER2) colour = PLAYER2_COLOUR;
|
|
|
|
|
|
|
|
if (point_in_vertex(x, y, r)) select_vertex(x, y);
|
|
|
|
else add_vertex(x, y, r, colour);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameData::select_vertex(int x, int y)
|
|
|
|
{
|
|
|
|
|
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
|
|
|
Vertex* v = *cursor;
|
|
|
|
if ((MathUtils::distance(v->x, v->y, x, y) <= v->r) &&
|
|
|
|
(v->colour == PLAYER1_COLOUR && player == PLAYER1 ||
|
|
|
|
v->colour == PLAYER2_COLOUR && player == PLAYER2))
|
|
|
|
{
|
|
|
|
current = v;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool GameData::add_vertex(int x, int y, int r, int colour)
|
|
|
|
{
|
|
|
|
// this is the special case for adding the first vertex for each player
|
|
|
|
if (current == NULL)
|
|
|
|
{
|
|
|
|
if ((player == PLAYER1 && !player1_played) ||
|
|
|
|
(player == PLAYER2 && !player2_played))
|
|
|
|
{
|
2011-06-24 14:19:41 +00:00
|
|
|
Graph::add_vertex(x, y, r, colour, 10);
|
2011-06-24 15:03:40 +00:00
|
|
|
#ifdef DEBUG
|
2011-06-24 15:06:26 +00:00
|
|
|
fprintf(stderr, "debug: GameData::add_vertex(): strength=%f\n",
|
2011-06-24 15:03:40 +00:00
|
|
|
calculate_strength(*(vertices.rbegin())));
|
|
|
|
#endif
|
2011-06-23 21:28:49 +00:00
|
|
|
if (player == PLAYER1) player1_played = true;
|
|
|
|
if (player == PLAYER2) player2_played = true;
|
|
|
|
toggle_turn();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-24 14:19:41 +00:00
|
|
|
if (Graph::add_vertex(x, y, r, colour, 10, current))
|
2011-06-23 21:28:49 +00:00
|
|
|
{
|
2011-06-24 15:03:40 +00:00
|
|
|
#ifdef DEBUG
|
2011-06-24 15:06:26 +00:00
|
|
|
fprintf(stderr, "debug: GameData::add_vertex(): strength=%f\n",
|
2011-06-24 15:03:40 +00:00
|
|
|
calculate_strength(*(vertices.rbegin())));
|
|
|
|
#endif
|
|
|
|
|
2011-06-23 21:28:49 +00:00
|
|
|
clear_current_vertex();
|
|
|
|
toggle_turn();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2011-06-24 15:03:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Oh the recursive recursion!
|
2011-06-24 15:06:26 +00:00
|
|
|
float GameData::calculate_strength(Vertex* node, unsigned int depth, list<Vertex*>* visited)
|
2011-06-24 15:03:40 +00:00
|
|
|
{
|
|
|
|
if (visited == NULL) visited = new list<Vertex*>;
|
|
|
|
visited->push_back(node);
|
|
|
|
|
|
|
|
list<Vertex*> all_nodes = get_colour(node->colour);
|
|
|
|
|
|
|
|
// Special case - a one-node tree just returns its own score!
|
2011-06-24 15:06:26 +00:00
|
|
|
if (all_nodes.size() == 1) return (float)node->score;
|
2011-06-24 15:03:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Find which vertices we need to visit from here
|
|
|
|
list<Edge> es = get_vertex_edges(node);
|
|
|
|
list<Vertex*> to_visit;
|
|
|
|
|
|
|
|
for (list<Edge>::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
|
2011-06-24 15:06:26 +00:00
|
|
|
if (to_visit.empty()) return (float)(node->score) / depth;
|
2011-06-24 15:03:40 +00:00
|
|
|
|
|
|
|
// 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.
|
2011-06-24 15:06:26 +00:00
|
|
|
float modscore = (float)node->score;
|
2011-06-24 15:03:40 +00:00
|
|
|
if (depth > 0) modscore /= depth;
|
|
|
|
|
|
|
|
for (list<Vertex*>::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;
|
|
|
|
}
|