diff --git a/Makefile b/Makefile index a79e1a3..6b9f8e1 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ LDFLAGS=`sdl-config --libs` -lSDL_ttf OBJECTS=\ main.o \ drawutils.o mathutils.o timer.o itos.o \ -graph.o gamedata.o \ +graph.o gamedata.o player.o \ mainevent.o gamestate.o game.o titlescreen.o all: $(PROJECT) diff --git a/game.cpp b/game.cpp index 8380752..3ba4b33 100644 --- a/game.cpp +++ b/game.cpp @@ -5,8 +5,6 @@ #include "itos.h" #include -int Game::NODE_RADIUS = 10; - Game::Game(stack* state_stack, SDL_Surface* display) : GameState(state_stack, display) @@ -54,9 +52,12 @@ void Game::render() switch(data.get_mode()) { - case MODE_MOVE: + case MODE_BUILD: range_colour = 0x0000ff; break; + case MODE_MOVE: + range_colour = 0x00ff00; + break; case MODE_ATTACK: range_colour = 0xff0000; break; @@ -68,7 +69,7 @@ void Game::render() list vertices = data.get_vertices(); // Now paint on the targeting circle - if (data.get_current_vertex() != NULL) + if (data.get_current_vertex(true) != NULL) { Vertex* v = data.get_current_vertex(); DrawUtils::draw_circle_filled(display, v->x, v->y, range, @@ -104,7 +105,7 @@ void Game::render() void Game::on_lbutton_down(int x, int y) { - data.do_vertex(x, y, NODE_RADIUS); + if (!data.endgame()) data.handle_click(x, y); } @@ -119,4 +120,5 @@ void Game::on_key_down(SDLKey sym, SDLMod mod, Uint16 unicode) if (sym == SDLK_q && mod & KMOD_CTRL) throw StateExit(); if (sym == SDLK_a) data.set_mode(MODE_ATTACK); if (sym == SDLK_m) data.set_mode(MODE_MOVE); + if (sym == SDLK_b) data.set_mode(MODE_BUILD); } diff --git a/gamedata.cpp b/gamedata.cpp index 7d5d36f..1feca5f 100644 --- a/gamedata.cpp +++ b/gamedata.cpp @@ -10,102 +10,114 @@ using std::list; int GameData::PLAYER1_COLOUR = 0x4a483f; int GameData::PLAYER2_COLOUR = 0x090c7a; -int GameData::BASE_MOVE_RADIUS = 75; +int GameData::BASE_BUILD_RADIUS = 75; +int GameData::NODE_RADIUS = 10; GameData::GameData() : Graph(true) { current = NULL; - player = PLAYER1; - mode = MODE_MOVE; + mode = MODE_BUILD; + player1 = Player(PLAYER1_COLOUR); + player2 = Player(PLAYER2_COLOUR); + turn = &player1; } GameData::~GameData() { } + +Vertex* GameData::get_current_vertex(bool only_mine) const +{ + if (only_mine) + { + if (current != NULL && + current->colour == turn->get_colour()) return current; + + return NULL; + } + + return current; +} + + void GameData::toggle_turn() { - mode = MODE_MOVE; - current = NULL; + if (!turn->has_played()) + { + set_mode(MODE_BUILD); + turn->set_played(); + } + else set_mode(MODE_SELECT); if (!endgame()) { - if (player == PLAYER1) player = PLAYER2; - else if (player == PLAYER2) player = PLAYER1; + if (turn == &player1) turn = &player2; + else if (turn == &player2) turn = &player1; + } } -void GameData::do_vertex(int x, int y, int r) +void GameData::handle_click(int x, int y) { - if (current != NULL && - (MathUtils::distance(current->x, current->y, current->z, x, y, 0) - > get_range())) - { - select_vertex(x, y); - return; - } + int r = 10; int colour; - if (player == PLAYER1) colour = PLAYER1_COLOUR; - if (player == PLAYER2) colour = PLAYER2_COLOUR; + colour = turn->get_colour(); - if (mode == MODE_MOVE) + if (mode == MODE_SELECT) { if (point_in_vertex(x, y, 0)) select_vertex(x, y); - else add_vertex(x, y, 0, r, colour); } - if (mode == MODE_ATTACK) + else if (mode == MODE_BUILD) + { + if (point_in_vertex(x, y, 0)) select_vertex(x, y, true); + if (!point_in_vertex(x, y, 0)) add_vertex(x, y, 0, r, colour); + } + else if (mode == MODE_ATTACK) { Vertex* v = vertex_at(x, y, 0); if (v == NULL) return; - - if (v->colour == colour) select_vertex(x, y); - else attack_vertex(v); + if (v->colour != colour) attack_vertex(v); } } -void GameData::select_vertex(int x, int y) +void GameData::select_vertex(int x, int y, bool only_mine) { + Vertex * v = vertex_at(x, y, 0); + if (v == NULL) return; - for (list::iterator cursor = vertices.begin(); - cursor != vertices.end(); cursor++) + if (only_mine && v->colour == turn->get_colour()) { - Vertex* v = *cursor; - if ((MathUtils::distance(v->x, v->y, v->z, x, y, 0) <= v->r) && - (v->colour == PLAYER1_COLOUR && player == PLAYER1 || - v->colour == PLAYER2_COLOUR && player == PLAYER2)) - { - current = v; - return; - } + current = v; + return; } + + current = v; } bool GameData::add_vertex(int x, int y, int z, int r, int colour) { - if (mode == MODE_ATTACK) return false; - 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)) + if (!turn->has_played()) { Graph::add_vertex(x, y, z, r, colour, 10); #ifdef DEBUG fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n", calculate_strength(*(vertices.rbegin()))); #endif - if (player == PLAYER1) player1_played = true; - if (player == PLAYER2) player2_played = true; toggle_turn(); return true; } return false; } + if (current->colour != turn->get_colour()) return false; + if (Graph::add_vertex(x, y, z, r, colour, 10, current)) { #ifdef DEBUG @@ -176,15 +188,22 @@ float GameData::calculate_strength_r(Vertex* node, unsigned int depth, listget_energy(); + else if (mode == MODE_BUILD) return BASE_BUILD_RADIUS; else if (mode == MODE_ATTACK) { - int range = BASE_MOVE_RADIUS; + int range = BASE_BUILD_RADIUS; list neighbors = node->neighbors; for(list::iterator cursor = neighbors.begin(); @@ -223,17 +242,15 @@ void GameData::attack_vertex(Vertex* target) bool GameData::endgame() { - if (!(player1_played && player2_played)) return false; + if (!(player1.has_played() && player2.has_played())) return false; - if (get_colour(PLAYER1_COLOUR).empty()) + if (get_colour(player1.get_colour()).empty()) { - player = WIN2; debug("Gamedata::endgame(): player 2 wins\n"); return true; } - if (get_colour(PLAYER2_COLOUR).empty()) + if (get_colour(player2.get_colour()).empty()) { - player = WIN1; debug("Gamedata::endgame(): player 1 wins\n"); return true; } diff --git a/gamedata.h b/gamedata.h index 4de4ded..846608a 100644 --- a/gamedata.h +++ b/gamedata.h @@ -7,9 +7,9 @@ #define _GAMEDATA_H_ #include "graph.h" +#include "player.h" -enum Turn {PLAYER1, PLAYER2, WIN1, WIN2}; -enum Mode {MODE_MOVE, MODE_ATTACK}; +enum Mode {MODE_MOVE, MODE_ATTACK, MODE_BUILD, MODE_SELECT}; enum VertexType {ATTACKER, DEFENDER, PRODUCER}; class GameVertex : public Vertex @@ -25,20 +25,20 @@ class GameData : public Graph GameData(); ~GameData(); - Vertex* get_current_vertex() const { return current; } + Vertex* get_current_vertex(bool only_mine = false) const; 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); + void handle_click(int x, int y); + void select_vertex(int x, int y, bool only_mine = false); void attack_vertex(Vertex* target); bool add_vertex(int x, int y, int z, int r, int colour); Mode get_mode() const { return mode; } - Mode set_mode(Mode m) { mode = m; } + Mode set_mode(Mode m); // returns the move/attack range for the specified node // (or the selected node if node == NULL) @@ -46,22 +46,22 @@ class GameData : public Graph // check for (and set, if needed) winner bool endgame(); - Turn get_turn() const { return player; } + Player* get_turn() const { return turn; } float calculate_strength(Vertex* node); private: float calculate_strength_r(Vertex* node, unsigned int depth, list& visited); Vertex* current; - Turn player; Mode mode; - bool player1_played; - bool player2_played; + Player player1, player2; + Player* turn; static int PLAYER1_COLOUR; static int PLAYER2_COLOUR; - static int BASE_MOVE_RADIUS; + static int BASE_BUILD_RADIUS; + static int NODE_RADIUS; }; #endif diff --git a/player.cpp b/player.cpp new file mode 100644 index 0000000..5224d29 --- /dev/null +++ b/player.cpp @@ -0,0 +1,28 @@ +#include "player.h" + +Player::Player(unsigned int colour) +{ + this->colour = colour; + energy = 50; +} + + +void Player::add_energy(unsigned int amount) +{ + energy += amount; +} + + +bool Player::spend_energy(unsigned int amount) +{ + if (amount > energy) return false; + + energy -= amount; + return true; +} + + +void Player::set_played() +{ + played = true; +} diff --git a/player.h b/player.h new file mode 100644 index 0000000..a5d769c --- /dev/null +++ b/player.h @@ -0,0 +1,27 @@ +/* Holds some useful data about each player + */ + +#ifndef _PLAYER_H_ +#define _PLAYER_H_ + +class Player +{ + public: + Player(unsigned int colour = 0x000000); + + unsigned int get_energy() const { return energy; } + unsigned int get_colour() const { return colour; } + + void add_energy(unsigned int amount); + bool spend_energy(unsigned int amount); + + bool has_played() const { return played; } + void set_played(); + + private: + unsigned int energy; + unsigned int colour; + bool played; +}; + +#endif