Skip to content
Open
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
8 changes: 8 additions & 0 deletions src/state/include/state/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ class STATE_EXPORT State : public ICommandTaker {
DoubleVec2D blast_position,
size_t impact_range);

/**
* Returns the neighbouring points of a given position
*
* @param position Postion for which neighbouring points are returned
* @return std::vector<Vec2D> Neighbouring points
*/
std::vector<Vec2D> getNeighbouringPoints(DoubleVec2D position);

/**
* Callback passed to all blasters to damage neighbouring actors given a
* position
Expand Down
52 changes: 44 additions & 8 deletions src/state/src/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,50 @@ void State::handleTransformRequests() {
++id) {
for (const auto &bot : bots[id]) {
DoubleVec2D bot_position = bot->getPosition();
Vec2D offset = getOffsetFromPosition(bot_position, (PlayerId) id);
position_counts[offset.x][offset.y]++;
}

for (const auto &tower : towers[id]) {
DoubleVec2D tower_position = tower->getPosition();
Vec2D offset = getOffsetFromPosition(tower_position, (PlayerId) id);
position_counts[offset.x][offset.y]++;
// Get neighbouring points
std::vector<Vec2D> neighbouring_offsets =
getNeighbouringPoints(bot_position);

// If the bot belongs strictly to only one offset
if (neighbouring_offsets.size() == 1) {
Vec2D offset = neighbouring_offsets[0];
position_counts[offset.x][offset.y]++;
} else if (neighbouring_offsets.size() ==
2) { // If the bot is on an edge
Vec2D offset1 = neighbouring_offsets[0];
Vec2D offset2 = neighbouring_offsets[1];

// If either of the offsets are blocked, then the bot is
// assigned to the other offset
if (path_planner->isOffsetBlocked(offset1) &&
!path_planner->isOffsetBlocked(offset2)) {
position_counts[offset2.x][offset2.y]++;
} else if (path_planner->isOffsetBlocked(offset2) &&
!path_planner->isOffsetBlocked(offset1)) {
position_counts[offset1.x][offset1.y]++;
}
} else if (neighbouring_offsets.size() ==
4) { // If the bot is on a vertex on the grid
uint64_t total_blocked_count = 0;
Vec2D unblocked_offset = Vec2D::null;
for (const auto &offset : neighbouring_offsets) {
if (path_planner->isOffsetBlocked(offset)) {
++total_blocked_count;
} else {
unblocked_offset = offset;
}
}

// If 3 offsets are blocked, assigning the actor to the final
// offset
if (total_blocked_count == 3) {
position_counts[unblocked_offset.x][unblocked_offset.y]++;
}

// If less than three are blocked, then not assigning the bot to
// any offset
}
}
}

Expand All @@ -103,7 +139,7 @@ void State::handleTransformRequests() {
Vec2D offset = getOffsetFromPosition(bot_position, (PlayerId) id);
// Checking if only one actor is in the offset position where
// transforming is requested
if (position_counts[offset.x][offset.y] == 1) {
if (position_counts[offset.x][offset.y] <= 1) {
produceTower(bot);
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/state/src/state_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,24 @@ Actor *State::getActorById(ActorId actor_id) {
return tower;
}

std::vector<Vec2D> State::getNeighbouringPoints(DoubleVec2D position) {
uint64_t pos_x = std::floor(position.x), pos_y = std::floor(position.y);

if (pos_x == position.x) {
pos_x = std::min(pos_x - 1, (uint64_t) 0);
}
if (pos_y == position.y) {
pos_y = std::min(pos_y - 1, (uint64_t) 0);
}

std::vector<Vec2D> neighbouring_points;
for (auto x = pos_x; x < std::floor(position.x); ++x) {
for (auto y = pos_y; y < std::floor(position.y); ++y) {
neighbouring_points.push_back(Vec2D(pos_x, pos_y));
}
}

return neighbouring_points;
}

} // namespace state
2 changes: 1 addition & 1 deletion test/state/state_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ TEST_F(StateTest, AcknowledgeTransformRequest) {
std::bind(&State::constructTowerCallback, state.get(), _1);
bot->setConstructTowerCallback(construct_tower_callback);

state->transformBot(bot->getActorId(), bot->getPosition());
bot->setTransforming(true);
bot->update();
bot->lateUpdate();

Expand Down