Added conquering and resource spending.
This commit is contained in:
parent
62cba726a8
commit
4f95ed3fc0
4 changed files with 155 additions and 30 deletions
113
src/Gameplay.cpp
113
src/Gameplay.cpp
|
@ -9,11 +9,6 @@ Player *FieldMeta::get_owner()
|
||||||
return this->owner;
|
return this->owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldMeta::set_owner(Player *player)
|
|
||||||
{
|
|
||||||
this->owner = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
Field FieldMeta::get_field() { return this->field; }
|
Field FieldMeta::get_field() { return this->field; }
|
||||||
|
|
||||||
void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
|
void FieldMeta::render(SDL_Renderer *renderer, Layout *layout)
|
||||||
|
@ -31,7 +26,9 @@ void FieldMeta::render(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;
|
||||||
}
|
}
|
||||||
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x22);
|
if ((*this->owner) == Player::default_player)
|
||||||
|
color = {0x77, 0x77, 0x77, 0x77};
|
||||||
|
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x33);
|
||||||
SDL_Color inverse;
|
SDL_Color inverse;
|
||||||
inverse.r = (Uint8) (0xff - color.r);
|
inverse.r = (Uint8) (0xff - color.r);
|
||||||
inverse.g = (Uint8) (0xff - color.g);
|
inverse.g = (Uint8) (0xff - color.g);
|
||||||
|
@ -95,20 +92,23 @@ Resource FieldMeta::get_resources()
|
||||||
return this->resources;
|
return this->resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource FieldMeta::get_resources_of_cluster()
|
Resource FieldMeta::get_resources_of_cluster(Cluster cluster)
|
||||||
{
|
{
|
||||||
Resource res = {0, 0, 0};
|
Resource res = {0, 0, 0};
|
||||||
std::unordered_set<FieldMeta *> *cluster = new std::unordered_set<FieldMeta *>();
|
for (FieldMeta *elem : cluster)
|
||||||
this->get_cluster(cluster);
|
|
||||||
for (FieldMeta *elem : *cluster)
|
|
||||||
{
|
{
|
||||||
Resource r_plus = elem->get_resources();
|
Resource r_plus = elem->get_resources();
|
||||||
res += r_plus;
|
res += r_plus;
|
||||||
}
|
}
|
||||||
delete cluster;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Resource FieldMeta::get_resources_of_cluster()
|
||||||
|
{
|
||||||
|
Cluster cluster = this->get_cluster();
|
||||||
|
return this->get_resources_of_cluster(cluster);
|
||||||
|
}
|
||||||
|
|
||||||
Uint32 FieldMeta::get_upgrades() { return this->upgrades; }
|
Uint32 FieldMeta::get_upgrades() { return this->upgrades; }
|
||||||
|
|
||||||
bool FieldMeta::upgrade(Upgrade upgrade)
|
bool FieldMeta::upgrade(Upgrade upgrade)
|
||||||
|
@ -132,22 +132,22 @@ bool FieldMeta::upgrade(Upgrade upgrade)
|
||||||
std::cout << "Unknown update: " << upgrade;
|
std::cout << "Unknown update: " << upgrade;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cluster_resources > costs)
|
Resource remaining_costs = this->consume_resources_of_cluster(costs);
|
||||||
|
Resource neutral = {0, 0, 0};
|
||||||
|
if (remaining_costs == neutral)
|
||||||
{
|
{
|
||||||
this->resources -= costs;
|
|
||||||
this->upgrades |= upgrade;
|
this->upgrades |= upgrade;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_set<FieldMeta *> *FieldMeta::get_cluster(std::unordered_set<FieldMeta *> *visited)
|
Cluster FieldMeta::get_cluster(Cluster visited)
|
||||||
{
|
{
|
||||||
assert(visited != nullptr);
|
if (visited.find(this) != visited.end()) // already been here before
|
||||||
|
|
||||||
if (visited->find(this) != visited->end()) // already been here before
|
|
||||||
return visited;
|
return visited;
|
||||||
|
|
||||||
visited->insert(this);
|
visited.insert(this);
|
||||||
|
|
||||||
for (Uint8 i = 0; i < 6; i++)
|
for (Uint8 i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
|
@ -160,3 +160,80 @@ std::unordered_set<FieldMeta *> *FieldMeta::get_cluster(std::unordered_set<Field
|
||||||
}
|
}
|
||||||
return visited;
|
return visited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Resource FieldMeta::consume_resources_of_cluster(Resource costs)
|
||||||
|
{
|
||||||
|
Cluster cluster = this->get_cluster();
|
||||||
|
Resource cluster_resources = this->get_resources_of_cluster(cluster);
|
||||||
|
for (FieldMeta *meta : cluster)
|
||||||
|
{
|
||||||
|
// mind the "special" definition of -=, only byte of what you can chew or leave nothing behind
|
||||||
|
Resource tmp = costs;
|
||||||
|
costs -= meta->resources;
|
||||||
|
meta->resources -= tmp;
|
||||||
|
}
|
||||||
|
return costs; // > {0, 0, 0} means there were not enough resources
|
||||||
|
}
|
||||||
|
|
||||||
|
void FieldMeta::set_owner(Player *player)
|
||||||
|
{
|
||||||
|
this->owner = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldMeta *FieldMeta::get_meta(Field field)
|
||||||
|
{
|
||||||
|
auto pair = fields.find(field);
|
||||||
|
if (pair != fields.end())
|
||||||
|
{
|
||||||
|
return pair->second;
|
||||||
|
}
|
||||||
|
return nullptr; // no meta-information (there is no field on the map at this location)
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Player::fight(Field field)
|
||||||
|
{
|
||||||
|
FieldMeta *meta = FieldMeta::get_meta(field);
|
||||||
|
if (meta == nullptr || *this == *(meta->get_owner())) // attacked field outside of the map or friendly fire
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (*(meta->get_owner()) == this->default_player) // still to be had
|
||||||
|
{
|
||||||
|
meta->set_owner(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// defending player's defense against attacking player's offense
|
||||||
|
int power_level = meta->get_defense(); // it's over 9000
|
||||||
|
Field center = meta->get_field();
|
||||||
|
for (Uint8 i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
Field neighbor = hex_neighbor(i, center);
|
||||||
|
FieldMeta *neighbor_meta = FieldMeta::get_meta(neighbor);
|
||||||
|
if (neighbor_meta == nullptr) // there is no neighbor in this direction
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*(neighbor_meta->get_owner()) == *this) // comparison by UUID
|
||||||
|
power_level -= neighbor_meta->get_offense();
|
||||||
|
else if (*(neighbor_meta->get_owner()) == *(meta->get_owner()))
|
||||||
|
power_level += neighbor_meta->get_defense();
|
||||||
|
// else ignore, field / player not part of the fight (e.g. default player)
|
||||||
|
}
|
||||||
|
if (power_level < 0) // attacking player has won
|
||||||
|
{
|
||||||
|
meta->set_owner(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FieldMeta::get_offense()
|
||||||
|
{
|
||||||
|
return this->offense;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FieldMeta::get_defense()
|
||||||
|
{
|
||||||
|
return this->defense;
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <SDL2/SDL_render.h>
|
#include <SDL2/SDL_render.h>
|
||||||
#include "Grid.hpp"
|
#include "Grid.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef Upgrade
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
UPGRADE_FIRST_UPGRADE = 0,
|
UPGRADE_FIRST_UPGRADE = 0,
|
||||||
|
@ -17,6 +19,7 @@ typedef enum
|
||||||
UPGRADE_REGENERATION_3,
|
UPGRADE_REGENERATION_3,
|
||||||
UPGRADE_REPRODUCTION
|
UPGRADE_REPRODUCTION
|
||||||
} Upgrade;
|
} Upgrade;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef Tagged
|
#ifndef Tagged
|
||||||
|
|
||||||
|
@ -96,6 +99,8 @@ public:
|
||||||
return descriptor.str();
|
return descriptor.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fight(Field field);
|
||||||
|
|
||||||
static Player default_player;
|
static Player default_player;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,9 +130,21 @@ struct Resource
|
||||||
|
|
||||||
Resource &operator-=(const Resource &rhs)
|
Resource &operator-=(const Resource &rhs)
|
||||||
{
|
{
|
||||||
this->circle -= rhs.circle;
|
if (this->circle < rhs.circle)
|
||||||
this->triangle -= rhs.triangle;
|
this->circle = 0;
|
||||||
this->square -= rhs.square;
|
else
|
||||||
|
this->circle -= rhs.circle;
|
||||||
|
|
||||||
|
if (this->triangle < rhs.triangle)
|
||||||
|
this->triangle = 0;
|
||||||
|
else
|
||||||
|
this->triangle -= rhs.triangle;
|
||||||
|
|
||||||
|
if (this->square < rhs.square)
|
||||||
|
this->square = 0;
|
||||||
|
else
|
||||||
|
this->square -= rhs.square;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +197,18 @@ struct Resource
|
||||||
inline bool operator<=(const Resource &rhs) const { return !(*this > rhs); }
|
inline bool operator<=(const Resource &rhs) const { return !(*this > rhs); }
|
||||||
|
|
||||||
inline bool operator>=(const Resource &rhs) const { return !(*this < rhs); }
|
inline bool operator>=(const Resource &rhs) const { return !(*this < rhs); }
|
||||||
|
|
||||||
|
bool operator==(const Resource &rhs) const
|
||||||
|
{
|
||||||
|
return (this->circle == rhs.circle && this->triangle == rhs.triangle && this->square == rhs.square);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const Resource &rhs) const { return !(*this == rhs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef FieldMeta
|
#ifndef FieldMeta
|
||||||
|
|
||||||
class FieldMeta
|
class FieldMeta
|
||||||
|
@ -201,21 +226,34 @@ public:
|
||||||
this->resources_base.square = distro(rng);
|
this->resources_base.square = distro(rng);
|
||||||
std::pair<Field, FieldMeta *> pair(field, this);
|
std::pair<Field, FieldMeta *> pair(field, this);
|
||||||
this->fields.insert(pair);
|
this->fields.insert(pair);
|
||||||
|
this->offense = 1;
|
||||||
|
this->defense = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_offense();
|
||||||
|
|
||||||
|
int get_defense();
|
||||||
|
|
||||||
|
static FieldMeta *get_meta(Field field);
|
||||||
|
|
||||||
Field get_field();
|
Field get_field();
|
||||||
|
|
||||||
Player *get_owner();
|
Player *get_owner();
|
||||||
|
|
||||||
void set_owner(Player *player);
|
void set_owner(Player *player);
|
||||||
|
|
||||||
|
//void set_owner(Player *player);
|
||||||
|
|
||||||
void render(SDL_Renderer *renderer, Layout *layout);
|
void render(SDL_Renderer *renderer, Layout *layout);
|
||||||
|
|
||||||
Resource get_resources();
|
Resource get_resources();
|
||||||
|
|
||||||
Resource get_resources_of_cluster();
|
Resource get_resources_of_cluster();
|
||||||
|
|
||||||
std::unordered_set<FieldMeta *> *get_cluster(std::unordered_set<FieldMeta *> *visited);
|
Resource get_resources_of_cluster(std::unordered_set<FieldMeta *> cluster);
|
||||||
|
|
||||||
|
std::unordered_set<FieldMeta *> get_cluster(
|
||||||
|
std::unordered_set<FieldMeta *> visited = std::unordered_set<FieldMeta *>());
|
||||||
|
|
||||||
Uint32 get_upgrades();
|
Uint32 get_upgrades();
|
||||||
|
|
||||||
|
@ -223,6 +261,8 @@ public:
|
||||||
|
|
||||||
bool upgrade(Upgrade upgrade);
|
bool upgrade(Upgrade upgrade);
|
||||||
|
|
||||||
|
Resource consume_resources_of_cluster(Resource costs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Field field;
|
const Field field;
|
||||||
static std::unordered_map<Field, FieldMeta *> fields;
|
static std::unordered_map<Field, FieldMeta *> fields;
|
||||||
|
@ -230,6 +270,13 @@ private:
|
||||||
Uint32 upgrades;
|
Uint32 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
|
||||||
|
int offense;
|
||||||
|
int defense;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Cluster
|
||||||
|
typedef std::unordered_set<FieldMeta *> Cluster;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
10
src/Main.cpp
10
src/Main.cpp
|
@ -58,7 +58,7 @@ void Game::toggle_fullscreen()
|
||||||
this->full_screen = true;
|
this->full_screen = true;
|
||||||
SDL_SetWindowSize(this->window, dm.w, dm.h);
|
SDL_SetWindowSize(this->window, dm.w, dm.h);
|
||||||
SDL_SetWindowFullscreen(this->window, SDL_WINDOW_FULLSCREEN);
|
SDL_SetWindowFullscreen(this->window, SDL_WINDOW_FULLSCREEN);
|
||||||
this->grid->update_box(dm.w, dm.h);
|
this->grid->update_box(dm.w - SIDEBOX_WIDTH, dm.h);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ int Game::game_loop()
|
||||||
if (move_timer->get_timer() > 10)
|
if (move_timer->get_timer() > 10)
|
||||||
{
|
{
|
||||||
move_timer->reset_timer();
|
move_timer->reset_timer();
|
||||||
SDL_Point move_by = {(this->move[1] - this->move[3]) * 10, (this->move[0] - this->move[2]) * 10};
|
SDL_Point move_by = {(this->move[1] - this->move[3]) * 20, (this->move[0] - this->move[2]) * 20};
|
||||||
this->grid->move(move_by);
|
this->grid->move(move_by);
|
||||||
}
|
}
|
||||||
if (frame_timer->get_timer() > 1000.0)
|
if (frame_timer->get_timer() > 1000.0)
|
||||||
|
@ -155,7 +155,7 @@ int Game::game_loop()
|
||||||
{
|
{
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEWHEEL)
|
if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEWHEEL || event.type == SDL_MOUSEBUTTONDOWN)
|
||||||
{
|
{
|
||||||
grid->handle_event(&event);
|
grid->handle_event(&event);
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,8 @@ int main(int, char **)
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Layout *layout = new Layout(pointy_orientation, GRID_SIZE, {5 * SCREEN_WIDTH / 12, 5 * SCREEN_HEIGTH / 12},
|
Layout *layout = new Layout(pointy_orientation, 20, {SCREEN_WIDTH / 2, SCREEN_HEIGTH / 2},
|
||||||
{0, 0, 5 * SCREEN_WIDTH / 6, 5 * SCREEN_HEIGTH / 6});
|
{0, 0, SCREEN_WIDTH - SIDEBOX_WIDTH, SCREEN_HEIGTH});
|
||||||
Game *game = new Game(window, renderer, layout);
|
Game *game = new Game(window, renderer, layout);
|
||||||
int exit_status = game->game_loop();
|
int exit_status = game->game_loop();
|
||||||
delete game;
|
delete game;
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
const Sint16 GRID_SIZE = 4;
|
const Sint16 GRID_SIZE = 4;
|
||||||
const int SCREEN_WIDTH = 800;
|
const int SCREEN_WIDTH = 800;
|
||||||
const int SCREEN_HEIGTH = 600;
|
const int SCREEN_HEIGTH = 600;
|
||||||
char TITLE[] = "Bob - Battles of Bacteria";
|
const int SIDEBOX_WIDTH = 200;
|
||||||
|
const char TITLE[] = "Bob - Battles of Bacteria";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
|
@ -49,7 +50,7 @@ private:
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
HexagonGrid *grid;
|
HexagonGrid *grid;
|
||||||
// only deal with meta information
|
// only deal with meta information
|
||||||
std::unordered_set<FieldMeta *> fields_meta;
|
Cluster fields_meta;
|
||||||
Layout *layout;
|
Layout *layout;
|
||||||
bool move[4];
|
bool move[4];
|
||||||
bool full_screen;
|
bool full_screen;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue