From 5ed05fc8297f46f4e6e29b60e8da4b89e928fe45 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Thu, 23 Jun 2011 17:28:49 -0400 Subject: [PATCH] Separated game-specific graph behavior into a subclass, implemented 2 players alternating turns --- Makefile | 2 +- gamecore.cpp | 27 ++++++------------- gamecore.h | 9 ++----- gamedata.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gamedata.h | 40 +++++++++++++++++++++++++++ graph.cpp | 76 ++++++++++++++++++++++------------------------------ graph.h | 21 ++++++++------- 7 files changed, 170 insertions(+), 81 deletions(-) create mode 100644 gamedata.cpp create mode 100644 gamedata.h diff --git a/Makefile b/Makefile index ccbc8db..0ea3831 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/gamecore.cpp b/gamecore.cpp index 1674f5b..d5e8fba 100644 --- a/gamecore.cpp +++ b/gamecore.cpp @@ -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 vertices = graph.get_vertices(); - list edges = graph.get_edges(); + list vertices = data.get_vertices(); + list 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(); } diff --git a/gamecore.h b/gamecore.h index 675bdd7..4d13d24 100644 --- a/gamecore.h +++ b/gamecore.h @@ -11,9 +11,7 @@ #include #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; }; diff --git a/gamedata.cpp b/gamedata.cpp new file mode 100644 index 0000000..cd69f77 --- /dev/null +++ b/gamedata.cpp @@ -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::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; +} diff --git a/gamedata.h b/gamedata.h new file mode 100644 index 0000000..14e5408 --- /dev/null +++ b/gamedata.h @@ -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 diff --git a/graph.cpp b/graph.cpp index d77e531..f427b79 100644 --- a/graph.cpp +++ b/graph.cpp @@ -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::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::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::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::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; } diff --git a/graph.h b/graph.h index a4025dc..22d738b 100644 --- a/graph.h +++ b/graph.h @@ -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 get_vertices() const { return vertices; } list 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 vertices; list edges; + + private: + bool planar; }; #endif