You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RumbleBot.java 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import java.util.LinkedList;
  2. import java.util.Queue;
  3. public class RumbleBot extends Bot {
  4. protected final static String obstacles = "~#X";
  5. protected boolean offByOne = true;
  6. protected int currentStepCount = 0;
  7. protected int steps = 0;
  8. public static void main(String[] args) {
  9. Bot bot = new RumbleBot(args);
  10. bot.run();
  11. }
  12. protected RumbleBot(String[] args) {
  13. super(args);
  14. }
  15. @Override
  16. protected char nextMove(View view) {
  17. System.out.println();
  18. int size = view.width;
  19. String data = view.data
  20. .replace('^', '*')
  21. .replace('<', '*')
  22. .replace('>', '*')
  23. .replace('V', '*');
  24. char[][] grid = dataToGrid(data, size);
  25. if (data.contains("*")) {
  26. if (isInLineOfSight(grid)) {
  27. return 'f';
  28. } else {
  29. return breadthFirstSearch(grid);
  30. }
  31. } else {
  32. return walkAround(grid);
  33. }
  34. }
  35. protected char[][] dataToGrid(String data, int size) {
  36. char[][] grid = new char[size][size];
  37. for (int i = 0; i < data.length(); i++) {
  38. grid[i % size][i / size] = data.charAt(i);
  39. }
  40. return grid;
  41. }
  42. boolean isInLineOfSight(char[][] grid) {
  43. int size = grid.length;
  44. for (int y = size / 2; y > 0; y--) {
  45. if (obstacles.contains("" + grid[size / 2][y]))
  46. break;
  47. if (grid[size / 2][y] == '*') {
  48. return true;
  49. }
  50. }
  51. return false;
  52. }
  53. protected char walkAround(char[][] grid) {
  54. if (steps == 0) {
  55. currentStepCount++;
  56. if (offByOne) {
  57. currentStepCount++;
  58. }
  59. offByOne = !offByOne;
  60. steps = currentStepCount;
  61. return '>';
  62. } else {
  63. steps--;
  64. return safeMove(grid);
  65. }
  66. }
  67. protected char safeMove(char[][] grid) {
  68. int size = grid.length;
  69. if (obstacles.contains("" + grid[size / 2][size / 2 - 1])) {
  70. return '<';
  71. } else {
  72. return '^';
  73. }
  74. }
  75. protected char breadthFirstSearch(char[][] grid) {
  76. int size = grid.length;
  77. int start = size / 2;
  78. boolean[][] visited = new boolean[size][size];
  79. Queue<Move> queue = new LinkedList<>();
  80. int[][] directions = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
  81. char[] commands = {'^', '>', '>', '<'};
  82. for (int i = 0; i < 4; i++) {
  83. queue.add(new Move(start + directions[i][0], start + directions[i][1], commands[i]));
  84. }
  85. queue.add(new Move(start, start - 1, '^'));
  86. queue.add(new Move(start, start + 1, '>'));
  87. queue.add(new Move(start + 1, start, '>'));
  88. queue.add(new Move(start - 1, start, '<'));
  89. while (!queue.isEmpty()) {
  90. Move move = queue.poll();
  91. if (move.x < 0 || move.x >= size || move.y < 0 || move.y >= size || visited[move.x][move.y]) continue;
  92. visited[move.x][move.y] = true;
  93. if (obstacles.contains("" + grid[move.x][move.y])) continue;
  94. if (grid[move.x][move.y] == '*') return move.direction;
  95. for (int[] direction : directions) {
  96. queue.add(new Move(move.x + direction[0], move.y + direction[1], move.direction));
  97. }
  98. }
  99. System.err.println("No path found");
  100. return safeMove(grid);
  101. }
  102. protected record Move(int x, int y, char direction) {
  103. }
  104. }