umutcaner's picture
Upload 29 files
f11ab78 verified
import java.awt.Color;
import java.util.Random;
public class Agent {
private int x, y;
private final int id;
private final MazeManager maze;
private final Color color;
private final String name;
private boolean phaseWallUsed = false;
private boolean passedWall = false;
private final Stack<String> moveHistory;
private final Random random = new Random();
private boolean gotPowerUp = false;
private int powerUpUses = 0;
private int stepCount = 0;
private int trapHits = 0;
public Agent(int startX, int startY, MazeManager maze, Color color, String name, int id) {
this.id=id;
this.x = startX;
this.y = startY;
this.maze = maze;
this.color = color;
this.name = name;
this.moveHistory = new Stack<>(maze.getCols() * maze.getRows());
moveHistory.push("(" + x + ", " + y + ")");
}
public int getId()
{
return id;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getTrapHits() {
return trapHits;
}
public String getName() {
return name;
}
public Stack<String> getMoveHistory() {
return moveHistory;
}
public boolean passedWallThisTurn() {
return passedWall;
}
public void setPassedWall(boolean value) {
this.passedWall = value;
}
public int getStepCount() {
return stepCount;
}
public int getPowerUpUses() {
return powerUpUses;
}
public void moveTowardsGoal() {
boolean canPhaseWall = false;
if (gotPowerUp && !phaseWallUsed) {
if (random.nextInt(100) < 20) {
canPhaseWall = true;
passedWall = true;
powerUpUses++;
}
} else {
passedWall = false;
}
Node[] openSet = new Node[maze.getCols() * maze.getRows()];
boolean[][] closedSet = new boolean[maze.getCols()][maze.getRows()];
int openSetSize = 0;
int goalX = maze.getCols() / 2;
int goalY = maze.getRows() / 2;
Node start = new Node(x, y, null, 0, heuristic(x, y, goalX, goalY));
openSet[openSetSize++] = start;
Node goalNode = null;
while (openSetSize > 0) {
int bestIndex = 0;
for (int i = 1; i < openSetSize; i++) {
if (openSet[i].f < openSet[bestIndex].f) bestIndex = i;
}
Node current = openSet[bestIndex];
openSet[bestIndex] = openSet[--openSetSize];
if (current.x == goalX && current.y == goalY) {
goalNode = current;
break;
}
closedSet[current.x][current.y] = true;
for (int dir = 0; dir < 4; dir++) {
int nx = current.x;
int ny = current.y;
switch (dir) {
case 0:
ny--;
break;
case 1:
nx++;
break;
case 2:
ny++;
break;
case 3:
nx--;
break;
}
if (!maze.isInMaze(nx, ny)) {
continue;
}
boolean isWall = maze.hasWall(current.x, current.y, dir);
if (isWall && !canPhaseWall) {
continue;
}
if (closedSet[nx][ny]) {
continue;
}
boolean alreadyInOpenSet = false;
for (int i = 0; i < openSetSize; i++) {
if (openSet[i].x == nx && openSet[i].y == ny) {
alreadyInOpenSet = true;
break;
}
}
if (!alreadyInOpenSet) {
openSet[openSetSize++] = new Node(nx, ny, current,
current.g + 1, heuristic(nx, ny, goalX, goalY));
}
}
}
if (goalNode != null && goalNode.parent != null) {
Node moveTo = goalNode;
while (moveTo.parent.parent != null) {
moveTo = moveTo.parent;
}
int oldX = x;
int oldY = y;
if (maze.hasWall(x, y, directionTo(moveTo.x, moveTo.y)) && canPhaseWall) {
phaseWallUsed = true;
}
this.x = moveTo.x;
this.y = moveTo.y;
if (x != oldX || y != oldY) {
moveHistory.push("(" + x + ", " + y + ")");
stepCount++;
}
MazeTile tile = maze.getTile(x, y);
if (tile.getEntity() == MazeTile.EntityType.TRAP && tile.isTrapActive()) {
tile.deactivateTrap();
trapHits++;
stepBackTwice();
}
if (tile.getEntity() == MazeTile.EntityType.POWER_UP && tile.isPowerUpActive()) {
tile.deactivatePowerUp();
gotPowerUp = true;
phaseWallUsed = false;
}
}
}
private int directionTo(int toX, int toY) {
if (toX == x + 1) return 1;
if (toX == x - 1) return 3;
if (toY == y + 1) return 2;
if (toY == y - 1) return 0;
return -1;
}
private void stepBackTwice() {
if (moveHistory.getSize() < 3) return;
moveHistory.pop();
moveHistory.pop();
String coord = (String) moveHistory.pop();
String[] parts = coord.replace("(", "").replace(")", "").split(", ");
this.x = Integer.parseInt(parts[0]);
this.y = Integer.parseInt(parts[1]);
}
private int heuristic(int x1, int y1, int x2, int y2) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}
private static class Node {
int x, y;
Node parent;
int g;
int f;
public Node(int x, int y, Node parent, int g, int h) {
this.x = x;
this.y = y;
this.parent = parent;
this.g = g;
this.f = g + h;
}
}
}