Commit 268bb6d5 authored by Thomas Kolb's avatar Thomas Kolb
Browse files

Do not use shared_ptrs for Segments

parent b938000d
......@@ -278,8 +278,8 @@ void Field::debugVisualization(void)
bool first = true;
for(auto &seg: snake->getSegments()) {
size_t x = static_cast<size_t>(seg->pos().x());
size_t y = static_cast<size_t>(seg->pos().y());
size_t x = static_cast<size_t>(seg.pos().x());
size_t y = static_cast<size_t>(seg.pos().y());
if(first) {
rep[y*intW + x] = '#';
......
......@@ -25,13 +25,13 @@ class Field
public:
struct SnakeSegmentInfo {
std::shared_ptr<Snake::Segment> segment; //!< Pointer to the segment
const Snake::Segment &segment; //!< Pointer to the segment
std::shared_ptr<Bot> bot; //!< The bot this segment belongs to
SnakeSegmentInfo(const std::shared_ptr<Snake::Segment> &s, const std::shared_ptr<Bot> &b)
SnakeSegmentInfo(const Snake::Segment &s, const std::shared_ptr<Bot> &b)
: segment(s), bot(b) {}
const Vector2D& pos() const { return segment->pos(); }
const Vector2D& pos() const { return segment.pos(); }
};
typedef SpatialMap<SnakeSegmentInfo, config::SPATIAL_MAP_TILES_X, config::SPATIAL_MAP_TILES_Y> SegmentInfoMap;
......
......@@ -63,7 +63,7 @@ namespace MsgPackProtocol
struct BotMoveItem
{
guid_t bot_id;
std::vector< std::shared_ptr<Snake::Segment> > new_segments;
std::vector< Snake::Segment > new_segments;
uint32_t current_length;
uint32_t current_segment_radius;
};
......
......@@ -7,8 +7,7 @@
Snake::Snake(Field *field)
: m_field(field), m_mass(1.0f), m_heading(0.0f)
{
std::shared_ptr<Segment> segment = std::make_shared<Segment>(Vector2D {0,0});
m_segments.push_back(segment);
m_segments.emplace_back(Vector2D {0,0});
ensureSizeMatchesMass();
}
......@@ -18,8 +17,7 @@ Snake::Snake(Field *field, const Vector2D &startPos, real_t start_mass,
: m_field(field), m_mass(start_mass), m_heading(start_heading)
{
// create the first segment manually
std::shared_ptr<Segment> segment = std::make_shared<Segment>(startPos);
m_segments.push_back(segment);
m_segments.emplace_back(startPos);
// create the other segments
ensureSizeMatchesMass();
......@@ -45,9 +43,9 @@ void Snake::ensureSizeMatchesMass(void)
if(curLen < targetLen) {
// segments have to be added:
// repeat the last segment until the new target length is reached
const std::shared_ptr<Segment> refSegment = m_segments[curLen-1];
const Segment &refSegment = m_segments[curLen-1];
for(std::size_t i = 0; i < (targetLen - curLen); i++) {
m_segments.push_back(std::make_shared<Segment>(*refSegment));
m_segments.emplace_back(refSegment);
}
} else if(curLen > targetLen) {
// segments must be removed
......@@ -94,12 +92,12 @@ std::size_t Snake::move(real_t targetAngle, bool boost)
// unwrap all coordinates
for(std::size_t i = 0; i < m_segments.size(); i++) {
auto &ref = (i == 0) ? m_segments[0]->pos() : m_segments[i-1]->pos();
m_segments[i]->setPos(m_field->unwrapCoords(m_segments[i]->pos(), ref));
auto &ref = (i == 0) ? m_segments[0].pos() : m_segments[i-1].pos();
m_segments[i].setPos(m_field->unwrapCoords(m_segments[i].pos(), ref));
}
// remove the head from the segment list (will be re-added later)
std::shared_ptr<Segment> headSegment = m_segments[0];
Segment headSegment(m_segments[0]);
m_segments.erase(m_segments.begin());
// create multiple segments while boosting
......@@ -117,21 +115,20 @@ std::size_t Snake::move(real_t targetAngle, bool boost)
Vector2D movementVector2D(cos(headingRad), sin(headingRad));
movementVector2D *= config::SNAKE_DISTANCE_PER_STEP;
headSegment->setPos(headSegment->pos() + movementVector2D);
headSegment.setPos(headSegment.pos() + movementVector2D);
m_movedSinceLastSpawn += config::SNAKE_DISTANCE_PER_STEP;
// create new segments, if necessary
while(m_movedSinceLastSpawn > m_targetSegmentDistance) {
// vector from the first segment to the direction of the head
Vector2D newSegmentOffset = headSegment->pos() - m_segments[0]->pos();
Vector2D newSegmentOffset = headSegment.pos() - m_segments[0].pos();
newSegmentOffset *= (m_targetSegmentDistance / newSegmentOffset.norm());
m_movedSinceLastSpawn -= m_targetSegmentDistance;
// create new segment
std::shared_ptr<Segment> segment = std::make_shared<Segment>(m_segments[0]->pos() + newSegmentOffset);
m_segments.push_front(segment);
m_segments.emplace_front(m_segments[0].pos() + newSegmentOffset);
}
}
......@@ -150,15 +147,15 @@ std::size_t Snake::move(real_t targetAngle, bool boost)
// pull-together effect
for(std::size_t i = 1; i < m_segments.size()-1; i++) {
m_segments[i]->setPos(
m_segments[i]->pos() * (1 - config::SNAKE_PULL_FACTOR) +
(m_segments[i+1]->pos() * 0.5 + m_segments[i-1]->pos() * 0.5) * config::SNAKE_PULL_FACTOR
m_segments[i].setPos(
m_segments[i].pos() * (1 - config::SNAKE_PULL_FACTOR) +
(m_segments[i+1].pos() * 0.5 + m_segments[i-1].pos() * 0.5) * config::SNAKE_PULL_FACTOR
);
}
// wrap coordinates
for(std::size_t i = 0; i < m_segments.size(); i++) {
m_segments[i]->setPos(m_field->wrapCoords(m_segments[i]->pos()));
m_segments[i].setPos(m_field->wrapCoords(m_segments[i].pos()));
}
return m_segments.size(); // == number of new segments at head
......@@ -171,7 +168,7 @@ const Snake::SegmentList& Snake::getSegments(void) const
const Vector2D& Snake::getHeadPosition(void) const
{
return m_segments[0]->pos();
return m_segments[0].pos();
}
real_t Snake::getSegmentRadius(void) const
......@@ -181,7 +178,7 @@ real_t Snake::getSegmentRadius(void) const
bool Snake::canConsume(const Food &food)
{
const Vector2D &headPos = m_segments[0]->pos();
const Vector2D &headPos = m_segments[0].pos();
const Vector2D &foodPos = food.pos();
Vector2D unwrappedFoodPos = m_field->unwrapCoords(foodPos, headPos);
......@@ -196,6 +193,6 @@ void Snake::convertToFood(void) const
real_t foodPerSegment = m_mass / m_segments.size() * config::SNAKE_CONVERSION_FACTOR;
for(auto &s: m_segments) {
m_field->createDynamicFood(foodPerSegment, s->pos(), m_segmentRadius);
m_field->createDynamicFood(foodPerSegment, s.pos(), m_segmentRadius);
}
}
......@@ -19,12 +19,14 @@ class Snake
class Segment : public PositionObject
{
public:
Segment() : PositionObject(Vector2D {0,0}) {}
Segment(const Vector2D &position) : PositionObject(position) {}
Segment(const Segment &other) : PositionObject(other.pos()) {}
const Segment& operator = (const Segment &other) { setPos(other.pos()); return *this; }
// more stuff like color?
};
typedef std::deque< std::shared_ptr<Segment> > SegmentList;
typedef std::deque< Segment > SegmentList;
private:
/*!
......
Markdown is supported
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