Commit 7d9a683c authored by Thomas Kolb's avatar Thomas Kolb
Browse files

Implemented more compact move message format

Now only the new head positions and mass of the snake are reported to
the client. The client has to reproduce the segment movement from this
info.
parent ea527b5d
......@@ -24,6 +24,7 @@ namespace MsgPackProtocol
MESSAGE_TYPE_BOT_MOVE = 0x22,
MESSAGE_TYPE_BOT_LOG = 0x23,
MESSAGE_TYPE_BOT_STATS = 0x24,
MESSAGE_TYPE_BOT_MOVE_HEAD = 0x25,
MESSAGE_TYPE_FOOD_SPAWN = 0x30,
MESSAGE_TYPE_FOOD_CONSUME = 0x31,
......@@ -75,6 +76,20 @@ namespace MsgPackProtocol
std::vector<BotMoveItem> items;
};
struct BotMoveHeadItem
{
guid_t bot_id;
double mass;
// one head position for each step moved in this frame, in temporal order
std::vector< Vector2D > new_head_positions;
};
struct BotMoveHeadMessage
{
std::vector<BotMoveHeadItem> items;
};
struct BotKillMessage
{
guid_t killer_id;
......@@ -219,6 +234,30 @@ namespace msgpack {
}
};
template <> struct pack<MsgPackProtocol::BotMoveHeadMessage>
{
template <typename Stream> msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, MsgPackProtocol::BotMoveHeadMessage const& v) const
{
o.pack_array(3);
o.pack(MsgPackProtocol::PROTOCOL_VERSION);
o.pack(static_cast<int>(MsgPackProtocol::MESSAGE_TYPE_BOT_MOVE_HEAD));
o.pack(v.items);
return o;
}
};
template <> struct pack<MsgPackProtocol::BotMoveHeadItem>
{
template <typename Stream> msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, MsgPackProtocol::BotMoveHeadItem const& v) const
{
o.pack_array(3);
o.pack(v.bot_id);
o.pack(v.mass);
o.pack(v.new_head_positions);
return o;
}
};
template <> struct pack<MsgPackProtocol::BotKillMessage>
{
template <typename Stream> msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, MsgPackProtocol::BotKillMessage const& v) const
......@@ -316,6 +355,18 @@ namespace msgpack {
}
};
template <> struct pack<Vector2D>
{
template <typename Stream> msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, Vector2D const& v) const
{
o.pack_array(2);
o.pack(v.x());
o.pack(v.y());
return o;
}
};
template<>
struct convert<Snake::Segment> {
msgpack::object const& operator()(msgpack::object const& o, Snake::Segment& v) const {
......
......@@ -75,6 +75,7 @@ void MsgPackUpdateTracker::botKilled(
void MsgPackUpdateTracker::botMoved(const std::shared_ptr<Bot> &bot, std::size_t steps)
{
// Fill BotMoveMessage
MsgPackProtocol::BotMoveItem item;
const Snake::SegmentList &segments = bot->getSnake()->getSegments();
......@@ -85,6 +86,15 @@ void MsgPackUpdateTracker::botMoved(const std::shared_ptr<Bot> &bot, std::size_t
item.current_length = segments.size();
m_botMoveMessage->items.push_back(item);
// Fill BotMoveHeadMessage
MsgPackProtocol::BotMoveHeadItem headItem;
headItem.bot_id = bot->getGUID();
headItem.mass = bot->getSnake()->getMass();
headItem.new_head_positions = bot->getSnake()->getHeadPositionsDuringLastMove();
m_botMoveHeadMessage->items.push_back(headItem);
}
void MsgPackUpdateTracker::botLogMessage(uint64_t viewerKey, const std::string& message)
......@@ -173,6 +183,13 @@ std::string MsgPackUpdateTracker::serialize(void)
appendMessage(buf);
}
// moved bots (compressed version)
if(!m_botMoveHeadMessage->items.empty()) {
msgpack::sbuffer buf;
msgpack::pack(buf, m_botMoveHeadMessage);
appendMessage(buf);
}
// bot statistics
if(!m_botStatsMessage->items.empty()) {
msgpack::sbuffer buf;
......@@ -198,6 +215,7 @@ void MsgPackUpdateTracker::reset(void)
m_foodSpawnMessage = std::make_unique<MsgPackProtocol::FoodSpawnMessage>();
m_foodDecayMessage = std::make_unique<MsgPackProtocol::FoodDecayMessage>();
m_botMoveMessage = std::make_unique<MsgPackProtocol::BotMoveMessage>();
m_botMoveHeadMessage = std::make_unique<MsgPackProtocol::BotMoveHeadMessage>();
m_botStatsMessage = std::make_unique<MsgPackProtocol::BotStatsMessage>();
m_botLogMessage = std::make_unique<MsgPackProtocol::BotLogMessage>();
......
......@@ -21,6 +21,7 @@ class MsgPackUpdateTracker : public UpdateTracker
std::unique_ptr<MsgPackProtocol::FoodSpawnMessage> m_foodSpawnMessage;
std::unique_ptr<MsgPackProtocol::FoodDecayMessage> m_foodDecayMessage;
std::unique_ptr<MsgPackProtocol::BotMoveMessage> m_botMoveMessage;
std::unique_ptr<MsgPackProtocol::BotMoveHeadMessage> m_botMoveHeadMessage;
std::unique_ptr<MsgPackProtocol::BotStatsMessage> m_botStatsMessage;
std::unique_ptr<MsgPackProtocol::BotLogMessage> m_botLogMessage;
......
......@@ -106,6 +106,8 @@ std::size_t Snake::move(real_t targetAngle, bool boost)
steps = config::SNAKE_BOOST_STEPS;
}
m_headPositionsDuringLastMove.clear();
// create new segments at head
for(std::size_t i = 0; i < steps; i++) {
// calculate new segment offset
......@@ -117,6 +119,8 @@ std::size_t Snake::move(real_t targetAngle, bool boost)
headSegment.setPos(headSegment.pos() + movementVector2D);
m_headPositionsDuringLastMove.push_back(headSegment.pos());
m_movedSinceLastSpawn += config::SNAKE_DISTANCE_PER_STEP;
// create new segments, if necessary
......
......@@ -28,6 +28,7 @@ class Snake
};
typedef std::deque< Segment > SegmentList;
typedef std::vector< Vector2D > PositionList;
private:
/*!
......@@ -35,6 +36,8 @@ class Snake
*/
SegmentList m_segments;
PositionList m_headPositionsDuringLastMove;
Field *m_field;
real_t m_mass; //!< Mass (length) of the snake
......@@ -117,4 +120,8 @@ class Snake
real_t maxRotationPerStep(void);
/*!
* Get a list of head positions that were used during the last call to move().
*/
const PositionList& getHeadPositionsDuringLastMove(void) const { return m_headPositionsDuringLastMove; };
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment