#ifndef _WORLD_HPP #define _WORLD_HPP #include "generic.pb.h" #include "Connection.hpp" #include #include #include namespace World { void fillSettings(Generic::Settings& settings); struct Vector2 { float x, y; inline static Vector2 makeFromGeneric(const Generic::Vector2& generic) { return {generic.x(), generic.y()}; } void fromGeneric(const Generic::Vector2& generic) { x = generic.x(); y = generic.y(); } auto toGeneric() const { Generic::Vector2 fres; fres.set_x(x); fres.set_y(y); return fres; } float getDistanceTo(const Vector2& o) const { return fabs(x - o.x) + fabs(y - o.y); } }; struct LocalRobot { Generic::Robot generic; uint64_t stateTimer = 0; auto& operator *() { return generic; } auto operator ->() { return &generic; } const auto& operator *() const { return generic; } const auto operator ->() const { return &generic; } }; class Playfield { std::vector robots; Generic::Settings settings; uint64_t turn = 0; public: std::vector> clients; Playfield(const std::vector>& clients, const Generic::Settings& settings) : clients(clients), settings(settings) { fillSettings(this->settings); } boost::asio::awaitable reset(); boost::asio::awaitable updateRobot(const Connection::Client *sender, Generic::Robot& newRobot); LocalRobot& getLocalRobot(const Connection::Client *sender, unsigned robot); float getDistanceBetween(const Generic::Robot& a, const Generic::Robot& b) { return Vector2::makeFromGeneric(a.position()).getDistanceTo(Vector2::makeFromGeneric(b.position())); } auto getPlayfieldSync() const { Generic::PlayfieldSync fres; for (const auto& robot : robots) { *fres.add_robots() = robot.generic; } return fres; } bool isMasterClient(const Connection::Client *client) const { return client == clients.front().get(); } const auto& getSettings() const { return settings; } auto getTurn() const { return turn; } }; } #endif