import java.util.Random; /* * RumbleBot. * Der Rover ist auch mit einem Geschütz ausgestattet, dass nur in Fahrrichtung feuern kann. * Der Feuerbefehl ist „f“. Die Reichweite des Geschützes entspricht der Scanreichweite. * Wälder, Felsen und Wasser blockieren Schüsse. * Der Rover ist beim ersten Treffer zerstört. Wer überlebt am längsten? * docker run --rm -p 63187:63187 mediaeng/bots rumble */ public class RumbleBot extends Bot{ private String moves = ""; private int spiralFactor = 1; private char spiralDirection = '>'; private boolean goesForward = true; private boolean frontIsBlocked, leftIsBlocked, rightIsBlocked; public static void main(String[] args) { Bot rumbleBot = new RumbleBot(args); rumbleBot.run(); } protected RumbleBot(String[] args) { super(args); } protected char nextMove(View view){ char nextMove = checkForEnemy(view) ? takeAimAndShoot(view) : walkByColumns(view); checkBarriers(view); nextMove = checkMove(nextMove); return nextMove; } private char takeAimAndShoot(View view) { resetMovesSequence(); int[] frontIndexes = getFrontIndexes(view); int[] leftIndexes = getLeftIndexes(view); int[] rightIndexes = getRightIndexes(view); char[] enemies = {'^', '<', '>', 'v'}; for (int index : frontIndexes) { for (char enemy : enemies) { if (view.data.charAt(index) == enemy) return 'f'; } } for (int index : leftIndexes) { for (char enemy : enemies) { if (view.data.charAt(index) == '>') return 'v'; else if (view.data.charAt(index) == enemy) return '<'; } } for (int index : rightIndexes) { for (char enemy : enemies) { if (view.data.charAt(index) == '<') return 'v'; else if (view.data.charAt(index) == enemy) return '>'; } } return '^'; } private int[] getLeftIndexes(View view) { int center = view.width / 2; int[] leftIndexes = new int[center]; int index = 0; for (int col = 0; col < center; col++) { leftIndexes[index++] = getCharIndexFromCoordinates(view.width, col, center); } return leftIndexes; } private int[] getRightIndexes(View view) { int center = view.width / 2; int[] rightIndexes = new int[center]; int index = 0; for (int col = center + 1; col < view.width; col++) { rightIndexes[index++] = getCharIndexFromCoordinates(view.width, col, center); } return rightIndexes; } private int[] getFrontIndexes(View view) { int center = view.width / 2; int[] frontIndexes = new int[center]; int index = 0; for (int row = 0; row < center; row++) { frontIndexes[index++] = getCharIndexFromCoordinates(view.width, center, row); } return frontIndexes; } private int getCharIndexFromCoordinates(int width, int x, int y) { return width * y + x; } private void resetMovesSequence() { moves = ""; spiralFactor = 1; spiralDirection = (spiralDirection == '>') ? '<' : '>'; goesForward = true; } private boolean checkForEnemy(View view) { char[] enemies = {'^', '<', '>', 'v'}; boolean enemyDetected = false; for (char enemy : enemies) { if (view.data.contains(Character.toString(enemy))) { enemyDetected = true; break; } } return enemyDetected; } private void checkBarriers(View view) { int centerCoordinates = view.width / 2; int centerIndex = getCharIndexFromCoordinates(view.width, centerCoordinates, centerCoordinates); int frontIndex = getCharIndexFromCoordinates(view.width, centerCoordinates, centerCoordinates - 1); int leftIndex = centerIndex - 1; int rightIndex = centerIndex + 1; char[] obstacles = {'#', '~', 'X'}; frontIsBlocked = containsChar(obstacles, view.data.charAt(frontIndex)); leftIsBlocked = containsChar(obstacles, view.data.charAt(leftIndex)); rightIsBlocked = containsChar(obstacles, view.data.charAt(rightIndex)); } private boolean containsChar(char[] array, char target) { for (char c : array) { if (c == target) { return true; } } return false; } private char checkMove(char move) { if (frontIsBlocked) { resetMovesSequence(); if (leftIsBlocked) move = '>'; else if (rightIsBlocked) move = '<'; } return move; } private char walkBySpiral(View view) { if (moves.isEmpty()) { spiralFactor++; moves += "^".repeat(view.width * spiralFactor) + spiralDirection + "^".repeat(view.width * spiralFactor) + spiralDirection; } char nextMove = moves.charAt(0); moves = moves.substring(1); return nextMove; } private char walkByColumns(View view) { if (moves.isEmpty()) { int min = 10; int max = 100; Random random = new Random(); int steps = random.nextInt((max - min) + 1) + min; //int steps = 32 - view.width; moves = "^".repeat(steps); moves += (goesForward ? ">" + "^".repeat(view.width) + ">" : "<" + "^".repeat(view.width) + "<"); goesForward = !goesForward; } char nextMove = moves.charAt(0); moves = moves.substring(1); return nextMove; } }