Laid the groundwork for a more complex game - introduced a couple of bugs (can attack from anywhere, can't select another of your own vertices in attack mode...)

This commit is contained in:
Anna Rose 2011-07-01 14:10:45 -04:00
parent d1c11799f4
commit 4daaced5d7
6 changed files with 138 additions and 64 deletions

View File

@ -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 \ graph.o gamedata.o player.o \
mainevent.o gamestate.o game.o titlescreen.o mainevent.o gamestate.o game.o titlescreen.o
all: $(PROJECT) all: $(PROJECT)

View File

@ -5,8 +5,6 @@
#include "itos.h" #include "itos.h"
#include <SDL.h> #include <SDL.h>
int Game::NODE_RADIUS = 10;
Game::Game(stack<GameState*>* state_stack, SDL_Surface* display) Game::Game(stack<GameState*>* state_stack, SDL_Surface* display)
: GameState(state_stack, display) : GameState(state_stack, display)
@ -54,9 +52,12 @@ void Game::render()
switch(data.get_mode()) switch(data.get_mode())
{ {
case MODE_MOVE: case MODE_BUILD:
range_colour = 0x0000ff; range_colour = 0x0000ff;
break; break;
case MODE_MOVE:
range_colour = 0x00ff00;
break;
case MODE_ATTACK: case MODE_ATTACK:
range_colour = 0xff0000; range_colour = 0xff0000;
break; break;
@ -68,7 +69,7 @@ void Game::render()
list<Vertex*> vertices = data.get_vertices(); list<Vertex*> vertices = data.get_vertices();
// Now paint on the targeting circle // 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(); Vertex* v = data.get_current_vertex();
DrawUtils::draw_circle_filled(display, v->x, v->y, range, 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) 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_q && mod & KMOD_CTRL) throw StateExit();
if (sym == SDLK_a) data.set_mode(MODE_ATTACK); if (sym == SDLK_a) data.set_mode(MODE_ATTACK);
if (sym == SDLK_m) data.set_mode(MODE_MOVE); if (sym == SDLK_m) data.set_mode(MODE_MOVE);
if (sym == SDLK_b) data.set_mode(MODE_BUILD);
} }

View File

@ -10,102 +10,114 @@ using std::list;
int GameData::PLAYER1_COLOUR = 0x4a483f; int GameData::PLAYER1_COLOUR = 0x4a483f;
int GameData::PLAYER2_COLOUR = 0x090c7a; int GameData::PLAYER2_COLOUR = 0x090c7a;
int GameData::BASE_MOVE_RADIUS = 75; int GameData::BASE_BUILD_RADIUS = 75;
int GameData::NODE_RADIUS = 10;
GameData::GameData() GameData::GameData()
: Graph(true) : Graph(true)
{ {
current = NULL; current = NULL;
player = PLAYER1; mode = MODE_BUILD;
mode = MODE_MOVE; player1 = Player(PLAYER1_COLOUR);
player2 = Player(PLAYER2_COLOUR);
turn = &player1;
} }
GameData::~GameData() { } 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() void GameData::toggle_turn()
{ {
mode = MODE_MOVE; if (!turn->has_played())
current = NULL; {
set_mode(MODE_BUILD);
turn->set_played();
}
else set_mode(MODE_SELECT);
if (!endgame()) if (!endgame())
{ {
if (player == PLAYER1) player = PLAYER2; if (turn == &player1) turn = &player2;
else if (player == PLAYER2) player = PLAYER1; 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 && int r = 10;
(MathUtils::distance(current->x, current->y, current->z, x, y, 0)
> get_range()))
{
select_vertex(x, y);
return;
}
int colour; int colour;
if (player == PLAYER1) colour = PLAYER1_COLOUR; colour = turn->get_colour();
if (player == PLAYER2) colour = PLAYER2_COLOUR;
if (mode == MODE_MOVE) if (mode == MODE_SELECT)
{ {
if (point_in_vertex(x, y, 0)) select_vertex(x, y); 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) attack_vertex(v);
}
}
void GameData::select_vertex(int x, int y, bool only_mine)
{ {
Vertex * v = vertex_at(x, y, 0); Vertex * v = vertex_at(x, y, 0);
if (v == NULL) return; if (v == NULL) return;
if (v->colour == colour) select_vertex(x, y); if (only_mine && v->colour == turn->get_colour())
else attack_vertex(v);
}
}
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, v->z, x, y, 0) <= v->r) &&
(v->colour == PLAYER1_COLOUR && player == PLAYER1 ||
v->colour == PLAYER2_COLOUR && player == PLAYER2))
{ {
current = v; current = v;
return; return;
} }
}
current = v;
} }
bool GameData::add_vertex(int x, int y, int z, int r, int colour) bool GameData::add_vertex(int x, int y, int z, int r, int colour)
{ {
if (mode == MODE_ATTACK) return false;
if (current == NULL) if (current == NULL)
{ {
// this is the special case for adding the first vertex for each player // this is the special case for adding the first vertex for each player
if ((player == PLAYER1 && !player1_played) || if (!turn->has_played())
(player == PLAYER2 && !player2_played))
{ {
Graph::add_vertex(x, y, z, r, colour, 10); Graph::add_vertex(x, y, z, r, colour, 10);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n", fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n",
calculate_strength(*(vertices.rbegin()))); calculate_strength(*(vertices.rbegin())));
#endif #endif
if (player == PLAYER1) player1_played = true;
if (player == PLAYER2) player2_played = true;
toggle_turn(); toggle_turn();
return true; return true;
} }
return false; return false;
} }
if (current->colour != turn->get_colour()) return false;
if (Graph::add_vertex(x, y, z, r, colour, 10, current)) if (Graph::add_vertex(x, y, z, r, colour, 10, current))
{ {
#ifdef DEBUG #ifdef DEBUG
@ -176,15 +188,22 @@ float GameData::calculate_strength_r(Vertex* node, unsigned int depth, list<Vert
} }
Mode GameData::set_mode(Mode m)
{
mode = m;
}
int GameData::get_range(Vertex* node) int GameData::get_range(Vertex* node)
{ {
if (node == NULL) node = current; if (node == NULL) node = current;
if (node == NULL) return 0; if (node == NULL) return 0;
else if (mode == MODE_MOVE) return BASE_MOVE_RADIUS; else if (mode == MODE_MOVE) return turn->get_energy();
else if (mode == MODE_BUILD) return BASE_BUILD_RADIUS;
else if (mode == MODE_ATTACK) else if (mode == MODE_ATTACK)
{ {
int range = BASE_MOVE_RADIUS; int range = BASE_BUILD_RADIUS;
list<Vertex*> neighbors = node->neighbors; list<Vertex*> neighbors = node->neighbors;
for(list<Vertex*>::iterator cursor = neighbors.begin(); for(list<Vertex*>::iterator cursor = neighbors.begin();
@ -223,17 +242,15 @@ void GameData::attack_vertex(Vertex* target)
bool GameData::endgame() 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"); debug("Gamedata::endgame(): player 2 wins\n");
return true; return true;
} }
if (get_colour(PLAYER2_COLOUR).empty()) if (get_colour(player2.get_colour()).empty())
{ {
player = WIN1;
debug("Gamedata::endgame(): player 1 wins\n"); debug("Gamedata::endgame(): player 1 wins\n");
return true; return true;
} }

View File

@ -7,9 +7,9 @@
#define _GAMEDATA_H_ #define _GAMEDATA_H_
#include "graph.h" #include "graph.h"
#include "player.h"
enum Turn {PLAYER1, PLAYER2, WIN1, WIN2}; enum Mode {MODE_MOVE, MODE_ATTACK, MODE_BUILD, MODE_SELECT};
enum Mode {MODE_MOVE, MODE_ATTACK};
enum VertexType {ATTACKER, DEFENDER, PRODUCER}; enum VertexType {ATTACKER, DEFENDER, PRODUCER};
class GameVertex : public Vertex class GameVertex : public Vertex
@ -25,20 +25,20 @@ class GameData : public Graph
GameData(); GameData();
~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 clear_current_vertex() { current = NULL; }
void toggle_turn(); void toggle_turn();
// select or add vertex, as appropriate // select or add vertex, as appropriate
void do_vertex(int x, int y, int r); void handle_click(int x, int y);
void select_vertex(int x, int y); void select_vertex(int x, int y, bool only_mine = false);
void attack_vertex(Vertex* target); void attack_vertex(Vertex* target);
bool add_vertex(int x, int y, int z, int r, int colour); bool add_vertex(int x, int y, int z, int r, int colour);
Mode get_mode() const { return mode; } 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 // returns the move/attack range for the specified node
// (or the selected node if node == NULL) // (or the selected node if node == NULL)
@ -46,22 +46,22 @@ class GameData : public Graph
// check for (and set, if needed) winner // check for (and set, if needed) winner
bool endgame(); bool endgame();
Turn get_turn() const { return player; } Player* get_turn() const { return turn; }
float calculate_strength(Vertex* node); float calculate_strength(Vertex* node);
private: private:
float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited); float calculate_strength_r(Vertex* node, unsigned int depth, list<Vertex*>& visited);
Vertex* current; Vertex* current;
Turn player;
Mode mode; Mode mode;
bool player1_played; Player player1, player2;
bool player2_played; Player* turn;
static int PLAYER1_COLOUR; static int PLAYER1_COLOUR;
static int PLAYER2_COLOUR; static int PLAYER2_COLOUR;
static int BASE_MOVE_RADIUS; static int BASE_BUILD_RADIUS;
static int NODE_RADIUS;
}; };
#endif #endif

28
player.cpp Normal file
View File

@ -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;
}

27
player.h Normal file
View File

@ -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