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.

SnakeBot.java 3.6KB

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