111 lines
2.3 KiB
C++
111 lines
2.3 KiB
C++
#include "gamevertex.h"
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
float GameVertex::calculate_armor()
|
|
{
|
|
float armor = calculate_strength();
|
|
|
|
switch(type)
|
|
{
|
|
case VERTEX_ATTACKER:
|
|
armor *= 0.2;
|
|
break;
|
|
case VERTEX_DEFENDER:
|
|
armor *= 0.5;
|
|
break;
|
|
case VERTEX_PRODUCER:
|
|
armor *= 0.1;
|
|
break;
|
|
}
|
|
|
|
if (armor < 1) armor = 1;
|
|
return armor;
|
|
}
|
|
|
|
|
|
float GameVertex::calculate_attack()
|
|
{
|
|
float attack = calculate_strength();
|
|
|
|
switch (type)
|
|
{
|
|
case VERTEX_ATTACKER:
|
|
attack *= 1.25;
|
|
break;
|
|
case VERTEX_DEFENDER:
|
|
attack *= 0.1;
|
|
break;
|
|
case VERTEX_PRODUCER:
|
|
attack = 0;
|
|
break;
|
|
}
|
|
|
|
return attack;
|
|
}
|
|
|
|
|
|
float GameVertex::calculate_strength()
|
|
{
|
|
list<Vertex*> visited;
|
|
|
|
// Special case - a one-node tree just returns its own score!
|
|
if (neighbors.empty()) return (float)score;
|
|
|
|
return calculate_strength_r(this, 0, visited);
|
|
}
|
|
|
|
|
|
// Oh the recursive recursion!
|
|
float GameVertex::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;
|
|
}
|