Refactored Vertex and GameVertex classes into their own files, put some functions in GameVertex that made sense there
This commit is contained in:
122
gamedata.cpp
122
gamedata.cpp
@ -2,9 +2,6 @@
|
||||
#include "mathutils.h"
|
||||
#include "debug.h"
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
using std::list;
|
||||
|
||||
int GameData::PLAYER1_COLOUR = 0x4a483f;
|
||||
@ -14,15 +11,6 @@ int GameData::BASE_BUILD_RADIUS = 75;
|
||||
int GameData::NODE_RADIUS = 10;
|
||||
|
||||
|
||||
GameVertex::GameVertex(int x, int y, int z, int r, int colour, int score,
|
||||
VertexType type, Player* player)
|
||||
: Vertex(x, y, z, r, colour, score)
|
||||
{
|
||||
this->type = type;
|
||||
this->player = player;
|
||||
}
|
||||
|
||||
|
||||
GameData::GameData()
|
||||
: Graph(true)
|
||||
{
|
||||
@ -144,9 +132,6 @@ bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||
{
|
||||
if (Graph::add_vertex(v))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n", calculate_strength(*(vertices.rbegin())));
|
||||
#endif
|
||||
toggle_turn();
|
||||
return true;
|
||||
}
|
||||
@ -174,11 +159,6 @@ bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||
|
||||
if (Graph::add_vertex(v, current))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "debug: GameData::add_vertex(): strength=%.2f\n",
|
||||
calculate_strength(*(vertices.rbegin())));
|
||||
#endif
|
||||
|
||||
toggle_turn();
|
||||
return true;
|
||||
}
|
||||
@ -188,104 +168,6 @@ bool GameData::add_vertex(int x, int y, int z, int r, int colour)
|
||||
}
|
||||
|
||||
|
||||
float GameData::calculate_armor(Vertex* node)
|
||||
{
|
||||
float str = calculate_strength(node);
|
||||
float armor;
|
||||
|
||||
switch(dynamic_cast<GameVertex*>(node)->type)
|
||||
{
|
||||
case VERTEX_ATTACKER:
|
||||
armor = str / 10;
|
||||
break;
|
||||
case VERTEX_DEFENDER:
|
||||
armor = str / 5;
|
||||
break;
|
||||
case VERTEX_PRODUCER:
|
||||
armor = str / 40;
|
||||
break;
|
||||
}
|
||||
|
||||
if (armor < 1) armor = 1;
|
||||
return armor;
|
||||
}
|
||||
|
||||
|
||||
float GameData::calculate_attack(Vertex* node)
|
||||
{
|
||||
float attack = calculate_strength(node);
|
||||
|
||||
switch (dynamic_cast<GameVertex*>(node)->type)
|
||||
{
|
||||
case VERTEX_ATTACKER:
|
||||
attack *= 1.5;
|
||||
break;
|
||||
case VERTEX_DEFENDER:
|
||||
attack /= 0.75;
|
||||
break;
|
||||
case VERTEX_PRODUCER:
|
||||
attack = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float GameData::calculate_strength(Vertex* node)
|
||||
{
|
||||
list<Vertex*> visited;
|
||||
|
||||
// Special case - a one-node tree just returns its own score!
|
||||
if (node->neighbors.empty()) 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
|
||||
list<Vertex*> neighbors = node->neighbors;
|
||||
list<Vertex*> to_visit;
|
||||
|
||||
visited.push_back(node);
|
||||
|
||||
for (list<Vertex*>::iterator cursor = neighbors.begin();
|
||||
cursor != neighbors.end(); cursor++)
|
||||
{
|
||||
Vertex* v = *cursor;
|
||||
// if this is true, we haven't visited the vertex on the other end of
|
||||
// this edge yet
|
||||
if (find(visited.begin(), visited.end(), v) == visited.end())
|
||||
{
|
||||
to_visit.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the base case - this node has no unvisited neighbors
|
||||
if (to_visit.empty())
|
||||
{
|
||||
assert(depth > 0);
|
||||
return (float)(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.
|
||||
float modscore = (float)node->score;
|
||||
if (depth > 0) modscore /= depth;
|
||||
|
||||
for (list<Vertex*>::iterator cursor = to_visit.begin();
|
||||
cursor != to_visit.end(); cursor++)
|
||||
{
|
||||
Vertex* v = *cursor;
|
||||
modscore += calculate_strength_r(v, depth+1, visited);
|
||||
}
|
||||
|
||||
return modscore;
|
||||
}
|
||||
|
||||
|
||||
// This class contains logic checks to keep the mode aligned with
|
||||
// what is reasonable. Special cases inside the GameData class should just
|
||||
// do mode = MODE_<whatever>
|
||||
@ -330,8 +212,8 @@ int GameData::get_range(Vertex* node)
|
||||
|
||||
void GameData::attack_vertex(Vertex* target)
|
||||
{
|
||||
float atk = calculate_attack(current);
|
||||
float armor = calculate_armor(target);
|
||||
float atk = dynamic_cast<GameVertex*>(current)->calculate_attack();
|
||||
float armor = dynamic_cast<GameVertex*>(target)->calculate_armor();
|
||||
int damage = (int)(atk / armor);
|
||||
target->score -= damage;
|
||||
if (target->score <= 0) remove_vertex(target);
|
||||
|
Reference in New Issue
Block a user