Prog3A-Bot/EscapeBot.java
2025-02-10 13:26:27 +01:00

170 lines
5.3 KiB
Java

import java.util.*;
public class EscapeBot extends Bot {
private boolean rocketFound;
private int roverX;
private int roverY;
public EscapeBot(String[] args) {
super(args);
this.rocketFound = false;
this.roverX = -1; // Startposition des Rovers ist unbekannt
this.roverY = -1;
}
@Override
protected char nextMove(View view) throws Exception {
if (rocketFound) {
System.out.println("Rakete gefunden! Rover kehrt zurück.");
return 'V'; // Rückwärts bewegen
}
if (roverX == -1 || roverY == -1) {
for (int y = 0; y < view.width; y++) {
for (int x = 0; x < view.width; x++) {
char cell = view.data.charAt(y * view.width + x);
if (cell == 'A') {
roverX = x;
roverY = y;
}
}
}
}
char[][] grid = new char[view.width][view.width];
for (int y = 0; y < view.width; y++) {
for (int x = 0; x < view.width; x++) {
grid[y][x] = view.data.charAt(y * view.width + x);
}
}
List<Node> path = aStarSearch(grid, roverX, roverY);
if (path != null && !path.isEmpty()) {
Node nextNode = path.get(0);
if (nextNode.x > roverX) {
roverX++;
return 'd'; // Nach rechts bewegen
} else if (nextNode.x < roverX) {
roverX--;
return 'a'; // Nach links bewegen
} else if (nextNode.y > roverY) {
roverY++;
return '^'; // Vorwärts bewegen
} else if (nextNode.y < roverY) {
roverY--;
return 'V'; // Rückwärts bewegen
}
}
return '^'; // Standardbewegung, wenn keine Richtung gefunden wurde
}
private List<Node> aStarSearch(char[][] grid, int startX, int startY) {
PriorityQueue<Node> openList = new PriorityQueue<>(Comparator.comparingInt(a -> a.f));
Set<Node> closedSet = new HashSet<>();
Map<Node, Node> cameFrom = new HashMap<>();
Map<Node, Integer> gScore = new HashMap<>();
Map<Node, Integer> fScore = new HashMap<>();
Node startNode = new Node(startX, startY);
openList.add(startNode);
gScore.put(startNode, 0);
fScore.put(startNode, heuristic(startNode));
while (!openList.isEmpty()) {
Node current = openList.poll();
if (grid[current.y][current.x] == 'o') {
return reconstructPath(cameFrom, current);
}
closedSet.add(current);
for (Node neighbor : getNeighbors(current, grid)) {
if (closedSet.contains(neighbor)) {
continue;
}
int tentativeGScore = gScore.getOrDefault(current, Integer.MAX_VALUE) + 1;
if (!openList.contains(neighbor) || tentativeGScore < gScore.getOrDefault(neighbor, Integer.MAX_VALUE)) {
cameFrom.put(neighbor, current);
gScore.put(neighbor, tentativeGScore);
fScore.put(neighbor, tentativeGScore + heuristic(neighbor));
if (!openList.contains(neighbor)) {
openList.add(neighbor);
}
}
}
}
return null; // Kein Weg gefunden
}
private List<Node> getNeighbors(Node node, char[][] grid) {
List<Node> neighbors = new ArrayList<>();
int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // Rechts, Links, Unten, Oben
for (int[] dir : directions) {
int newX = node.x + dir[0];
int newY = node.y + dir[1];
if (newX >= 0 && newX < grid.length && newY >= 0 && newY < grid.length &&
grid[newY][newX] != '#') {
neighbors.add(new Node(newX, newY));
}
}
return neighbors;
}
private List<Node> reconstructPath(Map<Node, Node> cameFrom, Node current) {
List<Node> path = new ArrayList<>();
path.add(current);
while (cameFrom.containsKey(current)) {
current = cameFrom.get(current);
path.add(current);
}
Collections.reverse(path);
return path;
}
private int heuristic(Node node) {
// Verwenden Sie die Manhattan-Distanz als Heuristik, um die tatsächliche Entfernung zum Ziel zu schätzen
return Math.abs(node.x - roverX) + Math.abs(node.y - roverY);
}
private static class Node {
int x;
int y;
int f;
Node(int x, int y) {
this.x = x;
this.y = y;
this.f = 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return x == node.x && y == node.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
public static void main(String[] args) {
EscapeBot escapeBot = new EscapeBot(args);
escapeBot.run();
}
}