Refactored Vertex and GameVertex classes into their own files, put some functions in GameVertex that made sense there
This commit is contained in:
parent
8ad4ec0672
commit
f90c60b6ac
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ LDFLAGS=`sdl-config --libs` -lSDL_ttf
|
||||||
OBJECTS=\
|
OBJECTS=\
|
||||||
main.o \
|
main.o \
|
||||||
drawutils.o mathutils.o timer.o itos.o \
|
drawutils.o mathutils.o timer.o itos.o \
|
||||||
graph.o gamedata.o player.o \
|
graph.o gamedata.o player.o vertex.o gamevertex.o \
|
||||||
menubutton.o \
|
menubutton.o \
|
||||||
mainevent.o gamestate.o game.o titlescreen.o
|
mainevent.o gamestate.o game.o titlescreen.o
|
||||||
|
|
||||||
|
|
4
game.cpp
4
game.cpp
|
@ -277,13 +277,13 @@ void Game::draw_stats(Vertex* v)
|
||||||
line_num++;
|
line_num++;
|
||||||
adj_y = y + line_num * line_height;
|
adj_y = y + line_num * line_height;
|
||||||
DrawUtils::draw_text(display, "atk:", x, adj_y, font);
|
DrawUtils::draw_text(display, "atk:", x, adj_y, font);
|
||||||
DrawUtils::draw_text(display, itos(data.calculate_attack(v)),
|
DrawUtils::draw_text(display, itos(dynamic_cast<GameVertex*>(v)->calculate_attack()),
|
||||||
x + 50, adj_y, font);
|
x + 50, adj_y, font);
|
||||||
|
|
||||||
line_num++;
|
line_num++;
|
||||||
adj_y = y + line_num * line_height;
|
adj_y = y + line_num * line_height;
|
||||||
DrawUtils::draw_text(display, "armor:", x, adj_y, font);
|
DrawUtils::draw_text(display, "armor:", x, adj_y, font);
|
||||||
DrawUtils::draw_text(display, itos(data.calculate_armor(v)),
|
DrawUtils::draw_text(display, itos(dynamic_cast<GameVertex*>(v)->calculate_armor()),
|
||||||
x + 50, adj_y, font);
|
x + 50, adj_y, font);
|
||||||
|
|
||||||
line_num++;
|
line_num++;
|
||||||
|
|
122
gamedata.cpp
122
gamedata.cpp
|
@ -2,9 +2,6 @@
|
||||||
#include "mathutils.h"
|
#include "mathutils.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
using std::list;
|
using std::list;
|
||||||
|
|
||||||
int GameData::PLAYER1_COLOUR = 0x4a483f;
|
int GameData::PLAYER1_COLOUR = 0x4a483f;
|
||||||
|
@ -14,15 +11,6 @@ int GameData::BASE_BUILD_RADIUS = 75;
|
||||||
int GameData::NODE_RADIUS = 10;
|
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()
|
GameData::GameData()
|
||||||
: Graph(true)
|
: 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))
|
if (Graph::add_vertex(v))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n", calculate_strength(*(vertices.rbegin())));
|
|
||||||
#endif
|
|
||||||
toggle_turn();
|
toggle_turn();
|
||||||
return true;
|
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))
|
if (Graph::add_vertex(v, current))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "debug: GameData::add_vertex(): strength=%.2f\n",
|
|
||||||
calculate_strength(*(vertices.rbegin())));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
toggle_turn();
|
toggle_turn();
|
||||||
return true;
|
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
|
// This class contains logic checks to keep the mode aligned with
|
||||||
// what is reasonable. Special cases inside the GameData class should just
|
// what is reasonable. Special cases inside the GameData class should just
|
||||||
// do mode = MODE_<whatever>
|
// do mode = MODE_<whatever>
|
||||||
|
@ -330,8 +212,8 @@ int GameData::get_range(Vertex* node)
|
||||||
|
|
||||||
void GameData::attack_vertex(Vertex* target)
|
void GameData::attack_vertex(Vertex* target)
|
||||||
{
|
{
|
||||||
float atk = calculate_attack(current);
|
float atk = dynamic_cast<GameVertex*>(current)->calculate_attack();
|
||||||
float armor = calculate_armor(target);
|
float armor = dynamic_cast<GameVertex*>(target)->calculate_armor();
|
||||||
int damage = (int)(atk / armor);
|
int damage = (int)(atk / armor);
|
||||||
target->score -= damage;
|
target->score -= damage;
|
||||||
if (target->score <= 0) remove_vertex(target);
|
if (target->score <= 0) remove_vertex(target);
|
||||||
|
|
18
gamedata.h
18
gamedata.h
|
@ -8,20 +8,9 @@
|
||||||
|
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "gamevertex.h"
|
||||||
|
|
||||||
enum Mode {MODE_MOVE=0x1, MODE_ATTACK=0x2, MODE_BUILD=0x4, MODE_SELECT=0x8};
|
enum Mode {MODE_MOVE=0x1, MODE_ATTACK=0x2, MODE_BUILD=0x4, MODE_SELECT=0x8};
|
||||||
enum VertexType {VERTEX_NONE=0x1, VERTEX_ATTACKER=0x2, VERTEX_DEFENDER=0x4,
|
|
||||||
VERTEX_PRODUCER=0x8};
|
|
||||||
|
|
||||||
class GameVertex : public Vertex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GameVertex(int x, int y, int z, int r, int colour = 0, int score = 0,
|
|
||||||
VertexType type = VERTEX_NONE, Player* player = NULL);
|
|
||||||
|
|
||||||
VertexType type;
|
|
||||||
Player* player;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GameData : public Graph
|
class GameData : public Graph
|
||||||
{
|
{
|
||||||
|
@ -54,13 +43,8 @@ class GameData : public Graph
|
||||||
// check for (and set, if needed) winner
|
// check for (and set, if needed) winner
|
||||||
bool endgame();
|
bool endgame();
|
||||||
Player* get_turn() const { return turn; }
|
Player* get_turn() const { return turn; }
|
||||||
float calculate_attack(Vertex* node);
|
|
||||||
float calculate_strength(Vertex* node);
|
|
||||||
float calculate_armor(Vertex* node);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited);
|
|
||||||
|
|
||||||
Vertex* current;
|
Vertex* current;
|
||||||
Player player1, player2;
|
Player player1, player2;
|
||||||
Player* turn;
|
Player* turn;
|
||||||
|
|
109
gamevertex.cpp
Normal file
109
gamevertex.cpp
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#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;
|
||||||
|
}
|
36
gamevertex.h
Normal file
36
gamevertex.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* This extends a normal vertex to do a bunch of game-specific stuff,
|
||||||
|
* including handling attack and defense strengths. It is used by the
|
||||||
|
* GameData class.
|
||||||
|
*
|
||||||
|
* Following the lead of the Vertex class (which is more of a glorified struct)
|
||||||
|
* this will have public data members. Don't judge me.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GAMEVERTEX_H_
|
||||||
|
#define _GAMEVERTEX_H_
|
||||||
|
|
||||||
|
#include "vertex.h"
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
enum VertexType {VERTEX_NONE=0x1, VERTEX_ATTACKER=0x2, VERTEX_DEFENDER=0x4,
|
||||||
|
VERTEX_PRODUCER=0x8};
|
||||||
|
|
||||||
|
class GameVertex : public Vertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GameVertex(int x, int y, int z, int r, int colour = 0, int score = 0,
|
||||||
|
VertexType type = VERTEX_NONE, Player* player = NULL);
|
||||||
|
|
||||||
|
VertexType type;
|
||||||
|
Player* player;
|
||||||
|
|
||||||
|
float calculate_attack();
|
||||||
|
float calculate_armor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float calculate_strength();
|
||||||
|
float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
13
graph.cpp
13
graph.cpp
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
using std::list;
|
using std::list;
|
||||||
|
|
||||||
Vertex::~Vertex() {}
|
|
||||||
|
|
||||||
Graph::Graph(bool planar)
|
Graph::Graph(bool planar)
|
||||||
{
|
{
|
||||||
this->planar = planar;
|
this->planar = planar;
|
||||||
|
@ -158,14 +156,3 @@ void Graph::remove_vertex(Vertex* target)
|
||||||
vertices.erase(cursor);
|
vertices.erase(cursor);
|
||||||
delete target;
|
delete target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vertex::Vertex(int x, int y, int z, int r, int colour, int score)
|
|
||||||
{
|
|
||||||
this->x = x;
|
|
||||||
this->y = y;
|
|
||||||
this->z = z;
|
|
||||||
this->r = r;
|
|
||||||
this->colour = colour;
|
|
||||||
this->score = score;
|
|
||||||
}
|
|
||||||
|
|
17
graph.h
17
graph.h
|
@ -17,26 +17,11 @@
|
||||||
#ifndef _GRAPH_H_
|
#ifndef _GRAPH_H_
|
||||||
#define _GRAPH_H_
|
#define _GRAPH_H_
|
||||||
|
|
||||||
|
#include "vertex.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
using std::list;
|
using std::list;
|
||||||
|
|
||||||
class Vertex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Vertex(int x, int y, int z, int r, int colour = 0, int score = 0);
|
|
||||||
virtual ~Vertex();
|
|
||||||
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
int r;
|
|
||||||
int colour;
|
|
||||||
int score;
|
|
||||||
|
|
||||||
list<Vertex*> neighbors;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Graph
|
class Graph
|
||||||
{
|
{
|
||||||
|
|
13
vertex.cpp
Normal file
13
vertex.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "vertex.h"
|
||||||
|
|
||||||
|
Vertex::Vertex(int x, int y, int z, int r, int colour, int score)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
this->r = r;
|
||||||
|
this->colour = colour;
|
||||||
|
this->score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex::~Vertex() {}
|
27
vertex.h
Normal file
27
vertex.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* A graph-theory style vertex with cartesian coordinates
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VERTEX_H_
|
||||||
|
#define _VERTEX_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
using std::list;
|
||||||
|
|
||||||
|
class Vertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vertex(int x, int y, int z, int r, int colour = 0, int score = 0);
|
||||||
|
virtual ~Vertex();
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int r;
|
||||||
|
int colour;
|
||||||
|
int score;
|
||||||
|
|
||||||
|
list<Vertex*> neighbors;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user