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 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 final static String targets = "v^<>";
  6. protected boolean offByOne = true;
  7. protected int currentStepCount = 0;
  8. protected int steps = 0;
  9. public static void main(String[] args) {
  10. if(args.length == 0) {
  11. String[] dummyArgs = {"localhost", "63187"};
  12. DummyBot dummy = new DummyBot(dummyArgs);
  13. new Thread(dummy).start();
  14. }
  15. Bot bot = new RumbleBot(args);
  16. bot.run();
  17. }
  18. protected RumbleBot(String[] args) {
  19. super(args);
  20. }
  21. @Override
  22. protected char nextMove(View view) {
  23. System.out.println();
  24. int size = view.width;
  25. String data = view.data;
  26. char[][] grid = dataToGrid(data, size);
  27. if (data.contains("v") || data.contains("^") || data.contains("<") || data.contains(">")) {
  28. if (isInLineOfSight(grid)) {
  29. return 'f';
  30. } else {
  31. return breadthFirstSearch(grid);
  32. }
  33. } else {
  34. return walkAround(grid);
  35. }
  36. }
  37. protected char[][] dataToGrid(String data, int size) {
  38. char[][] grid = new char[size][size];
  39. for (int i = 0; i < data.length(); i++) {
  40. grid[i % size][i / size] = data.charAt(i);
  41. }
  42. return grid;
  43. }
  44. protected void markFiringLines(char[][] grid) {
  45. int size = grid.length;
  46. for (int x = 0; x < size; x++) {
  47. for (int y = 0; y < size; y++) {
  48. switch (grid[x][y]) {
  49. case 'v' -> markLine(grid, x, y, 0, 1);
  50. case '^' -> markLine(grid, x, y, 0, -1);
  51. case '>' -> markLine(grid, x, y, 1, 0);
  52. case '<' -> markLine(grid, x, y, -1, 0);
  53. }
  54. }
  55. }
  56. }
  57. private void markLine(char[][] grid, int x, int y, int dx, int dy) {
  58. int size = grid.length;
  59. x += dx;
  60. y += dy;
  61. while (x >= 0 && x < size && y >= 0 && y < size && !obstacles.contains("" + grid[x][y])) {
  62. if (grid[x][y] == '.') {
  63. grid[x][y] = '*';
  64. }
  65. x += dx;
  66. y += dy;
  67. }
  68. }
  69. protected boolean isInLineOfSight(char[][] grid) {
  70. int size = grid.length;
  71. for (int y = size / 2; y > 0; y--) {
  72. if (obstacles.contains("" + grid[size / 2][y]))
  73. break;
  74. if (targets.contains("" + grid[size / 2][y]))
  75. return true;
  76. }
  77. return false;
  78. }
  79. protected char walkAround(char[][] grid) {
  80. if (steps == 0) {
  81. currentStepCount = (currentStepCount + 1) % 10;
  82. if (offByOne) {
  83. currentStepCount++;
  84. }
  85. offByOne = !offByOne;
  86. steps = currentStepCount;
  87. return '>';
  88. } else {
  89. steps--;
  90. return safeMove(grid);
  91. }
  92. }
  93. protected char safeMove(char[][] grid) {
  94. int size = grid.length;
  95. if (obstacles.contains("" + grid[size / 2][size / 2 - 1])) {
  96. return '<';
  97. } else {
  98. return '^';
  99. }
  100. }
  101. protected char breadthFirstSearch(char[][] grid) {
  102. markFiringLines(grid);
  103. int size = grid.length;
  104. int start = size / 2;
  105. for (int y = 0; y < size; y++) {
  106. for (char[] chars : grid) System.err.print(chars[y]);
  107. System.err.println();
  108. }
  109. boolean[][] visited = new boolean[size][size];
  110. Queue<Move> queue = new LinkedList<>();
  111. int[][] directions = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
  112. char[] commands = {'^', 'v', '>', '<'};
  113. for (int i = 0; i < 4; i++) {
  114. queue.add(new Move(start + directions[i][0], start + directions[i][1], commands[i]));
  115. }
  116. while (!queue.isEmpty()) {
  117. Move move = queue.poll();
  118. if (move.x < 0 || move.x >= size || move.y < 0 || move.y >= size || visited[move.x][move.y]) continue;
  119. visited[move.x][move.y] = true;
  120. if (obstacles.contains("" + grid[move.x][move.y])) continue;
  121. if (targets.contains("" + grid[move.x][move.y])) return move.direction;
  122. for (int[] direction : directions) {
  123. queue.add(new Move(move.x + direction[0], move.y + direction[1], move.direction));
  124. }
  125. }
  126. System.err.println("No path found");
  127. return safeMove(grid);
  128. }
  129. protected record Move(int x, int y, char direction) {
  130. }
  131. }