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

10 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import java.util.Random;
  2. /*
  3. * RumbleBot.
  4. * Der Rover ist auch mit einem Geschütz ausgestattet, dass nur in Fahrrichtung feuern kann.
  5. * Der Feuerbefehl ist „f“. Die Reichweite des Geschützes entspricht der Scanreichweite.
  6. * Wälder, Felsen und Wasser blockieren Schüsse.
  7. * Der Rover ist beim ersten Treffer zerstört. Wer überlebt am längsten?
  8. * docker run --rm -p 63187:63187 mediaeng/bots rumble
  9. */
  10. public class RumbleBot extends Bot{
  11. private String moves = "";
  12. private int spiralFactor = 1;
  13. private char spiralDirection = '>';
  14. private boolean goesForward = true;
  15. private boolean frontIsBlocked, leftIsBlocked, rightIsBlocked;
  16. public static void main(String[] args) {
  17. Bot rumbleBot = new RumbleBot(args);
  18. rumbleBot.run();
  19. }
  20. protected RumbleBot(String[] args) {
  21. super(args);
  22. }
  23. protected char nextMove(View view){
  24. char nextMove = checkForEnemy(view) ? takeAimAndShoot(view) : walkByColumns(view);
  25. checkBarriers(view);
  26. nextMove = checkMove(nextMove);
  27. return nextMove;
  28. }
  29. private char takeAimAndShoot(View view) {
  30. resetMovesSequence();
  31. int[] frontIndexes = getFrontIndexes(view);
  32. int[] leftIndexes = getLeftIndexes(view);
  33. int[] rightIndexes = getRightIndexes(view);
  34. char[] enemies = {'^', '<', '>', 'v'};
  35. for (int index : frontIndexes) {
  36. for (char enemy : enemies) {
  37. if (view.data.charAt(index) == enemy) return 'f';
  38. }
  39. }
  40. for (int index : leftIndexes) {
  41. for (char enemy : enemies) {
  42. if (view.data.charAt(index) == '>') return 'v';
  43. else if (view.data.charAt(index) == enemy) return '<';
  44. }
  45. }
  46. for (int index : rightIndexes) {
  47. for (char enemy : enemies) {
  48. if (view.data.charAt(index) == '<') return 'v';
  49. else if (view.data.charAt(index) == enemy) return '>';
  50. }
  51. }
  52. return '^';
  53. }
  54. private int[] getLeftIndexes(View view) {
  55. int center = view.width / 2;
  56. int[] leftIndexes = new int[center];
  57. int index = 0;
  58. for (int col = 0; col < center; col++) {
  59. leftIndexes[index++] = getCharIndexFromCoordinates(view.width, col, center);
  60. }
  61. return leftIndexes;
  62. }
  63. private int[] getRightIndexes(View view) {
  64. int center = view.width / 2;
  65. int[] rightIndexes = new int[center];
  66. int index = 0;
  67. for (int col = center + 1; col < view.width; col++) {
  68. rightIndexes[index++] = getCharIndexFromCoordinates(view.width, col, center);
  69. }
  70. return rightIndexes;
  71. }
  72. private int[] getFrontIndexes(View view) {
  73. int center = view.width / 2;
  74. int[] frontIndexes = new int[center];
  75. int index = 0;
  76. for (int row = 0; row < center; row++) {
  77. frontIndexes[index++] = getCharIndexFromCoordinates(view.width, center, row);
  78. }
  79. return frontIndexes;
  80. }
  81. private int getCharIndexFromCoordinates(int width, int x, int y) {
  82. return width * y + x;
  83. }
  84. private void resetMovesSequence() {
  85. moves = "";
  86. spiralFactor = 1;
  87. spiralDirection = (spiralDirection == '>') ? '<' : '>';
  88. goesForward = true;
  89. }
  90. private boolean checkForEnemy(View view) {
  91. char[] enemies = {'^', '<', '>', 'v'};
  92. boolean enemyDetected = false;
  93. for (char enemy : enemies) {
  94. if (view.data.contains(Character.toString(enemy))) {
  95. enemyDetected = true;
  96. break;
  97. }
  98. }
  99. return enemyDetected;
  100. }
  101. private void checkBarriers(View view) {
  102. int centerCoordinates = view.width / 2;
  103. int centerIndex = getCharIndexFromCoordinates(view.width, centerCoordinates, centerCoordinates);
  104. int frontIndex = getCharIndexFromCoordinates(view.width, centerCoordinates, centerCoordinates - 1);
  105. int leftIndex = centerIndex - 1;
  106. int rightIndex = centerIndex + 1;
  107. char[] obstacles = {'#', '~', 'X'};
  108. frontIsBlocked = containsChar(obstacles, view.data.charAt(frontIndex));
  109. leftIsBlocked = containsChar(obstacles, view.data.charAt(leftIndex));
  110. rightIsBlocked = containsChar(obstacles, view.data.charAt(rightIndex));
  111. }
  112. private boolean containsChar(char[] array, char target) {
  113. for (char c : array) {
  114. if (c == target) {
  115. return true;
  116. }
  117. }
  118. return false;
  119. }
  120. private char checkMove(char move) {
  121. if (frontIsBlocked) {
  122. resetMovesSequence();
  123. if (leftIsBlocked) move = '>';
  124. else if (rightIsBlocked) move = '<';
  125. }
  126. return move;
  127. }
  128. private char walkBySpiral(View view) {
  129. if (moves.isEmpty()) {
  130. spiralFactor++;
  131. moves += "^".repeat(view.width * spiralFactor) + spiralDirection + "^".repeat(view.width * spiralFactor) + spiralDirection;
  132. }
  133. char nextMove = moves.charAt(0);
  134. moves = moves.substring(1);
  135. return nextMove;
  136. }
  137. private char walkByColumns(View view) {
  138. if (moves.isEmpty()) {
  139. int min = 10;
  140. int max = 100;
  141. Random random = new Random();
  142. int steps = random.nextInt((max - min) + 1) + min;
  143. //int steps = 32 - view.width;
  144. moves = "^".repeat(steps);
  145. moves += (goesForward ? ">" + "^".repeat(view.width) + ">" : "<" + "^".repeat(view.width) + "<");
  146. goesForward = !goesForward;
  147. }
  148. char nextMove = moves.charAt(0);
  149. moves = moves.substring(1);
  150. return nextMove;
  151. }
  152. }