123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*
- * SnakeBot.
- * Eine weitere wichtige Funktion des Rovers ist es, Gesteinsproben zu sammeln.
- * Interessante Steine sind im Scan mit einem @ gekennzeichnet.
- * Mit jeder aufgesammelten Gesteinsprobe wird an den Rover ein Wagen angehängt, der zukünftig hinter dem Rover mitgezogen wird.
- * Die Wagen sind im Scan mit * zu identifizieren.
- * Vorsicht: fährt der Rover in einen Wagen, ist er schwer beschädigt und kann keine weiteren Steine mehr sammeln.
- * Sie können Ihre Implementierung wieder testen mit:
- * docker run --rm -p 63187:63187 mediaeng/bots snakes
- * Für diese Funktion wird am 7.2.24 in einer gemeinsamen Arena mit allen Teams des Jahrgangs ein Wettbewerb durchgeführt.
- * Die besten acht Teams qualifizieren sich für die Königsdisziplin „Rumble“.
- */
- public class SnakeBot extends Bot{
- String moves = "";
- private int spiralNumber = 0;
- private boolean ignoreStones = false;
- public static void main(String[] args) {
- Bot snakeBot = new SnakeBot(args);
- snakeBot.run();
- }
-
- protected SnakeBot(String[] args) {
- super(args);
- }
- //@TODO: find a better way to avoid collectedStones
- protected char nextMove(View view) {
- boolean stoneDetected = view.data.contains("@");
- char nextMove;
- nextMove = (stoneDetected && !ignoreStones) ? goToStone(view) : walkBySpiral(view);
-
- int centerCoordinateOfView = view.width / 2;
- int frontCellIndex = calculateCharIndexFromCoordinates(view.width, centerCoordinateOfView, centerCoordinateOfView - 1);
-
- if(nextMove == '^' && view.data.charAt(frontCellIndex) == '*'){
- nextMove = (countCollectedStonesLeft(view) <= countCollectedStonesRight(view)) ? '<' : '>';
- ignoreStones = true;
- }
- /*
- * @TODO:
- * Avoiding endless loops due to trying to collect two stones at once.
- * Problem: stones located near to each other are ignored.
- */
- if(countUncollectedStones(view) > 1) ignoreStones = true;
- if(countCollectedStones(view) <= 2 && countUncollectedStones(view) <= 1) ignoreStones = false;
-
- return nextMove;
- }
-
- private int countUncollectedStones(View view) {
- int count = 0;
-
- for (char c : view.data.toCharArray()) {
- if (c == '@') count++;
- }
- return count;
- }
-
- private int countCollectedStonesLeft(View view) {
- int[] leftSide = generateLeftSideArray(view.width);
- int stones = 0;
- for (int cellIndex : leftSide) {
- if(view.data.charAt(cellIndex) == '*') stones++;
- }
- return stones;
- }
-
- private int countCollectedStonesRight(View view) {
- int[] rightSide = generateRightSideArray(view.width);
- int stones = 0;
- for (int cellIndex : rightSide) {
- if(view.data.charAt(cellIndex) == '*') stones++;
- }
- return stones;
- }
-
- private int countCollectedStones(View view) {
- int count = 0;
-
- for (char c : view.data.toCharArray()) {
- if (c == '*') count++;
- }
- return count;
- }
-
- private char goToStone(View view) {
- int rowDifference = findStoneRow(view) - (view.width / 2);
- return rowDifference < 0 ? '^' : '<';
- }
-
- private int findStoneRow(View view) {
- return view.data.indexOf('@') / view.width;
- }
-
- private char walkBySpiral(View view) {
- if (moves.isEmpty()) {
- spiralNumber++;
- moves += "^".repeat(view.width * spiralNumber) + ">" + "^".repeat(view.width * spiralNumber) + ">";
- }
- char nextMove = moves.charAt(0);
- moves = moves.substring(1);
- return nextMove;
- }
-
- private int calculateCharIndexFromCoordinates(int width, int x, int y){
- return width * y + x;
- }
-
- private int[] generateLeftSideArray(int sideLength) {
- int[] leftStones = new int[sideLength / 2 * sideLength];
- int index = 0;
-
- for (int row = 0; row < sideLength; row++) {
- for (int col = 0; col < sideLength / 2; col++) {
- leftStones[index++] = row * sideLength + col;
- }
- }
-
- return leftStones;
- }
-
- private int[] generateRightSideArray(int sideLength) {
- int[] rightStones = new int[sideLength / 2 * sideLength];
- int index = 0;
-
- for (int row = 0; row < sideLength; row++) {
- for (int col = (sideLength / 2) + 1; col < sideLength; col++) {
- rightStones[index++] = row * sideLength + col;
- }
- }
-
- return rightStones;
- }
- }
|