Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server/inc/action/AttackAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
#include "Common.h"
#include "GemPile.h"
#include "Bomb.h"

#include "Deposit.h"

#include "Board.h"
#include "Stats.h"

class Unit;

Expand Down
16 changes: 10 additions & 6 deletions server/inc/game/ReplayEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ using json = nlohmann::ordered_json;
#include "Logger.h"
#include "Config.h"
#include "Action.h"
#include "Stats.h"
#include "Core.h"

#include <fstream>
#include <unordered_map>
#include <filesystem>
#include <cstdlib>

enum class death_reason_t {
enum class death_reason_t
{
NONE_SURVIVED,
CORE_DESTROYED,
DISCONNECTED,
Expand All @@ -24,33 +27,34 @@ enum class death_reason_t {
TIMEOUT_RANDOM
};

typedef struct team_data_s {
typedef struct team_data_s
{
unsigned int teamId;
std::string teamName;
bool connectedInitially = false;
death_reason_t deathReason = death_reason_t::DID_NOT_CONNECT;
unsigned int place = std::numeric_limits<unsigned int>::max(); // 0 = won
} team_data_t;
} team_data_t;

class ReplayEncoder
{
public:
ReplayEncoder() : ticks_(json::object()), lastTickCount_(0) {}
~ReplayEncoder() = default;

static ReplayEncoder& instance();
static ReplayEncoder &instance();

void addTickState(json &state, unsigned long long tick, std::vector<std::pair<std::unique_ptr<Action>, Core *>> &actions);

void registerExpectedTeam(unsigned int teamId);
void setTeamName(unsigned int teamId, const std::string& teamName);
void setTeamName(unsigned int teamId, const std::string &teamName);
void markConnectedInitially(unsigned int teamId, bool connected);
void setDeathReason(unsigned int teamId, death_reason_t reason);
void setPlace(unsigned int teamId, unsigned int place);

bool wasConnectedInitially(unsigned int teamId) const;

void includeConfig(json& config);
void includeConfig(json &config);
json &getCustomData(void) { return customData_; }

void exportReplay() const;
Expand Down
51 changes: 51 additions & 0 deletions server/inc/game/Stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef STATS_H
#define STATS_H

#include <unordered_map>
#include <string>
#include <string_view>
#include "json.hpp"
using json = nlohmann::ordered_json;

namespace stat_keys
{
inline constexpr std::string_view damage_total = "damage_total";
inline constexpr std::string_view damage_self = "damage_self";
inline constexpr std::string_view damage_opponent = "damage_opponent";

inline constexpr std::string_view damage_units = "damage_units";
inline constexpr std::string_view damage_cores = "damage_cores";
inline constexpr std::string_view damage_walls = "damage_walls";
inline constexpr std::string_view damage_deposits = "damage_deposits";

inline constexpr std::string_view units_spawned = "units_spawned";
inline constexpr std::string_view walls_spawned = "walls_spawned";
inline constexpr std::string_view bombs_spawned = "bombs_spawned";

inline constexpr std::string_view units_destroyed = "units_destroyed";
inline constexpr std::string_view cores_destroyed = "cores_destroyed";
inline constexpr std::string_view deposits_destroyed = "deposits_destroyed";
inline constexpr std::string_view gempiles_destroyed = "gempiles_destroyed"; // picked up
inline constexpr std::string_view walls_destroyed = "walls_destroyed";
inline constexpr std::string_view bombs_destroyed = "bombs_destroyed"; // explosions

inline constexpr std::string_view gems_transferred = "gems_transferred";
inline constexpr std::string_view tiles_traveled = "tiles_traveled";

inline constexpr std::string_view gems_gained = "gems_gained";

inline constexpr std::string_view actions_executed = "actions_executed";
}

class Stats
{
public:
static Stats &instance();
void inc(std::string_view key, uint64_t by = 1);
json toJson() const;

private:
std::unordered_map<std::string, uint64_t> counters_;
};

#endif // STATS_H
19 changes: 10 additions & 9 deletions server/inc/object/Bomb.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
#include "Common.h"
#include "Config.h"
#include "Board.h"
#include "Stats.h"

class Bomb : public Object
{
public:
Bomb();
Bomb(const Bomb &other)
: Object(other), countdown_(other.countdown_) {}
public:
Bomb();
Bomb(const Bomb &other)
: Object(other), countdown_(other.countdown_) {}

void explode();
void tick(unsigned long long tickCount);
void explode();
void tick(unsigned long long tickCount);

unsigned int getCountdown() const { return countdown_; }
unsigned int getCountdown() const { return countdown_; }

private:
unsigned int countdown_ = 0; // Countdown for the bomb to explode
private:
unsigned int countdown_ = 0; // Countdown for the bomb to explode
};

#endif // BOMB_H
51 changes: 41 additions & 10 deletions server/src/action/AttackAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,50 @@ std::string AttackAction::execute(Core *core)
unit->resetActionCooldown();

// calculate attack damage depending on object type
unsigned int damage = 1;
if (obj->getType() == ObjectType::Unit)
{
obj->setHP(obj->getHP() - Config::game().units[unit->getUnitType()].damageUnit);
damage = Config::game().units[unit->getUnitType()].damageUnit;
obj->setHP(obj->getHP() - damage);

Stats::instance().inc(stat_keys::damage_units, damage);
if (((Unit *)obj)->getTeamId() != unit->getTeamId())
Stats::instance().inc(stat_keys::damage_opponent, damage);
else
Stats::instance().inc(stat_keys::damage_self, damage);
}
else if (obj->getType() == ObjectType::Core)
{
obj->setHP(obj->getHP() - Config::game().units[unit->getUnitType()].damageCore);
damage = Config::game().units[unit->getUnitType()].damageCore;
obj->setHP(obj->getHP() - damage);

Stats::instance().inc(stat_keys::damage_cores, damage);
if (((Core *)obj)->getTeamId() != unit->getTeamId())
Stats::instance().inc(stat_keys::damage_opponent, damage);
else
Stats::instance().inc(stat_keys::damage_self, damage);
}
else if (obj->getType() == ObjectType::Deposit)
{
obj->setHP(obj->getHP() - Config::game().units[unit->getUnitType()].damageDeposit);
if (obj->getHP() > 0)
return "";
unsigned int gems = ((Deposit *)obj)->getBalance();
Board::instance().removeObjectById(obj->getId());
Board::instance().addObject<GemPile>(GemPile(gems), target_pos_);
damage = Config::game().units[unit->getUnitType()].damageDeposit;
obj->setHP(obj->getHP() - damage);
if (obj->getHP() <= 0)
{
unsigned int gems = ((Deposit *)obj)->getBalance();
Board::instance().removeObjectById(obj->getId());
Board::instance().addObject<GemPile>(GemPile(gems), target_pos_);

Stats::instance().inc(stat_keys::deposits_destroyed, 1);
}

Stats::instance().inc(stat_keys::damage_deposits, damage);
Comment thread
FreddyMSchubert marked this conversation as resolved.
}
else if (obj->getType() == ObjectType::Wall)
{
obj->setHP(obj->getHP() - Config::game().units[unit->getUnitType()].damageWall);
damage = Config::game().units[unit->getUnitType()].damageWall;
obj->setHP(obj->getHP() - damage);

Stats::instance().inc(stat_keys::damage_walls, damage);
}
else if (obj->getType() == ObjectType::Bomb)
{
Expand All @@ -89,9 +113,16 @@ std::string AttackAction::execute(Core *core)
}
else if (obj->getType() == ObjectType::GemPile)
{
unit->setBalance(unit->getBalance() + static_cast<GemPile *>(obj)->getBalance());
unsigned int gems = static_cast<GemPile *>(obj)->getBalance();
unit->setBalance(unit->getBalance() + gems);
Board::instance().removeObjectById(obj->getId());

Stats::instance().inc(stat_keys::gems_gained, gems);
Stats::instance().inc(stat_keys::gempiles_destroyed, 1);
}

Stats::instance().inc(stat_keys::actions_executed);
Stats::instance().inc(stat_keys::damage_total, damage);

return "";
}
6 changes: 6 additions & 0 deletions server/src/action/BuildAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ std::string BuildAction::execute(Core *core)
builder->resetActionCooldown();
builder->setBalance(builder->getBalance() - Config::game().wallBuildCost);
Board::instance().addObject<Wall>(Wall(), position_);

Stats::instance().inc(stat_keys::walls_spawned);
}
else if (buildType == BuildType::BOMB)
{
Expand All @@ -73,7 +75,11 @@ std::string BuildAction::execute(Core *core)
builder->resetActionCooldown();
builder->setBalance(builder->getBalance() - Config::game().bombThrowCost);
Board::instance().addObject<Bomb>(Bomb(), position_);

Stats::instance().inc(stat_keys::bombs_spawned);
}

Stats::instance().inc(stat_keys::actions_executed);

return "";
}
3 changes: 3 additions & 0 deletions server/src/action/CreateAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,8 @@ std::string CreateAction::execute(Core *core)
Board::instance().addObject<Unit>(Unit(core->getTeamId(), unit_type_), closestEmptyPos);
core->setBalance(core->getBalance() - unitCost);

Stats::instance().inc(stat_keys::units_spawned);
Stats::instance().inc(stat_keys::actions_executed);

return "";
}
3 changes: 3 additions & 0 deletions server/src/action/MoveAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@ std::string MoveAction::execute(Core *core)
Board::instance().moveObjectById(unit->getId(), target_);
unit->resetActionCooldown();

Stats::instance().inc(stat_keys::tiles_traveled);
Stats::instance().inc(stat_keys::actions_executed);

return "";
}
6 changes: 6 additions & 0 deletions server/src/action/TransferGemsAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ std::string TransferGemsAction::dropMoney(Core *core, Object *srcObj)

Board::instance().addObject<GemPile>(GemPile(amount_), target_);

Stats::instance().inc(stat_keys::actions_executed);
Stats::instance().inc(stat_keys::gems_transferred, amount_);

return "";
}

Expand Down Expand Up @@ -130,5 +133,8 @@ std::string TransferGemsAction::execute(Core *core)
dstUnit->setBalance(dstUnit->getBalance() + amount_);
}

Stats::instance().inc(stat_keys::actions_executed);
Stats::instance().inc(stat_keys::gems_transferred, amount_);

return "";
}
Loading