programmieren-projekt/src/SpecificAiPlayerHard.java

125 lines
3.8 KiB
Java

import java.util.ArrayList;
import java.util.Random;
public class SpecificAiPlayerHard extends AiPlayer{
private int gridSize;
private boolean[][] shotsFired;
private final ArrayList<Point> hitQueue;
private final Random random;
private int nextChessRow;
private int nextChessCol;
public SpecificAiPlayerHard() {
super();
this.setName("AI Player Hard");
/*this.gridSize = super.board.getSize();
this.shotsFired = new boolean[gridSize][gridSize];*/
this.gridSize = 0;
this.hitQueue = new ArrayList<>();
this.random = new Random();
this.nextChessRow = 0;
this.nextChessCol = 0;
}
// Checks if a position has already been shot at
public boolean alreadyShot(Point p) {
return shotsFired[p.getX()][p.getY()];
}
// Generates the next move for the AI
public Point getNextMove() {
if(gridSize == 0) {
this.gridSize = super.board.getSize();
this.shotsFired = new boolean[gridSize][gridSize];
}
// If there are hits to process, prioritize those
while (!hitQueue.isEmpty()) {
Point target = hitQueue.remove(0);
if (!alreadyShot(target)) {
return target;
}
}
// Otherwise, use chess pattern targeting
int row = nextChessRow;
int col = nextChessCol;
while (alreadyShot(new Point(row, col))) {
advanceChessPattern();
row = nextChessRow;
col = nextChessCol;
}
shotsFired[row][col] = true;
advanceChessPattern();
return new Point(row, col);
}
@Override
public synchronized void receiveHit(HitResponse hitResponse) {
super.receiveHit(hitResponse);
// If it's a hit or sunk, add adjacent cells to the hitsQueue
if (hitResponse.getHitResponse() == HitResponseType.HIT) {
addAdjacentPoints(hitResponse.getPoint());
}
}
private void addAdjacentPoints(Point point) {
int x = point.getX();
int y = point.getY();
// Possible adjacent positions (up, down, left, right)
Point[] adjacentPoints = {
new Point(x, y - 1),
new Point(x, y + 1),
new Point(x - 1, y),
new Point(x + 1, y)
};
for (Point p : adjacentPoints) {
if (isValidPoint(p) && !alreadyShot(p) && !hitQueue.contains(p)) {
hitQueue.add(p);
}
}
}
private boolean isValidPoint(Point point) {
return point.getX() >= 0 && point.getX() < gridSize &&
point.getY() >= 0 && point.getY() < gridSize;
}
@Override
public void aiShoot() {
this.enemy.receiveShoot(getNextMove());
}
// Advances the chess pattern to the next cell
private void advanceChessPattern() {
nextChessCol += 2;
if (nextChessCol >= gridSize) {
nextChessRow += 1;
nextChessCol = (nextChessRow % 2 == 0) ? 0 : 1; // Alternate starting points for chess pattern
}
if (nextChessRow >= gridSize) {
nextChessRow = 0;
nextChessCol = 0; // Reset if pattern wraps around
}
}
// Adds adjacent cells to the hit queue
/* public void processHit(int row, int col) {
if (row > 0 && !alreadyShot(row - 1, col)) {
hitQueue.add(new int[]{row - 1, col});
}
if (row < gridSize - 1 && !alreadyShot(row + 1, col)) {
hitQueue.add(new int[]{row + 1, col});
}
if (col > 0 && !alreadyShot(row, col - 1)) {
hitQueue.add(new int[]{row, col - 1});
}
if (col < gridSize - 1 && !alreadyShot(row, col + 1)) {
hitQueue.add(new int[]{row, col + 1});
}
}*/
}