From c7a576dfabb15f144f517bef658a06aecb066cc9 Mon Sep 17 00:00:00 2001 From: Your Average Code <138674451+UrAvgCode@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:11:04 +0100 Subject: [PATCH] RumbleBot derived from SnakeBot --- rumbletest.sh | 4 ++ src/RumbleBot.java | 122 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 96 insertions(+), 30 deletions(-) create mode 100755 rumbletest.sh diff --git a/rumbletest.sh b/rumbletest.sh new file mode 100755 index 0000000..0ec5d75 --- /dev/null +++ b/rumbletest.sh @@ -0,0 +1,4 @@ +while true +do +docker run --rm -p 63187:63187 mediaeng/bots rumble +done diff --git a/src/RumbleBot.java b/src/RumbleBot.java index f2339ba..c624522 100644 --- a/src/RumbleBot.java +++ b/src/RumbleBot.java @@ -1,7 +1,11 @@ +import java.util.LinkedList; +import java.util.Queue; + public class RumbleBot extends Bot { - boolean offByOne = true; - int currentStepCount = 0; - int steps = 0; + protected final static String obstacles = "~#X"; + protected boolean offByOne = true; + protected int currentStepCount = 0; + protected int steps = 0; public static void main(String[] args) { Bot bot = new RumbleBot(args); @@ -13,49 +17,107 @@ public class RumbleBot extends Bot { } @Override - protected char nextMove(View view) throws Exception { - String data = view.data; - int width = view.width; - int height = data.length() / view.width; - - data = data.replace('^', '*'); - data = data.replace('<', '*'); - data = data.replace('>', '*'); - data = data.replace('V', '*'); + protected char nextMove(View view) { System.out.println(); + int size = view.width; + String data = view.data + .replace('^', '*') + .replace('<', '*') + .replace('>', '*') + .replace('V', '*'); + char[][] grid = dataToGrid(data, size); if (data.contains("*")) { - int index = data.indexOf('*'); - if (index < width * height / 2 && index % width == 4) { + if (isInLineOfSight(grid)) { return 'f'; - } else if (index < width * height / 2 && !(index > width * height / 2 + 1)) { - return safeMove(data); - } else if (index % 5 < 2) { - return '<'; - } else if (index % 5 > 2) { - return '>'; + } else { + return breadthFirstSearch(grid); } - return ' '; - } else if (steps == 0) { - currentStepCount += 1; + } else { + return walkAround(grid); + } + } + + protected char[][] dataToGrid(String data, int size) { + char[][] grid = new char[size][size]; + for (int i = 0; i < data.length(); i++) { + grid[i % size][i / size] = data.charAt(i); + } + return grid; + } + + boolean isInLineOfSight(char[][] grid) { + int size = grid.length; + for (int y = size / 2; y > 0; y--) { + if (obstacles.contains("" + grid[size / 2][y])) + break; + + if (grid[size / 2][y] == '*') { + return true; + } + } + return false; + } + + protected char walkAround(char[][] grid) { + if (steps == 0) { + currentStepCount++; if (offByOne) { - currentStepCount += 1; + currentStepCount++; } offByOne = !offByOne; steps = currentStepCount; return '>'; } else { - steps -= 1; - return safeMove(data); + steps--; + return safeMove(grid); } } - protected char safeMove(String data) { - if ("~#X".contains("" + data.charAt(35))) { - currentStepCount = 2; - return '>'; + protected char safeMove(char[][] grid) { + int size = grid.length; + if (obstacles.contains("" + grid[size / 2][size / 2 - 1])) { + return '<'; } else { return '^'; } } + + protected char breadthFirstSearch(char[][] grid) { + int size = grid.length; + int start = size / 2; + + boolean[][] visited = new boolean[size][size]; + Queue queue = new LinkedList<>(); + + int[][] directions = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}}; + char[] commands = {'^', '>', '>', '<'}; + for (int i = 0; i < 4; i++) { + queue.add(new Move(start + directions[i][0], start + directions[i][1], commands[i])); + } + + queue.add(new Move(start, start - 1, '^')); + queue.add(new Move(start, start + 1, '>')); + queue.add(new Move(start + 1, start, '>')); + queue.add(new Move(start - 1, start, '<')); + + while (!queue.isEmpty()) { + Move move = queue.poll(); + if (move.x < 0 || move.x >= size || move.y < 0 || move.y >= size || visited[move.x][move.y]) continue; + visited[move.x][move.y] = true; + if (obstacles.contains("" + grid[move.x][move.y])) continue; + if (grid[move.x][move.y] == '*') return move.direction; + + for (int[] direction : directions) { + queue.add(new Move(move.x + direction[0], move.y + direction[1], move.direction)); + } + } + + System.err.println("No path found"); + return safeMove(grid); + } + + protected record Move(int x, int y, char direction) { + } + }