Add reproduction on every turn.
This commit is contained in:
parent
439d2ce868
commit
7ada34cc1b
4 changed files with 103 additions and 49 deletions
33
src/Bob.cpp
33
src/Bob.cpp
|
@ -152,7 +152,7 @@ void Game::handle_event(SDL_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_FIELDUPGRADEVENT || event->type == BOB_NEXTTURNEVENT)
|
||||||
{
|
{
|
||||||
this->grid->handle_event(event);
|
this->grid->handle_event(event);
|
||||||
this->field_box->handle_event(event);
|
this->field_box->handle_event(event);
|
||||||
|
@ -162,18 +162,22 @@ void Game::handle_event(SDL_Event *event)
|
||||||
p->handle_event(event);
|
p->handle_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event->type == BOB_PLAYERADDED && !this->started)
|
else if (event->type == BOB_FIELDSELECTEDEVENT && !this->started)
|
||||||
{
|
{
|
||||||
Player *added = (Player *) event->user.data1;
|
FieldMeta *field = (FieldMeta *) event->user.data1;
|
||||||
if (event->user.code == 0)
|
if (event->user.code == 0 && this->adding != nullptr)
|
||||||
{
|
{
|
||||||
this->players.push_back(added);
|
if (this->grid->place(this->adding, field))
|
||||||
prompt << "Added Player: " << added->get_name();
|
{
|
||||||
|
this->players.push_back(this->adding);
|
||||||
|
prompt << "Added Player: " << this->adding->get_name();
|
||||||
|
this->adding = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prompt << "Failed to add Player: " << added->get_name();
|
prompt << "Failed to add Player: " << this->adding->get_name();
|
||||||
delete added;
|
delete this->adding;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->text_input_box->prompt(prompt.str());
|
this->text_input_box->prompt(prompt.str());
|
||||||
}
|
}
|
||||||
|
@ -206,6 +210,7 @@ void Game::command(std::string input)
|
||||||
Player::current_player = players[turn];
|
Player::current_player = players[turn];
|
||||||
if (this->turn == 0)
|
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);
|
trigger_event(BOB_NEXTROUNDEVENT, 0, (void *) last_player, (void *) Player::current_player);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -227,9 +232,15 @@ void Game::command(std::string input)
|
||||||
{
|
{
|
||||||
if (!this->started)
|
if (!this->started)
|
||||||
{
|
{
|
||||||
Player *added = new Player(input.substr(11, std::string::npos));
|
if (this->adding != nullptr)
|
||||||
this->grid->set_selecting(true, added);
|
{
|
||||||
prompt << "Select a place, please!";
|
this->grid->set_selecting(false);
|
||||||
|
prompt << "Failed to add player " << this->adding->get_name() << "!df\n";
|
||||||
|
delete this->adding;
|
||||||
|
}
|
||||||
|
this->grid->set_selecting(true);
|
||||||
|
this->adding = new Player(input.substr(11, std::string::npos));
|
||||||
|
prompt << "Select a place for " << this->adding->get_name() << ", please!";
|
||||||
this->text_input_box->stop();
|
this->text_input_box->stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
12
src/Bob.hpp
12
src/Bob.hpp
|
@ -20,6 +20,7 @@ class Game
|
||||||
public:
|
public:
|
||||||
Game(SDL_Rect *window_dimensions, Sint16 size)
|
Game(SDL_Rect *window_dimensions, Sint16 size)
|
||||||
{
|
{
|
||||||
|
this->adding = nullptr;
|
||||||
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},
|
||||||
|
@ -35,15 +36,15 @@ public:
|
||||||
this->players.push_back(default_player);
|
this->players.push_back(default_player);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 12);
|
this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20);
|
||||||
this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
|
this->window = new Window(TITLE, window_dimensions, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
|
||||||
SDL_Point window_size = this->window->get_size();
|
SDL_Point window_size = this->window->get_size();
|
||||||
this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
this->renderer = new Renderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
||||||
| SDL_RENDERER_TARGETTEXTURE);
|
| SDL_RENDERER_TARGETTEXTURE);
|
||||||
this->grid = new HexagonGrid(size, this->layout, this->renderer);
|
this->grid = new HexagonGrid(size, this->layout, this->renderer);
|
||||||
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, 100, 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, 100, 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,
|
this->next_turn_button = new NextTurnButtonBox(this->renderer,
|
||||||
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
|
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
|
||||||
this->font, &(this->players));
|
this->font, &(this->players));
|
||||||
|
@ -77,6 +78,10 @@ public:
|
||||||
delete this->renderer;
|
delete this->renderer;
|
||||||
delete this->window;
|
delete this->window;
|
||||||
delete this->layout;
|
delete this->layout;
|
||||||
|
if (this->adding != nullptr)
|
||||||
|
{
|
||||||
|
delete this->adding;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
@ -91,6 +96,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool started;
|
bool started;
|
||||||
|
Player *adding;
|
||||||
Uint64 turn;
|
Uint64 turn;
|
||||||
TextInputBox *text_input_box;
|
TextInputBox *text_input_box;
|
||||||
std::vector<Player *> players;
|
std::vector<Player *> players;
|
||||||
|
|
|
@ -257,11 +257,15 @@ Resource HexagonGrid::consume_resources_of_cluster(Cluster *cluster, Resource co
|
||||||
|
|
||||||
bool Player::fight(FieldMeta *field)
|
bool Player::fight(FieldMeta *field)
|
||||||
{
|
{
|
||||||
if (*this == *(field->get_owner())) // friendly fire
|
bool is_neighbor = false; // player has a field around here
|
||||||
|
// friendly fire or owned by default player
|
||||||
|
if (*this == *(field->get_owner()) || field->get_owner()->get_id() == boost::uuids::nil_uuid())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Cluster defenders_cluster = field->get_grid()->get_cluster(field);
|
||||||
|
Resource defenders_cluster_res = field->get_grid()->get_resources_of_cluster(&defenders_cluster);
|
||||||
|
Cluster attackers_cluster;
|
||||||
// defending player's defense against attacking player's offense
|
// defending player's defense against attacking player's offense
|
||||||
int power_level = field->get_defense(); // it's over 9000
|
int power_level = field->get_defense(); // it's over 9000
|
||||||
for (Uint8 i = 0; i < 6; i++)
|
for (Uint8 i = 0; i < 6; i++)
|
||||||
|
@ -272,19 +276,31 @@ bool Player::fight(FieldMeta *field)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*(neighbor->get_owner()) == *this) // comparison by UUID
|
if (*(neighbor->get_owner()) == *this) // comparison by UUID
|
||||||
power_level -= neighbor->get_offense();
|
|
||||||
else if (*(neighbor->get_owner()) == *(field->get_owner()))
|
|
||||||
power_level += neighbor->get_defense();
|
|
||||||
// else ignore, field / player not part of the fight (e.g. default player)
|
|
||||||
}
|
|
||||||
if (power_level < 0) // attacking player has won
|
|
||||||
{
|
{
|
||||||
|
power_level -= neighbor->get_offense();
|
||||||
|
is_neighbor = true;
|
||||||
|
}
|
||||||
|
else if (*(neighbor->get_owner()) == *(field->get_owner()))
|
||||||
|
{
|
||||||
|
Cluster temp_attackers_cluster = neighbor->get_grid()->get_cluster(neighbor);
|
||||||
|
attackers_cluster.insert(temp_attackers_cluster.begin(), temp_attackers_cluster.end());
|
||||||
|
power_level += neighbor->get_defense();
|
||||||
|
}
|
||||||
|
// else: ignore, field / player not part of the fight (e.g. default player)
|
||||||
|
}
|
||||||
|
Resource costs = {(Uint32) std::abs(power_level), (Uint32) std::abs(power_level), (Uint32) std::abs(power_level)};
|
||||||
|
if (power_level < 0 && is_neighbor) // attacking player has won
|
||||||
|
{
|
||||||
|
field->get_grid()->consume_resources_of_cluster(&attackers_cluster, costs);
|
||||||
|
field->get_grid()->consume_resources_of_cluster(&defenders_cluster, costs);
|
||||||
field->set_owner(this);
|
field->set_owner(this);
|
||||||
this->fought = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this->fought = true;
|
else // lost
|
||||||
|
{
|
||||||
|
field->get_grid()->consume_resources_of_cluster(&attackers_cluster, costs);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldMeta::handle_event(const SDL_Event *event)
|
void FieldMeta::handle_event(const SDL_Event *event)
|
||||||
|
@ -429,13 +445,13 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
if (old_size + scroll < 20)
|
if (old_size + scroll < 10)
|
||||||
{
|
{
|
||||||
this->layout->size = 20;
|
this->layout->size = 10;
|
||||||
}
|
}
|
||||||
else if (old_size + scroll > 100)
|
else if (old_size + scroll > 1000)
|
||||||
{
|
{
|
||||||
this->layout->size = 100;
|
this->layout->size = 1000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -476,14 +492,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
||||||
case SDL_BUTTON_LEFT:
|
case SDL_BUTTON_LEFT:
|
||||||
if (this->selecting)
|
if (this->selecting)
|
||||||
{
|
{
|
||||||
if (this->place(this->selecting_player, this->marker))
|
trigger_event(BOB_FIELDSELECTEDEVENT, 0, (void *) this->marker, nullptr);
|
||||||
{
|
|
||||||
trigger_event(BOB_PLAYERADDED, 0, (void *) this->selecting_player, nullptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
trigger_event(BOB_PLAYERADDED, 1, (void *) this->selecting_player, nullptr);
|
|
||||||
}
|
|
||||||
this->selecting = false;
|
this->selecting = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -520,6 +529,34 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
||||||
field.second->regenerate_resources();
|
field.second->regenerate_resources();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->type == BOB_NEXTTURNEVENT)
|
||||||
|
{
|
||||||
|
std::default_random_engine generator;
|
||||||
|
std::normal_distribution<double> distribution(0.0, 1.0);
|
||||||
|
std::unordered_set<FieldMeta *> aquired;
|
||||||
|
for (auto pair : this->fields)
|
||||||
|
{
|
||||||
|
FieldMeta *field = pair.second;
|
||||||
|
if (*(field->get_owner()) == *(Player::current_player))
|
||||||
|
{
|
||||||
|
for (Uint8 i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
FieldMeta *neighbor = field->get_neighbor(i);
|
||||||
|
if (neighbor != nullptr && neighbor->get_owner()->get_id() == boost::uuids::nil_uuid()
|
||||||
|
&& (neighbor->get_reproduction() > distribution(generator)))
|
||||||
|
{
|
||||||
|
aquired.insert(neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto foo : aquired)
|
||||||
|
{
|
||||||
|
foo->set_owner(Player::current_player);
|
||||||
|
}
|
||||||
|
this->changed = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (auto elem : this->fields)
|
for (auto elem : this->fields)
|
||||||
|
@ -652,6 +689,6 @@ void Player::handle_event(SDL_Event *event)
|
||||||
{
|
{
|
||||||
if (event->type == BOB_NEXTROUNDEVENT)
|
if (event->type == BOB_NEXTROUNDEVENT)
|
||||||
{
|
{
|
||||||
this->fought = false;
|
// nothing atm
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -342,9 +342,9 @@ inline std::ostream &operator<<(std::ostream &os, const Field &rhs)
|
||||||
|
|
||||||
struct Resource
|
struct Resource
|
||||||
{
|
{
|
||||||
Uint8 circle;
|
Uint32 circle;
|
||||||
Uint8 triangle;
|
Uint32 triangle;
|
||||||
Uint8 square;
|
Uint32 square;
|
||||||
|
|
||||||
Resource &operator+=(const Resource &rhs)
|
Resource &operator+=(const Resource &rhs)
|
||||||
{
|
{
|
||||||
|
@ -511,7 +511,7 @@ 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>()()), fought(false)
|
: name(name_), uuid(boost::uuids::basic_random_generator<boost::mt19937>()())
|
||||||
{
|
{
|
||||||
// use the last 24 bits of the tag for the color
|
// use the last 24 bits of the tag for the color
|
||||||
boost::uuids::uuid id = this->uuid;
|
boost::uuids::uuid id = this->uuid;
|
||||||
|
@ -551,7 +551,6 @@ private:
|
||||||
boost::uuids::uuid uuid;
|
boost::uuids::uuid uuid;
|
||||||
SDL_Color color;
|
SDL_Color color;
|
||||||
std::string name;
|
std::string name;
|
||||||
bool fought;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Grid;
|
class Grid;
|
||||||
|
@ -564,6 +563,9 @@ 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::normal_distribution<double> distribution(0.0, 1.0);
|
||||||
|
this->reproduction = distribution(generator);
|
||||||
this->fighting = false;
|
this->fighting = false;
|
||||||
this->upgrades = 0;
|
this->upgrades = 0;
|
||||||
static std::random_device rd;
|
static std::random_device rd;
|
||||||
|
@ -613,7 +615,10 @@ public:
|
||||||
|
|
||||||
void set_fighting(bool state) { this->fighting = state; }
|
void set_fighting(bool state) { this->fighting = state; }
|
||||||
|
|
||||||
|
double get_reproduction() { return this->reproduction; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
double reproduction;
|
||||||
bool fighting;
|
bool fighting;
|
||||||
bool changed;
|
bool changed;
|
||||||
const Field field;
|
const Field field;
|
||||||
|
@ -697,16 +702,11 @@ public:
|
||||||
|
|
||||||
bool place(Player *player, FieldMeta *center);
|
bool place(Player *player, FieldMeta *center);
|
||||||
|
|
||||||
void set_selecting(bool state, Player *player)
|
void set_selecting(bool state) { this->selecting = state; }
|
||||||
{
|
|
||||||
this->selecting = state;
|
|
||||||
this->selecting_player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool changed;
|
bool changed;
|
||||||
bool selecting;
|
bool selecting;
|
||||||
Player *selecting_player;
|
|
||||||
FieldMeta *first_attack;
|
FieldMeta *first_attack;
|
||||||
Renderer *renderer;
|
Renderer *renderer;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
|
@ -715,9 +715,9 @@ private:
|
||||||
FieldMeta *marker;
|
FieldMeta *marker;
|
||||||
bool panning;
|
bool panning;
|
||||||
Player *default_player;
|
Player *default_player;
|
||||||
|
Sint16 radius;
|
||||||
|
|
||||||
bool on_rectangle(SDL_Rect *rect);
|
bool on_rectangle(SDL_Rect *rect);
|
||||||
Sint16 radius;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool inside_target(const SDL_Rect *target, const SDL_Point *position);
|
bool inside_target(const SDL_Rect *target, const SDL_Point *position);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue