Manage players from a sepeate class.

This commit is contained in:
Tim Schubert 2016-01-31 14:34:53 +01:00
parent 230408e2fc
commit 75906f2353
8 changed files with 188 additions and 214 deletions

View file

@ -4,17 +4,23 @@ cmake_minimum_required(VERSION 3.3)
set(CMAKE_C_COMPILER /usr/bin/clang) set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++) set(CMAKE_CXX_COMPILER /usr/bin/clang++)
add_definitions(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
find_library(SDL2_LIB SDL2) find_library(SDL2_LIB SDL2)
find_library(SDL2_GFX_LIB SDL2_gfx) find_library(SDL2_GFX_LIB SDL2_gfx)
find_library(SDL2_IMAGE_LIB SDL2_image) find_library(SDL2_IMAGE_LIB SDL2_image)
find_library(SDL2_TTF_LIB SDL2_ttf) find_library(SDL2_TTF_LIB SDL2_ttf)
find_library(BOOST_UUID_LIB boost/uuid) find_library(BOOST_UUID_LIB boost/uuid)
find_program(CTEST_MEMORYCHECK_COMMAND valgrind)
enable_testing()
add_test(NAME memtest COMMAND /usr/bin/valgrind -v --trace-children=yes --tool=memcheck ${CMAKE_BINARY_DIR}/build/bin/Bob)
add_test(NAME calltest COMMAND /usr/bin/valgrind -v --trace-children=yes --tool=callgrind ${CMAKE_BINARY_DIR}/build/bin/Bob)
add_subdirectory(src) add_subdirectory(src)

View file

@ -146,10 +146,6 @@ void Game::handle_event(SDL_Event *event)
{ {
this->upgrade_box->handle_event(event); this->upgrade_box->handle_event(event);
} }
for (Player *p : this->players)
{
p->handle_event(event);
}
} }
if (event->type == BOB_NEXTROUNDEVENT || event->type == BOB_FIELDUPDATEEVENT if (event->type == BOB_NEXTROUNDEVENT || event->type == BOB_FIELDUPDATEEVENT
|| event->type == BOB_FIELDUPGRADEVENT || event->type == BOB_NEXTTURNEVENT) || event->type == BOB_FIELDUPGRADEVENT || event->type == BOB_NEXTTURNEVENT)
@ -157,26 +153,20 @@ void Game::handle_event(SDL_Event *event)
this->grid->handle_event(event); this->grid->handle_event(event);
this->field_box->handle_event(event); this->field_box->handle_event(event);
this->upgrade_box->handle_event(event); this->upgrade_box->handle_event(event);
for (Player *p : this->players)
{
p->handle_event(event);
}
} }
else if (event->type == BOB_FIELDSELECTEDEVENT && !this->started) else if (event->type == BOB_FIELDSELECTEDEVENT && !this->started)
{ {
FieldMeta *field = (FieldMeta *) event->user.data1; FieldMeta *field = (FieldMeta *) event->user.data1;
if (event->user.code == 0 && this->adding != nullptr) if (event->user.code == 0 && this->adding != pm->default_player)
{ {
if (this->grid->place(this->adding, field)) if (this->grid->place(this->adding, field))
{ {
this->players.push_back(this->adding); PlayerManager::pm->add_player(this->adding);
prompt << "Added Player: " << this->adding->get_name(); prompt << "Added Player: " << this->adding.get_name();
this->adding = nullptr;
} }
else else
{ {
prompt << "Failed to add Player: " << this->adding->get_name(); prompt << "Failed to add Player: " << this->adding.get_name();
delete this->adding;
} }
} }
this->text_input_box->prompt(prompt.str()); this->text_input_box->prompt(prompt.str());
@ -206,7 +196,7 @@ void Game::command(std::string input)
if (this->started) if (this->started)
{ {
this->next_turn(); this->next_turn();
prompt << "Next player is: " << (Player::current_player)->get_name(); prompt << "Next player is: " << PlayerManager::pm->get_current().get_name();
} }
else else
{ {
@ -215,31 +205,23 @@ void Game::command(std::string input)
} }
else if (input == "surrender") else if (input == "surrender")
{ {
this->grid->surrender(Player::current_player); Player current = PlayerManager::pm->get_current();
prompt << "Player " << Player::current_player->get_name() << " surrendered!\n"; PlayerManager::pm->surrender(current, this->grid);
for (int i = 0; i < this->players.size(); i++) prompt << "Player " << current.get_name() << " surrendered!\n";
{
if (this->players[i] == Player::current_player)
{
delete this->players[i];
this->players.erase(this->players.begin() + i);
}
}
this->next_turn(); this->next_turn();
} }
else if (input.substr(0, 10) == "add player") else if (input.substr(0, 10) == "add player")
{ {
if (!this->started) if (!this->started)
{ {
if (this->adding != nullptr) if (this->adding != pm->default_player)
{ {
this->grid->set_selecting(false); this->grid->set_selecting(false);
prompt << "Failed to add player " << this->adding->get_name() << "!df\n"; prompt << "Failed to add player " << this->adding.get_name() << "!df\n";
delete this->adding;
} }
this->grid->set_selecting(true); this->grid->set_selecting(true);
this->adding = new Player(input.substr(11, std::string::npos)); this->adding = Player(input.substr(11, std::string::npos));
prompt << "Select a place for " << this->adding->get_name() << ", please!"; prompt << "Select a place for " << this->adding.get_name() << ", please!";
this->text_input_box->stop(); this->text_input_box->stop();
} }
else else
@ -249,7 +231,7 @@ void Game::command(std::string input)
} }
else if (input == "start") else if (input == "start")
{ {
if (this->players.size() < 2) if (PlayerManager::pm->get_num_players() < 2)
{ {
prompt << "Please add at least one player, before starting the game."; prompt << "Please add at least one player, before starting the game.";
} }
@ -269,37 +251,14 @@ void Game::command(std::string input)
void Game::start() void Game::start()
{ {
this->players.erase(players.begin()); // remove default player from vector PlayerManager::pm->shuffle();
std::random_shuffle(players.begin(), players.end());
this->turn = 0;
Player::current_player = players[0];
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, (void *) Player::current_player);
trigger_event(BOB_NEXTTURNEVENT, 0, nullptr, (void *) Player::current_player);
} }
void Game::next_turn() void Game::next_turn()
{ {
if (!this->players.empty()) if (this->started)
{ {
Player *last_player = Player::current_player; pm->next_turn();
this->turn = (this->turn + 1) % players.size();
Player::current_player = players[turn];
if (this->turn == 0)
{
trigger_event(BOB_NEXTTURNEVENT, 0, (void *) last_player, (void *) Player::current_player);
trigger_event(BOB_NEXTROUNDEVENT, 0, (void *) last_player, (void *) Player::current_player);
}
else
{
trigger_event(BOB_NEXTTURNEVENT, 0, (void *) last_player, (void *) Player::current_player);
}
}
else
{
Player *def = new Player();
Player::current_player = def;
this->players.push_back(def);
this->started = false;
} }
} }
@ -374,6 +333,7 @@ void init_ttf()
int main(int, char **) int main(int, char **)
{ {
PlayerManager::init();
try try
{ {
init_sdl(SDL_INIT_VIDEO); init_sdl(SDL_INIT_VIDEO);
@ -387,11 +347,12 @@ int main(int, char **)
SDL_Rect bounds; SDL_Rect bounds;
SDL_GetDisplayBounds(0, &bounds); SDL_GetDisplayBounds(0, &bounds);
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600}; SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600};
Game *game = new Game(&window_dimensions, 10);
int exit_status = 1; int exit_status = 1;
Game *game = new Game(&window_dimensions, 10, PlayerManager::pm);
exit_status = game->game_loop(); exit_status = game->game_loop();
delete game; delete game;
TTF_Quit();
SDL_Quit(); SDL_Quit();
PlayerManager::destroy();
TTF_Quit();
return exit_status; return exit_status;
} }

View file

@ -18,9 +18,10 @@ class Game
{ {
public: public:
Game(SDL_Rect *window_dimensions, Sint16 size) Game(SDL_Rect *window_dimensions, Sint16 size, PlayerManager *pm)
: pm(pm)
{ {
this->adding = nullptr; this->adding = pm->default_player;
this->started = false; this->started = false;
this->layout = new Layout(pointy_orientation, 20, this->layout = new Layout(pointy_orientation, 20,
{window_dimensions->w / 2, window_dimensions->h / 2}, {window_dimensions->w / 2, window_dimensions->h / 2},
@ -31,9 +32,6 @@ public:
} }
this->quit = false; this->quit = false;
SDL_Color fg = {0x00, 0x00, 0x00, 0xff}; SDL_Color fg = {0x00, 0x00, 0x00, 0xff};
this->players = std::vector<Player *>();
Player *default_player = new Player();
this->players.push_back(default_player);
try try
{ {
this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20); this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20);
@ -45,9 +43,6 @@ public:
FieldMeta *center = this->grid->get_field({0, 0, 0}); FieldMeta *center = this->grid->get_field({0, 0, 0});
this->field_box = new FieldBox(this->renderer, {0, 0, 200, 100}, fg, this->font, center); this->field_box = new FieldBox(this->renderer, {0, 0, 200, 100}, fg, this->font, center);
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 200, 20}, fg, this->font, center); this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 200, 20}, fg, this->font, center);
this->next_turn_button = new NextTurnButtonBox(this->renderer,
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
this->font, &(this->players));
int font_height = TTF_FontHeight(this->font); int font_height = TTF_FontHeight(this->font);
this->text_input_box = new TextInputBox(this->renderer, {0, 0, window_size.x, font_height}, fg, this->font); this->text_input_box = new TextInputBox(this->renderer, {0, 0, window_size.x, font_height}, fg, this->font);
this->text_input_box->stop(); this->text_input_box->stop();
@ -58,18 +53,16 @@ public:
} }
this->frame_timer = new Timer(); this->frame_timer = new Timer();
this->move_timer = new Timer(); this->move_timer = new Timer();
this->turn = 0; //Player::current_player = this->players[turn];
Player::current_player = this->players[turn];
} }
~Game() ~Game()
{ {
for (auto player : this->players) /*for (auto player : this->players)
{ {
delete player; delete player;
} }*/
delete text_input_box; delete text_input_box;
delete this->next_turn_button;
delete this->upgrade_box; delete this->upgrade_box;
delete this->field_box; delete this->field_box;
delete this->move_timer; delete this->move_timer;
@ -78,11 +71,12 @@ public:
delete this->renderer; delete this->renderer;
delete this->window; delete this->window;
delete this->layout; delete this->layout;
if (this->adding != nullptr) }
PlayerManager *get_player_manager()
{ {
delete this->adding; return this->pm;
} };
}
void start(); void start();
@ -98,11 +92,10 @@ public:
private: private:
bool started; bool started;
Player *adding; Player adding;
Uint64 turn;
TextInputBox *text_input_box; TextInputBox *text_input_box;
std::vector<Player *> players; //std::vector<Player *> players;
NextTurnButtonBox *next_turn_button; PlayerManager *pm;
UpgradeBox *upgrade_box; UpgradeBox *upgrade_box;
FieldBox *field_box; FieldBox *field_box;
TTF_Font *font; TTF_Font *font;
@ -110,7 +103,6 @@ private:
Renderer *renderer; Renderer *renderer;
HexagonGrid *grid; HexagonGrid *grid;
Layout *layout; Layout *layout;
Container *side_bar;
bool move[4]; bool move[4];
bool quit; bool quit;
Timer *frame_timer; Timer *frame_timer;

View file

@ -1,2 +1,2 @@
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp Pixelmask.h Wrapper.hpp Wrapper.cpp) add_executable(Bob Bob.cpp Gameplay.cpp Gui.cpp Events.cpp Wrapper.cpp Bots.hpp Bots.cpp)
target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES}) target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES})

View file

@ -1,6 +1,6 @@
#include "Gameplay.hpp" #include "Gameplay.hpp"
Player *Player::current_player = nullptr; PlayerManager *PlayerManager::pm = nullptr;
SDL_Point operator+(SDL_Point left, SDL_Point right) SDL_Point operator+(SDL_Point left, SDL_Point right)
{ {
@ -232,7 +232,7 @@ Cluster HexagonGrid::get_cluster(FieldMeta *field)
{ {
FieldMeta *neighbor = this->get_neighbor(current, i); FieldMeta *neighbor = this->get_neighbor(current, i);
// neighbor is unvisited, unseen and inside same cluster // neighbor is unvisited, unseen and inside same cluster
if (neighbor != nullptr && *(neighbor->get_owner()) == *(current->get_owner()) if (neighbor != nullptr && neighbor->get_owner() == current->get_owner()
&& visited.find(neighbor) == visited.end() && seen.find(neighbor) == seen.end()) && visited.find(neighbor) == visited.end() && seen.find(neighbor) == seen.end())
{ {
seen.insert(neighbor); // discovered an unseen neighbor, will visit later seen.insert(neighbor); // discovered an unseen neighbor, will visit later
@ -265,7 +265,7 @@ bool Player::fight(FieldMeta *field)
{ {
bool is_neighbor = false; // player has a field around here bool is_neighbor = false; // player has a field around here
// friendly fire or owned by default player // friendly fire or owned by default player
if (*this == *(field->get_owner()) || field->get_owner()->get_id() == boost::uuids::nil_uuid()) if (*this == field->get_owner() || field->get_owner().get_id() == boost::uuids::nil_uuid())
{ {
return false; return false;
} }
@ -281,14 +281,14 @@ bool Player::fight(FieldMeta *field)
{ {
continue; continue;
} }
if (*(neighbor->get_owner()) == *this) // comparison by UUID, attacking player if (neighbor->get_owner() == *this) // comparison by UUID, attacking player
{ {
Cluster temp_attackers_cluster = neighbor->get_grid()->get_cluster(neighbor); Cluster temp_attackers_cluster = neighbor->get_grid()->get_cluster(neighbor);
attackers_cluster.insert(temp_attackers_cluster.begin(), temp_attackers_cluster.end()); attackers_cluster.insert(temp_attackers_cluster.begin(), temp_attackers_cluster.end());
power_level -= neighbor->get_offense(); power_level -= neighbor->get_offense();
is_neighbor = true; is_neighbor = true;
} }
else if (*(neighbor->get_owner()) == *(field->get_owner())) // attacked player else if (neighbor->get_owner() == field->get_owner()) // attacked player
{ {
power_level += neighbor->get_defense(); power_level += neighbor->get_defense();
} }
@ -300,7 +300,7 @@ bool Player::fight(FieldMeta *field)
{ {
field->get_grid()->consume_resources_of_cluster(&attackers_cluster, costs); field->get_grid()->consume_resources_of_cluster(&attackers_cluster, costs);
field->get_grid()->consume_resources_of_cluster(&defenders_cluster, costs); field->get_grid()->consume_resources_of_cluster(&defenders_cluster, costs);
field->set_owner(this); field->set_owner(*this);
return true; return true;
} }
else // lost else // lost
@ -326,7 +326,7 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
location.x = (int) precise_location.x; location.x = (int) precise_location.x;
location.y = (int) precise_location.y; location.y = (int) precise_location.y;
std::vector<Point> polygon = this->field.field_to_polygon(layout); std::vector<Point> polygon = this->field.field_to_polygon(layout);
SDL_Color color = this->owner->get_color(); SDL_Color color = this->owner.get_color();
Sint16 vx[6]; Sint16 vx[6];
Sint16 vy[6]; Sint16 vy[6];
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
@ -334,16 +334,12 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
vx[i] = (Sint16) polygon[i].x; vx[i] = (Sint16) polygon[i].x;
vy[i] = (Sint16) polygon[i].y; vy[i] = (Sint16) polygon[i].y;
} }
if (this->owner->get_id().is_nil()) if (this->owner.get_id().is_nil())
color = {0x77, 0x77, 0x77, 0xff}; color = {0x22, 0x22, 0x22, 0xff};
if (this->get_grid()->get_attack_marker() == this) if (this->get_grid()->get_attack_marker() == this)
color = {0x0, 0x77, 0x77, 0xff}; color = {0x0, 0x77, 0x77, 0xff};
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77); filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0xff);
SDL_Color inverse; SDL_Color fg = {0xff, 0xff, 0xff, 0xff};
inverse.r = (Uint8) (color.r + 0x77);
inverse.g = (Uint8) (color.g + 0x77);
inverse.b = (Uint8) (color.b + 0x77);
inverse.a = 0xff;
double resource_size = layout->size / 4; double resource_size = layout->size / 4;
if (this->resources_base.triangle > 0) if (this->resources_base.triangle > 0)
{ {
@ -355,12 +351,12 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size)); vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size)); vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
} }
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a); trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], fg.r, fg.g, fg.b, fg.a);
} }
if (this->resources_base.circle > 0) if (this->resources_base.circle > 0)
{ {
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g, circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, fg.r, fg.g,
inverse.b, inverse.a); fg.b, fg.a);
} }
if (this->resources_base.square > 0) if (this->resources_base.square > 0)
{ {
@ -373,7 +369,7 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
vx[i] = (Sint16) (location.x + square[i].x * resource_size); vx[i] = (Sint16) (location.x + square[i].x * resource_size);
vy[i] = (Sint16) (location.y + square[i].y * resource_size); vy[i] = (Sint16) (location.y + square[i].y * resource_size);
} }
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a); polygonRGBA(renderer, vx, vy, 4, fg.r, fg.g, fg.b, fg.a);
} }
} }
@ -504,7 +500,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
{ {
if (this->attack_marker == this->marker) if (this->attack_marker == this->marker)
{ {
Player::current_player->fight(this->attack_marker); PlayerManager::pm->get_current().fight(this->attack_marker);
} }
this->attack_marker = nullptr; this->attack_marker = nullptr;
} }
@ -526,7 +522,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
field.second->regenerate_resources(); field.second->regenerate_resources();
} }
} }
else if (event->type == BOB_NEXTTURNEVENT) if (event->type == BOB_NEXTTURNEVENT || event->type == BOB_NEXTROUNDEVENT)
{ {
std::default_random_engine generator; std::default_random_engine generator;
std::normal_distribution<double> distribution(0.0, 1.0); std::normal_distribution<double> distribution(0.0, 1.0);
@ -534,13 +530,12 @@ void HexagonGrid::handle_event(SDL_Event *event)
for (auto pair : this->fields) for (auto pair : this->fields)
{ {
FieldMeta *field = pair.second; FieldMeta *field = pair.second;
if (*(field->get_owner()) == *(Player::current_player)) if (field->get_owner() == PlayerManager::pm->get_current())
{ {
for (Uint8 i = 0; i < 6; i++) for (Uint8 i = 0; i < 6; i++)
{ {
FieldMeta *neighbor = field->get_neighbor(i); FieldMeta *neighbor = field->get_neighbor(i);
if (neighbor != nullptr && neighbor->get_owner()->get_id() == boost::uuids::nil_uuid() if (neighbor != nullptr && neighbor->get_owner() == PlayerManager::pm->default_player
&& (neighbor->get_reproduction() > distribution(generator))) && (neighbor->get_reproduction() > distribution(generator)))
{ {
aquired.insert(neighbor); aquired.insert(neighbor);
@ -550,7 +545,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
} }
for (auto foo : aquired) for (auto foo : aquired)
{ {
foo->set_owner(Player::current_player); foo->set_owner(PlayerManager::pm->get_current());
foo->set_defense(1); foo->set_defense(1);
foo->set_offense(1); foo->set_offense(1);
} }
@ -650,14 +645,14 @@ bool inside_target(const SDL_Rect *box, const SDL_Point *position)
box->y + box->h > position->y; box->y + box->h > position->y;
} }
bool HexagonGrid::place(Player *player, FieldMeta *center) bool HexagonGrid::place(Player &player, FieldMeta *center)
{ {
std::vector<FieldMeta *> selected; std::vector<FieldMeta *> selected;
selected.push_back(center); selected.push_back(center);
for (Uint8 i = 0; i < 6; i++) for (Uint8 i = 0; i < 6; i++)
{ {
FieldMeta *neighbor = center->get_neighbor(i); FieldMeta *neighbor = center->get_neighbor(i);
if (neighbor->get_owner()->get_id() == boost::uuids::nil_uuid()) if (neighbor != nullptr && neighbor->get_owner().get_id() == boost::uuids::nil_uuid())
{ {
selected.push_back(neighbor); selected.push_back(neighbor);
} }
@ -693,17 +688,88 @@ void Player::handle_event(SDL_Event *event)
} }
} }
void HexagonGrid::surrender(Player *player) void HexagonGrid::free(Player &player)
{ {
for (std::pair<Field, FieldMeta *> pair : this->fields) for (std::pair<Field, FieldMeta *> pair : this->fields)
{ {
if (pair.second != nullptr && *(pair.second->get_owner()) == *player) if (pair.second != nullptr && pair.second->get_owner() == player)
{ {
Field old_field = pair.second->get_field(); Field old_field = pair.second->get_field();
delete pair.second; delete pair.second;
this->fields.erase(pair.first); fields.erase(old_field);
FieldMeta *new_field = new FieldMeta(this, old_field, this->default_player); FieldMeta *new_field = new FieldMeta(this, old_field, PlayerManager::pm->default_player);
this->fields.insert({old_field, new_field}); this->fields.insert({old_field, new_field});
} }
} }
} }
Player &PlayerManager::get_current()
{
if (players.empty())
{
return default_player;
}
else
{
return *current_player;
}
}
void PlayerManager::next_turn()
{
current_player += 1;
if (current_player == players.end())
{
current_player = players.begin();
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, nullptr);
}
else
{
trigger_event(BOB_NEXTTURNEVENT, 0, nullptr, nullptr);
}
}
void PlayerManager::shuffle()
{
std::random_shuffle(players.begin(), players.end());
current_player = players.begin();
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, nullptr);
}
void PlayerManager::add_player(Player &player)
{
players.push_back(player);
current_player = players.begin();
}
void PlayerManager::surrender(Player &player, HexagonGrid *grid)
{
grid->free(player);
//players.erase(std::remove(players.begin(), players.end(), player), players.end());
}
bool PlayerManager::init()
{
pm = new PlayerManager();
if (pm)
{
return true;
}
else
{
return false;
}
}
bool PlayerManager::destroy()
{
if (pm != nullptr)
{
delete pm;
return true;
}
else
{
return false;
}
}

View file

@ -532,10 +532,10 @@ class FieldMeta;
class Player class Player
{ {
public: public:
Player() Player()
: name("Default Player"), uuid(boost::uuids::nil_uuid()) { } : name("Default Player"), uuid(boost::uuids::nil_uuid()) { }
Player(std::string name_) Player(std::string name_)
: name(name_), uuid(boost::uuids::basic_random_generator<boost::mt19937>()()) : name(name_), uuid(boost::uuids::basic_random_generator<boost::mt19937>()())
{ {
@ -570,9 +570,6 @@ public:
} }
void handle_event(SDL_Event *event); void handle_event(SDL_Event *event);
static Player *current_player;
private: private:
boost::uuids::uuid uuid; boost::uuids::uuid uuid;
SDL_Color color; SDL_Color color;
@ -586,7 +583,7 @@ class HexagonGrid;
class FieldMeta class FieldMeta
{ {
public: public:
FieldMeta(HexagonGrid *grid_, Field field_, Player *owner_) FieldMeta(HexagonGrid *grid_, Field field_, Player &owner_)
: grid(grid_), field(field_), owner(owner_), changed(true) : grid(grid_), field(field_), owner(owner_), changed(true)
{ {
std::default_random_engine generator; std::default_random_engine generator;
@ -631,39 +628,27 @@ public:
} }
void set_offense(int off) { this->offense = off; } void set_offense(int off) { this->offense = off; }
void set_defense(int def) { this->defense = def; } void set_defense(int def) { this->defense = def; }
Field get_field() { return this->field; } Field get_field() { return this->field; }
Player *get_owner() { return this->owner; } Player &get_owner() { return this->owner; }
void set_owner(Player *player) { this->owner = player; }
void set_owner(Player &player) { this->owner = player; }
void load(SDL_Renderer *renderer, Layout *layout); void load(SDL_Renderer *renderer, Layout *layout);
Resource get_resources() { return this->resources; } Resource get_resources() { return this->resources; }
UpgradeFlags get_upgrades() { return this->upgrades; } UpgradeFlags get_upgrades() { return this->upgrades; }
void consume_resources(Resource costs); void consume_resources(Resource costs);
void regenerate_resources(); void regenerate_resources();
bool upgrade(Upgrade upgrade); bool upgrade(Upgrade upgrade);
void handle_event(const SDL_Event *event); void handle_event(const SDL_Event *event);
FieldMeta *get_neighbor(Uint8 direction); FieldMeta *get_neighbor(Uint8 direction);
double get_reproduction() { return this->reproduction; } double get_reproduction() { return this->reproduction; }
private: private:
double reproduction; double reproduction;
bool changed; bool changed;
const Field field; const Field field;
HexagonGrid *grid; HexagonGrid *grid;
Player *owner; Player owner;
UpgradeFlags upgrades; UpgradeFlags upgrades;
Resource resources_base; // without upgrades applied, used as basis of regeneration Resource resources_base; // without upgrades applied, used as basis of regeneration
Resource resources; // actual current resources Resource resources; // actual current resources
@ -673,6 +658,42 @@ private:
typedef std::unordered_set<FieldMeta *> Cluster; typedef std::unordered_set<FieldMeta *> Cluster;
class HexagonGrid;
class PlayerManager
{
public:
PlayerManager()
{
players = std::vector<Player>();
current_player = players.begin();
default_player = Player();
}
Player &get_current();
void next_turn();
void shuffle();
void surrender(Player &player, HexagonGrid *grid);
void add_player(Player &player);
long get_num_players() { return players.size(); }
Player default_player;
static PlayerManager *pm;
static bool init();
static bool destroy();
private:
std::vector<Player> players;
std::vector<Player>::iterator current_player;
};
class HexagonGrid class HexagonGrid
{ {
public: public:
@ -683,7 +704,6 @@ public:
this->texture = nullptr; this->texture = nullptr;
this->panning = false; this->panning = false;
std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>(); std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>();
this->default_player = new Player();
// first lower half, then upper half // first lower half, then upper half
Field new_field = {0, 0, 0}; Field new_field = {0, 0, 0};
for (Sint16 x = -grid_radius; x <= grid_radius; x++) for (Sint16 x = -grid_radius; x <= grid_radius; x++)
@ -694,11 +714,11 @@ public:
{ {
Sint16 z = -x - y; Sint16 z = -x - y;
new_field = {x, y, z}; new_field = {x, y, z};
FieldMeta *meta = new FieldMeta(this, new_field, this->default_player); FieldMeta *meta = new FieldMeta(this, new_field, PlayerManager::pm->default_player);
this->fields.insert({new_field, meta}); this->fields.insert({new_field, meta});
} }
} }
this->marker = new FieldMeta(this, new_field, this->default_player); this->marker = new FieldMeta(this, new_field, PlayerManager::pm->default_player);
this->load(); this->load();
} }
@ -708,46 +728,28 @@ public:
{ {
delete elem.second; delete elem.second;
} }
delete this->default_player;
SDL_DestroyTexture(this->texture); SDL_DestroyTexture(this->texture);
} }
FieldMeta *get_neighbor(FieldMeta *field, Uint8 direction); FieldMeta *get_neighbor(FieldMeta *field, Uint8 direction);
Cluster get_cluster(FieldMeta *field); Cluster get_cluster(FieldMeta *field);
void render(Renderer *renderer); void render(Renderer *renderer);
void load(); void load();
Sint16 get_radius() { return radius * layout->size; } Sint16 get_radius() { return radius * layout->size; }
void move(SDL_Point move); void move(SDL_Point move);
void update_marker(); void update_marker();
void update_dimensions(SDL_Point dimensions); void update_dimensions(SDL_Point dimensions);
Resource get_resources_of_cluster(Cluster *cluster); Resource get_resources_of_cluster(Cluster *cluster);
Resource consume_resources_of_cluster(Cluster *cluster, Resource costs); Resource consume_resources_of_cluster(Cluster *cluster, Resource costs);
FieldMeta *point_to_field(const Point p); FieldMeta *point_to_field(const Point p);
Point field_to_point(FieldMeta *field); Point field_to_point(FieldMeta *field);
FieldMeta *get_field(Field field); FieldMeta *get_field(Field field);
void handle_event(SDL_Event *event); void handle_event(SDL_Event *event);
bool place(Player *player, FieldMeta *center); bool place(Player &player, FieldMeta *center);
void set_selecting(bool state) { this->placing = state; } void set_selecting(bool state) { this->placing = state; }
FieldMeta *get_attack_marker() { return this->attack_marker; } FieldMeta *get_attack_marker() { return this->attack_marker; }
void surrender(Player *player); void free(Player &player);
private: private:
bool changed; bool changed;
bool placing; bool placing;
@ -758,9 +760,7 @@ private:
Layout *layout; Layout *layout;
FieldMeta *marker; FieldMeta *marker;
bool panning; bool panning;
Player *default_player;
Sint16 radius; Sint16 radius;
bool on_rectangle(SDL_Rect *rect); bool on_rectangle(SDL_Rect *rect);
}; };

View file

@ -99,7 +99,7 @@ void FieldBox::update()
Resource cluster_resources = grid->get_resources_of_cluster(&cluster); Resource cluster_resources = grid->get_resources_of_cluster(&cluster);
Resource field_resources = this->field->get_resources(); Resource field_resources = this->field->get_resources();
std::ostringstream output; std::ostringstream output;
output << this->field->get_owner()->get_name() << "\n" output << this->field->get_owner().get_name() << "\n"
<< "off " << this->field->get_offense() << "\ndef " << this->field->get_defense() << "\n" << "off " << this->field->get_offense() << "\ndef " << this->field->get_defense() << "\n"
<< "" << (int) cluster_resources.circle << " (" << (int) field_resources.circle << ")" << "\n" << "" << (int) cluster_resources.circle << " (" << (int) field_resources.circle << ")" << "\n"
<< "" << (int) cluster_resources.triangle << " (" << (int) field_resources.triangle << ")" << "\n" << "" << (int) cluster_resources.triangle << " (" << (int) field_resources.triangle << ")" << "\n"
@ -210,7 +210,7 @@ void UpgradeButtonBox::handle_event(const SDL_Event *event)
if (inside_target(&(this->dimensions), &pos)) if (inside_target(&(this->dimensions), &pos))
{ {
FieldMeta *field = this->box->get_field(); FieldMeta *field = this->box->get_field();
if (*(Player::current_player) == *(field->get_owner())) if (PlayerManager::pm->get_current() == field->get_owner())
{ {
field->upgrade(this->upgrade); field->upgrade(this->upgrade);
changed = true; changed = true;
@ -301,34 +301,6 @@ void FieldBox::update_position(SDL_Point point)
this->dimensions.y = point.y - this->dimensions.h - 6; this->dimensions.y = point.y - this->dimensions.h - 6;
} }
void NextTurnButtonBox::handle_event(const SDL_Event *event)
{
if (event->type == SDL_MOUSEBUTTONDOWN)
{
SDL_Point mouse;
SDL_GetMouseState(&(mouse.x), &(mouse.y));
if (inside_target(&(this->dimensions), &mouse))
{
Player *last_player = Player::current_player;
this->current_player = this->current_player + 1;
if (this->current_player == players->end())
{
this->current_player = players->begin();
trigger_event(BOB_NEXTROUNDEVENT, 0, last_player, Player::current_player);
}
else
{
trigger_event(BOB_NEXTTURNEVENT, 0, last_player, Player::current_player);
}
Player::current_player = *(this->current_player);
std::ostringstream text;
text << "NEXT TURN" << "\n\n" << Player::current_player->get_name();
this->load_text(text.str());
this->changed = true;
}
}
}
void TextInputBox::start() void TextInputBox::start()
{ {
this->visible = true; this->visible = true;
@ -397,7 +369,7 @@ void TextInputBox::handle_event(const SDL_Event *event)
void TextInputBox::prompt(std::string message) void TextInputBox::prompt(std::string message)
{ {
this->output << this->input.str() << "\n" << message << "\n" << Player::current_player->get_name() << "# "; this->output << this->input.str() << "\n" << message << "\n" << PlayerManager::pm->get_current().get_name() << "# ";
this->lines += 2; this->lines += 2;
this->load_text(output.str()); this->load_text(output.str());
if (lines > 20) if (lines > 20)

View file

@ -82,7 +82,7 @@ public:
: TextBox(renderer_, dimensions_, color_, font_), input("") : TextBox(renderer_, dimensions_, color_, font_), input("")
{ {
this->visible = false; this->visible = false;
this->output << Player::current_player->get_name() << "# "; this->output << PlayerManager::pm->get_current().get_name() << "# ";
this->load(); this->load();
this->load_text(output.str()); this->load_text(output.str());
} }
@ -145,29 +145,6 @@ private:
bool active; // this upgrade has been unlocked bool active; // this upgrade has been unlocked
}; };
class NextTurnButtonBox : public TextBox
{
public:
NextTurnButtonBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_,
std::vector<Player *> *players_)
: TextBox(renderer, dimensions, color, font_), players(players_)
{
this->current_player = this->players->begin();
Player::current_player = *(this->current_player);
std::ostringstream text;
// Warning, next line looks ugly @.@
text << "NEXT TURN" << "\n\n" << (*(this->current_player))->get_name();
this->load_text(text.str());
this->visible = true;
}
void handle_event(const SDL_Event *event);
private:
std::vector<Player *> *players;
std::vector<Player *>::iterator current_player;
};
class UpgradeBox : public Box class UpgradeBox : public Box
{ {
public: public: