follow left wall

This commit is contained in:
Thomas Lindner 2022-05-20 16:28:04 +02:00
parent 64ccef590d
commit 586889f543

View file

@ -17,6 +17,27 @@
namespace asio = boost::asio; namespace asio = boost::asio;
enum class Direction : int {
UP,
RIGHT,
DOWN,
LEFT,
};
std::string_view DirectionToString(Direction direction) {
switch (direction) {
case Direction::UP:
return "up";
case Direction::RIGHT:
return "right";
case Direction::DOWN:
return "down";
case Direction::LEFT:
return "left";
}
return "(invalid)";
}
class Bot { class Bot {
asio::any_io_executor executor; asio::any_io_executor executor;
asio::ip::tcp::socket socket; asio::ip::tcp::socket socket;
@ -26,13 +47,7 @@ class Bot {
int goal_x, goal_y; int goal_x, goal_y;
int x, y; int x, y;
bool up, right, down, left; bool up, right, down, left;
Direction heading;
enum class Direction : int {
UP,
RIGHT,
DOWN,
LEFT,
};
asio::awaitable<void> Protocol(); asio::awaitable<void> Protocol();
asio::awaitable<void> Join(); asio::awaitable<void> Join();
@ -46,7 +61,11 @@ class Bot {
Bot::Bot(asio::any_io_executor executor, std::string_view name, Bot::Bot(asio::any_io_executor executor, std::string_view name,
std::string_view pass) std::string_view pass)
: executor{executor}, socket{executor}, name{name}, pass{pass} { : executor{executor},
socket{executor},
name{name},
pass{pass},
heading{Direction::LEFT} {
asio::co_spawn(executor, std::bind(&Bot::Protocol, this), asio::detached); asio::co_spawn(executor, std::bind(&Bot::Protocol, this), asio::detached);
} }
@ -113,59 +132,30 @@ asio::awaitable<void> Bot::Join() {
asio::awaitable<bool> Bot::Move(Direction direction) { asio::awaitable<bool> Bot::Move(Direction direction) {
asio::streambuf buf; asio::streambuf buf;
std::ostream os{&buf}; std::ostream os{&buf};
std::string_view direction_str; if (direction == Direction::LEFT && left) {
switch (direction) { co_return false;
case Direction::LEFT:
direction_str = "left";
if (left) {
co_return false;
}
break;
case Direction::UP:
direction_str = "up";
if (up) {
co_return false;
}
break;
case Direction::RIGHT:
direction_str = "right";
if (right) {
co_return false;
}
break;
case Direction::DOWN:
direction_str = "down";
if (down) {
co_return false;
}
break;
} }
os << "move|" << direction_str << std::endl; if (direction == Direction::UP && up) {
std::cout << "<- Go " << direction_str << std::endl; co_return false;
}
if (direction == Direction::RIGHT && right) {
co_return false;
}
if (direction == Direction::DOWN && down) {
co_return false;
}
os << "move|" << DirectionToString(direction) << std::endl;
std::cout << "<- Go " << DirectionToString(direction) << std::endl;
co_await async_write(socket, buf.data(), asio::use_awaitable); co_await async_write(socket, buf.data(), asio::use_awaitable);
co_return true; co_return true;
} }
asio::awaitable<void> Bot::ChooseMove() { asio::awaitable<void> Bot::ChooseMove() {
// move closer to the goal if possible // follow left wall
if (x > goal_x && co_await Move(Direction::LEFT)) { while (!co_await Move(heading)) {
co_return; heading = Direction{(static_cast<int>(heading) + 1) % 4};
} }
if (x > goal_y && co_await Move(Direction::UP)) { heading = Direction{(static_cast<int>(heading) + 3) % 4};
co_return;
}
if (x < goal_x && co_await Move(Direction::RIGHT)) {
co_return;
}
if (x < goal_y && co_await Move(Direction::DOWN)) {
co_return;
}
// choose a random direction
std::uniform_int_distribution<int> direction{0, 3};
while (!co_await Move(Direction{direction(generator)}))
;
co_return; co_return;
} }