#include "debug.h" #include "gamevertex.h" #include "itos.h" #include "drawutils.h" #include #include TTF_Font* GameVertex::font = NULL; SDL_Surface* GameVertex::attacker_icon = NULL; SDL_Surface* GameVertex::defender_icon = NULL; SDL_Surface* GameVertex::producer_icon = NULL; 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; if (font == NULL || attacker_icon == NULL || defender_icon == NULL || producer_icon == NULL) init(); } 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 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& visited) { // Find which vertices we need to visit from here list neighbors = node->neighbors; list to_visit; visited.push_back(node); for (list::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::iterator cursor = to_visit.begin(); cursor != to_visit.end(); cursor++) { Vertex* v = *cursor; modscore += calculate_strength_r(v, depth+1, visited); } return modscore; } bool GameVertex::init() { font = TTF_OpenFont("res/LiberationSans-Regular.ttf", 12); attacker_icon = DrawUtils::load("attacker_icon.bmp"); defender_icon = DrawUtils::load("defender_icon.bmp"); producer_icon = DrawUtils::load("producer_icon.bmp"); if (font == NULL || attacker_icon == NULL || defender_icon == NULL || producer_icon == NULL) { debug("GameVertex::init(): error: Couldn't load some resource(s)"); return false; } DrawUtils::transpare(attacker_icon); DrawUtils::transpare(defender_icon); DrawUtils::transpare(producer_icon); return true; } void GameVertex::render(SDL_Surface* display) { SDL_Surface* icon; switch (type) { case VERTEX_ATTACKER: icon = attacker_icon; break; case VERTEX_DEFENDER: icon = defender_icon; break; case VERTEX_PRODUCER: icon = producer_icon; break; default: icon = NULL; } DrawUtils::draw_circle_filled(display, x, y, r, colour); if (score > 0) DrawUtils::draw_text(display, itos(score), x, y, font, 0x00ff00, true, true); if (icon != NULL) DrawUtils::draw(display, icon, x + 5, y + 5); }