import java.util.ArrayList; import java.util.List; public class SpecificAiPlayerMedium extends AiPlayer{ private List hitsQueue = new ArrayList<>(); public SpecificAiPlayerMedium() { super(); this.setName("AI Player Medium"); } @Override public void aiShoot() { Point nextShot = ComputeNextShot(); // Shoot at the enemy and receive the hit response enemy.receiveShoot(nextShot); } @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()); } } public Point ComputeNextShot() { Point nextShot; // Prioritize shots from the hitsQueue while (!hitsQueue.isEmpty()) { nextShot = hitsQueue.remove(0); if (!alreadyShot(nextShot)) { return nextShot; } } // If hitsQueue is empty, pick a random point that hasn't been shot do { nextShot = RandomPoint(); } while (alreadyShot(nextShot)); return nextShot; } 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) && !hitsQueue.contains(p)) { hitsQueue.add(p); } } } private boolean alreadyShot(Point p) { return this.enemy.board.getHitResponseOnPoint(p) != null; } private boolean isValidPoint(Point point) { return point.getX() >= 0 && point.getX() < board.getSize() && point.getY() >= 0 && point.getY() < board.getSize(); } }