Separated game-specific graph behavior into a subclass, implemented 2 players alternating turns

This commit is contained in:
Anna Rose 2011-06-23 17:28:49 -04:00
parent b967542157
commit 5ed05fc829
7 changed files with 170 additions and 81 deletions

View File

@ -4,7 +4,7 @@ PROJECT=graphgame
CXX=g++
CXXFLAGS=-DDEBUG -g
LDFLAGS=-lSDL
OBJECTS=drawutils.o gamecore.o graph.o main.o mainevent.o mathutils.o
OBJECTS=drawutils.o gamecore.o graph.o main.o mainevent.o mathutils.o gamedata.o
all: $(PROJECT)

View File

@ -5,17 +5,12 @@
int GameCore::MAX_MOVE_DISTANCE = 100;
int GameCore::NODE_RADIUS = 12;
int GameCore::PLAYER1_COLOUR = 0x4a483f;
int GameCore::PLAYER2_COLOUR = 0x090c7a;
GameCore::GameCore()
{
display = NULL;
background = NULL;
is_running = true;
who = PLAYER1;
}
int GameCore::execute()
@ -73,12 +68,12 @@ void GameCore::render()
{
DrawUtils::draw(display, background, 0, 0);
list<Vertex*> vertices = graph.get_vertices();
list<Edge> edges = graph.get_edges();
list<Vertex*> vertices = data.get_vertices();
list<Edge> edges = data.get_edges();
if (graph.get_current_vertex() != NULL)
if (data.get_current_vertex() != NULL)
{
Vertex* v = graph.get_current_vertex();
Vertex* v = data.get_current_vertex();
DrawUtils::draw_circle_filled(display, v->x, v->y,
MAX_MOVE_DISTANCE, 0xcb1919);
}
@ -125,26 +120,20 @@ void GameCore::on_exit()
void GameCore::on_lbutton_down(int x, int y)
{
Vertex* cv = graph.get_current_vertex();
Vertex* cv = data.get_current_vertex();
if (cv != NULL &&
(MathUtils::distance(cv->x, cv->y, x, y)
> MAX_MOVE_DISTANCE))
{
Vertex* v = graph.vertex_at(x, y);
if (v->colour == PLAYER1_COLOUR && turn == PLAYER1 ||
v->colour == PLAYER2_COLOUR && turn == PLAYER2)
graph.select_vertex(x, y);
data.select_vertex(x, y);
return;
}
graph.do_vertex(x, y, NODE_RADIUS, PLAYER1_COLOUR);
if (turn == PLAYER1) turn = PLAYER2;
else turn = PLAYER_1;
data.do_vertex(x, y, NODE_RADIUS);
}
void GameCore::on_rbutton_down(int mX, int mY)
{
graph.clear_current_vertex();
data.clear_current_vertex();
}

View File

@ -11,9 +11,7 @@
#include <SDL/SDL.h>
#include "mainevent.h"
#include "graph.h"
enum turn {PLAYER1, PLAYER2, WIN1, WIN2};
#include "gamedata.h"
class GameCore : public MainEvent
{
@ -42,13 +40,10 @@ class GameCore : public MainEvent
SDL_Surface* background;
// data
Graph graph;
turn who;
GameData data;
static int NODE_RADIUS;
static int MAX_MOVE_DISTANCE;
static int PLAYER1_COLOUR;
static int PLAYER2_COLOUR;
};

76
gamedata.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "gamedata.h"
#include "mathutils.h"
int GameData::PLAYER1_COLOUR = 0x4a483f;
int GameData::PLAYER2_COLOUR = 0x090c7a;
GameData::GameData()
: Graph(true)
{
current = NULL;
player = PLAYER1;
}
GameData::~GameData() { }
void GameData::toggle_turn()
{
if (player == PLAYER1) player = PLAYER2;
else if (player == PLAYER2) player = PLAYER1;
}
void GameData::do_vertex(int x, int y, int r)
{
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);
else add_vertex(x, y, r, colour);
}
void GameData::select_vertex(int x, int y)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if ((MathUtils::distance(v->x, v->y, x, y) <= v->r) &&
(v->colour == PLAYER1_COLOUR && player == PLAYER1 ||
v->colour == PLAYER2_COLOUR && player == PLAYER2))
{
current = v;
return;
}
}
}
bool GameData::add_vertex(int x, int y, int r, int colour)
{
// this is the special case for adding the first vertex for each player
if (current == NULL)
{
if ((player == PLAYER1 && !player1_played) ||
(player == PLAYER2 && !player2_played))
{
Graph::add_vertex(x, y, r, colour);
if (player == PLAYER1) player1_played = true;
if (player == PLAYER2) player2_played = true;
toggle_turn();
return true;
}
return false;
}
if (Graph::add_vertex(x, y, r, colour, current))
{
clear_current_vertex();
toggle_turn();
return true;
}
return false;
}

40
gamedata.h Normal file
View File

@ -0,0 +1,40 @@
/* This takes the general graph code and does stuff specific to the game
* with it. It stores the current turn, selected vertex and other useful
* information
*/
#ifndef _GAMEDATA_H_
#define _GAMEDATA_H_
#include "graph.h"
enum Turn {PLAYER1, PLAYER2, WIN1, WIN2};
class GameData : public Graph
{
public:
GameData();
~GameData();
Vertex* get_current_vertex() const { return current; }
void clear_current_vertex() { current = NULL; }
void toggle_turn();
// select or add vertex, as appropriate
void do_vertex(int x, int y, int r);
void select_vertex(int x, int y);
bool add_vertex(int x, int y, int r, int colour);
private:
Vertex* current;
Turn player;
bool player1_played;
bool player2_played;
static int PLAYER1_COLOUR;
static int PLAYER2_COLOUR;
};
#endif

View File

@ -2,9 +2,9 @@
#include "mathutils.h"
#include "debug.h"
Graph::Graph()
Graph::Graph(bool planar)
{
current_vertex = NULL;
this->planar = planar;
}
Graph::~Graph()
@ -17,7 +17,7 @@ Graph::~Graph()
}
}
bool Graph::vertex_present(int x, int y, int r)
bool Graph::point_in_vertex(int x, int y, int r)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
@ -30,6 +30,19 @@ bool Graph::vertex_present(int x, int y, int r)
}
Vertex * Graph::vertex_at(int x, int y)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, x, y) <= v->r) return v;
}
return NULL;
}
bool Graph::vertex_would_overlap(int x, int y, int r)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
@ -58,30 +71,7 @@ bool Graph::crosses_edge(Edge e)
}
void Graph::do_vertex(int x, int y, int r, int colour)
{
if (vertex_present(x, y, r)) select_vertex(x, y);
else add_vertex(x, y, r, colour);
}
Vertex* Graph::select_vertex(int x, int y)
{
for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++)
{
Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, x, y) <= v->r)
{
current_vertex = v
return;
}
}
return NULL;
}
void Graph::add_vertex(int x, int y, int r, int colour)
bool Graph::add_vertex(int x, int y, int r, int colour, Vertex* src)
{
Vertex* v = new Vertex(x, y, r, colour);
@ -92,36 +82,34 @@ void Graph::add_vertex(int x, int y, int r, int colour)
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to vertex collision: x=%d, y=%d, r=%d\n", v->x, v->y, v->r);
#endif
delete v;
return;
return false;
}
if (current_vertex == NULL)
if (src != NULL)
{
current_vertex = v;
vertices.push_back(v);
return;
}
Edge e;
e.a = src;
e.b = v;
Edge e;
e.a = current_vertex;
e.b = v;
if (crosses_edge(e))
{
if (planar && crosses_edge(e))
{
#ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to edge collision: x1=%d, y1=%d, x2=%d, y2=%d\n", e.a->x, e.a->y, e.b->x, e.b->y);
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to edge collision: x1=%d, y1=%d, x2=%d, y2=%d\n", e.a->x, e.a->y, e.b->x, e.b->y);
#endif
delete v;
return;
delete v;
return false;
}
edges.push_back(e);
}
vertices.push_back(v);
edges.push_back(e);
current_vertex = v;
#ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, r=%d\n", v->x, v->y, v->r);
#endif
return true;
}

21
graph.h
View File

@ -31,28 +31,29 @@ struct Edge
class Graph
{
public:
Graph();
~Graph();
bool vertex_present(int x, int y, int size);
Graph(bool planar);
virtual ~Graph();
list<Vertex*> get_vertices() const { return vertices; }
list<Edge> get_edges() const { return edges; }
void select_vertex(int x, int y);
void do_vertex(int x, int y, int r, int colour);
bool point_in_vertex(int x, int y, int size);
Vertex * vertex_at(int x, int y);
virtual bool add_vertex(int x, int y, int r, int colour, Vertex* src=NULL);
Vertex* get_current_vertex() const { return current_vertex; }
void clear_current_vertex() { current_vertex = NULL; }
bool is_planar() const { return planar; }
void set_planar(bool planar) { this->planar = planar; }
private:
void add_vertex(int x, int y, int r, int colour);
bool vertex_would_overlap(int x, int y, int r);
bool crosses_edge(Edge e);
Vertex* current_vertex;
protected:
list<Vertex*> vertices;
list<Edge> edges;
private:
bool planar;
};
#endif