treewars/gamevertex.cpp

110 lines
2.3 KiB
C++
Raw Normal View History

#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 str = calculate_strength();
float armor;
switch(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 GameVertex::calculate_attack()
{
float attack = calculate_strength();
switch (type)
{
case VERTEX_ATTACKER:
attack *= 1.5;
break;
case VERTEX_DEFENDER:
attack /= 0.75;
break;
case VERTEX_PRODUCER:
attack = 0;
break;
}
}
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;
}