// enemy_result_priority.cpp
// =========================================
// Bot 'b' ưu tiên kết quả tốt nhất, có xử lý vòng tránh khi gặp 2 hộp liên tiếp
// Đồng thời giữ logic RÀNG BUỘC_B (b không được đi vào vị trí của 'a')
// =========================================
#include <bits/stdc++.h>
using namespace std;
struct Pos {
int r, c;
bool operator==(const Pos &o) const { return r == o.r && c == o.c; }
};
int R = 16, C = 16;
vector<string> grid;
Pos startB, goalB, startA;
vector<Pos> boxes;
// 4 hướng di chuyển
int dr[4] = {-1, 1, 0, 0};
int dc[4] = {0, 0, -1, 1};
char dirChar[4] = {'U', 'D', 'L', 'R'};
// Kiểm tra ô hợp lệ để đi
bool inBounds(int r, int c) {
return r >= 0 && r < R && c >= 0 && c < C;
}
// Hàm phát hiện góc chết (hộp ở vị trí không thể đẩy về goal)
bool isDeadCorner(const Pos &p) {
if (p == goalB) return false;
bool wallUp = (p.r - 1 < 0 || grid[p.r - 1][p.c] == '#');
bool wallDown = (p.r + 1 >= R || grid[p.r + 1][p.c] == '#');
bool wallLeft = (p.c - 1 < 0 || grid[p.r][p.c - 1] == '#');
bool wallRight = (p.c + 1 >= C || grid[p.r][p.c + 1] == '#');
if ((wallUp && wallLeft) || (wallUp && wallRight) ||
(wallDown && wallLeft) || (wallDown && wallRight)) {
return true;
}
return false;
}
// BFS tìm đường đi từ src đến dest (tránh tường, hộp, và RÀNG BUỘC_B)
vector<char> bfsPath(Pos src, Pos dest) {
queue<Pos> q;
map<Pos, Pos> parent;
map<Pos, char> moveChar;
set<pair<int,int>> visited;
q.push(src);
visited.insert({src.r, src.c});
while (!q.empty()) {
Pos cur = q.front(); q.pop();
if (cur == dest) {
vector<char> path;
Pos p = cur;
while (!(p == src)) {
path.push_back(moveChar[p]);
p = parent[p];
}
reverse(path.begin(), path.end());
return path;
}
for (int d = 0; d < 4; d++) {
int nr = cur.r + dr[d];
int nc = cur.c + dc[d];
if (!inBounds(nr, nc)) continue;
if (grid[nr][nc] == '#') continue;
if (grid[nr][nc] == 'X') continue;
// ===== RÀNG BUỘC_B: 'b' KHÔNG ĐƯỢC ĐI VÀO VỊ TRÍ CỦA 'a' =====
// Muốn tắt: comment dòng dưới
if (nr == startA.r && nc == startA.c) continue;
if (!visited.count({nr, nc})) {
visited.insert({nr, nc});
Pos nxt{nr, nc};
parent[nxt] = cur;
moveChar[nxt] = dirChar[d];
q.push(nxt);
}
}
}
return {};
}
// Tìm vị trí đứng để đẩy hộp về goal
vector<char> findPushPath(const Pos &box) {
// BFS trạng thái: (vị trí bot, vị trí hộp)
struct State {
Pos me, b;
vector<char> path;
};
queue<State> q;
set<tuple<int,int,int,int>> visited;
q.push({startB, box, {}});
visited.insert({startB.r, startB.c, box.r, box.c});
while (!q.empty()) {
State cur = q.front(); q.pop();
if (cur.b == goalB) {
return cur.path;
}
for (int d = 0; d < 4; d++) {
int mr = cur.me.r + dr[d];
int mc = cur.me.c + dc[d];
if (!inBounds(mr, mc) || grid[mr][mc] == '#') continue;
// Nếu di chuyển vào vị trí hộp
if (mr == cur.b.r && mc == cur.b.c) {
int br = cur.b.r + dr[d];
int bc = cur.b.c + dc[d];
if (!inBounds(br, bc) || grid[br][bc] == '#' || grid[br][bc] == 'X') continue;
// Không đẩy vào goal của đối thủ
if (grid[br][bc] == 'A') continue;
Pos newMe{mr, mc};
Pos newBox{br, bc};
if (isDeadCorner(newBox)) continue;
if (!visited.count({newMe.r, newMe.c, newBox.r, newBox.c})) {
visited.insert({newMe.r, newMe.c, newBox.r, newBox.c});
auto newPath = cur.path;
newPath.push_back(dirChar[d]);
q.push({newMe, newBox, newPath});
}
} else {
Pos newMe{mr, mc};
if (!visited.count({newMe.r, newMe.c, cur.b.r, cur.b.c})) {
visited.insert({newMe.r, newMe.c, cur.b.r, cur.b.c});
auto newPath = cur.path;
newPath.push_back(dirChar[d]);
q.push({newMe, cur.b, newPath});
}
}
}
}
return {};
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
grid.resize(R);
for (int i = 0; i < R; i++) {
cin >> grid[i];
for (int j = 0; j < C; j++) {
if (grid[i][j] == 'b') startB = {i, j};
if (grid[i][j] == 'B') goalB = {i, j};
if (grid[i][j] == 'a') startA = {i, j};
if (grid[i][j] == 'X') boxes.push_back({i, j});
}
}
vector<char> bestMove;
for (auto &box : boxes) {
if (isDeadCorner(box)) continue;
auto path = findPushPath(box);
if (!path.empty()) {
bestMove = path;
break;
}
}
if (!bestMove.empty()) {
cout << bestMove[0] << "\n";
} else {
cout << "S\n"; // Stay nếu không làm gì
}
return 0;
}