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.8KB

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