diff --git a/gamedata.cpp b/gamedata.cpp index ef72b7d..3af9f37 100644 --- a/gamedata.cpp +++ b/gamedata.cpp @@ -22,9 +22,14 @@ GameData::~GameData() { } void GameData::toggle_turn() { - if (player == PLAYER1) player = PLAYER2; - else if (player == PLAYER2) player = PLAYER1; mode = MODE_MOVE; + current = NULL; + + if (!endgame()) + { + if (player == PLAYER1) player = PLAYER2; + else if (player == PLAYER2) player = PLAYER1; + } } @@ -38,15 +43,23 @@ void GameData::do_vertex(int x, int y, int r) return; } + int colour; + if (player == PLAYER1) colour = PLAYER1_COLOUR; + if (player == PLAYER2) colour = PLAYER2_COLOUR; + if (mode == MODE_MOVE) { - 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); + if (point_in_vertex(x, y)) select_vertex(x, y); else add_vertex(x, y, r, colour); } + if (mode == MODE_ATTACK) + { + Vertex* v = vertex_at(x, y); + if (v == NULL) return; + + if (v->colour == colour) select_vertex(x, y); + else attack_vertex(v); + } } @@ -72,9 +85,9 @@ bool GameData::add_vertex(int x, int y, int r, int colour) { if (mode == MODE_ATTACK) return false; - // this is the special case for adding the first vertex for each player if (current == NULL) { + // this is the special case for adding the first vertex for each player if ((player == PLAYER1 && !player1_played) || (player == PLAYER2 && !player2_played)) { @@ -98,7 +111,6 @@ bool GameData::add_vertex(int x, int y, int r, int colour) calculate_strength(*(vertices.rbegin()))); #endif - clear_current_vertex(); toggle_turn(); return true; } @@ -171,12 +183,53 @@ int GameData::get_range(Vertex* node) else if (mode == MODE_MOVE) return 100; else if (mode == MODE_ATTACK) { - + int range = 200; + list neighbors = get_neighbors(node); + + for(list::iterator cursor = neighbors.begin(); + cursor != neighbors.end(); cursor++) + { + Vertex* v = *cursor; + range -= 100 - MathUtils::distance(v->x, v->y, node->x, node->y); + } } } void GameData::attack_vertex(Vertex* target) { + float atk_str = calculate_strength(current); + float def_str = calculate_strength(target); + float armor = def_str / 10; // how much energy it takes to deal 1 damage + int damage = (int)(atk_str / armor); + + target->score -= damage; + + if (target->score <= 0) remove_vertex(target); + +#ifdef DEBUG + fprintf(stderr, "debug: GameData::attack_vertex(): atk_str=%2.f, def_str=%2.f, armor=%2.f, damage=%d\n", atk_str, def_str, armor, damage); +#endif + + toggle_turn(); +} + + +bool GameData::endgame() +{ + if (!(player1_played && player2_played)) return false; + + if (get_colour(PLAYER1_COLOUR).empty()) + { + player = WIN2; + return true; + } + if (get_colour(PLAYER2_COLOUR).empty()) + { + player = WIN1; + return true; + } + + return false; } diff --git a/gamedata.h b/gamedata.h index c9f2245..b117e2b 100644 --- a/gamedata.h +++ b/gamedata.h @@ -36,6 +36,10 @@ class GameData : public Graph // (or the selected node if node == NULL) int get_range(Vertex* node = NULL); + // check for (and set, if needed) winner + bool endgame(); + Turn get_turn() const { return player; } + private: float calculate_strength(Vertex* node); float calculate_strength_r(Vertex* node, unsigned int depth, list& visited); diff --git a/graph.cpp b/graph.cpp index 10d5611..2094fa5 100644 --- a/graph.cpp +++ b/graph.cpp @@ -1,6 +1,11 @@ #include "graph.h" #include "mathutils.h" #include "debug.h" +#include +#include +#include + +using std::list; Graph::Graph(bool planar) { @@ -17,7 +22,7 @@ Graph::~Graph() } } -bool Graph::point_in_vertex(int x, int y, int r) +bool Graph::point_in_vertex(int x, int y) { for (list::iterator cursor = vertices.begin(); cursor != vertices.end(); cursor++) @@ -113,16 +118,6 @@ bool Graph::add_vertex(int x, int y, int r, int colour, int score, Vertex* src) } -Vertex::Vertex(int x, int y, int r, int colour, int score) -{ - this->x = x; - this->y = y; - this->r = r; - this->colour = colour; - this->score = score; -} - - list Graph::get_colour(int colour) { list answer; @@ -167,3 +162,62 @@ list Graph::get_neighbors(Vertex* v) return answer; } + + +void Graph::remove_vertex(Vertex* target) +{ + list dead_edges = get_edges(target); + + for (list::iterator cursor = dead_edges.begin(); + cursor != dead_edges.end(); cursor++) + { + Edge e = *cursor; + list::iterator to_del = find(edges.begin(), edges.end(), e); + + if (to_del != edges.end()) + { + edges.erase(to_del); + } + } + + list::iterator to_del = find(vertices.begin(), vertices.end(), + target); + + assert(to_del != vertices.end()); + vertices.erase(to_del); + delete target; +} + + +Vertex::Vertex(int x, int y, int r, int colour, int score) +{ + this->x = x; + this->y = y; + this->r = r; + this->colour = colour; + this->score = score; +} + + +Edge::Edge() +{ + a = NULL; + b = NULL; + score = 0; +} + + +Edge::Edge(Vertex* a, Vertex* b, int score) +{ + this->a = a; + this->b = b; + this->score = score; +} + + +bool Edge::operator==(const Edge e) const +{ + return (this->a == e.a && + this->b == e.b && + this->score == e.score); +} diff --git a/graph.h b/graph.h index 24139b8..a49dd08 100644 --- a/graph.h +++ b/graph.h @@ -33,11 +33,18 @@ class Vertex int score; }; -struct Edge +class Edge { + public: + Edge(); + Edge(Vertex* a, Vertex* b, int score = 0); + Vertex* a; Vertex* b; int score; + + bool operator==(const Edge e) const; + bool operator!=(const Edge e) const { return !(*this == e); } }; class Graph @@ -52,10 +59,11 @@ class Graph list get_edges(Vertex* v); list get_neighbors(Vertex* v); - bool point_in_vertex(int x, int y, int size); + bool point_in_vertex(int x, int y); Vertex * vertex_at(int x, int y); virtual bool add_vertex(int x, int y, int r, int colour = 0, int score = 0, Vertex* src=NULL); + void remove_vertex(Vertex* target); bool is_planar() const { return planar; } void set_planar(bool planar) { this->planar = planar; }