changed algo. added build
This commit is contained in:
@@ -466,31 +466,50 @@ public class HamiltonianSnakeAI extends JPanel implements ActionListener {
|
||||
scoreLabel.setText("Score: " + score);
|
||||
}
|
||||
}
|
||||
private Point findDirectPathToFood(Point head, List<Point> possibleMoves) {
|
||||
// Find moves that directly reduce distance to food
|
||||
Point bestMove = null;
|
||||
int minDistance = Integer.MAX_VALUE;
|
||||
|
||||
for (Point move : possibleMoves) {
|
||||
int dist = estimateDistance(move, food);
|
||||
if (dist < minDistance && !willCollideImmediately(move)) {
|
||||
minDistance = dist;
|
||||
bestMove = move;
|
||||
}
|
||||
}
|
||||
|
||||
return bestMove;
|
||||
}
|
||||
|
||||
private Point getNextMove(Point head) {
|
||||
List<Point> possibleMoves = getSafeMoves(head);
|
||||
|
||||
if (possibleMoves.isEmpty()) {
|
||||
return head; // No safe moves available (will trigger game over)
|
||||
return head; // No safe moves available
|
||||
}
|
||||
|
||||
// 1. First priority: Don't die next turn
|
||||
// 1. If food is very close and safe, go for it immediately
|
||||
if (estimateDistance(head, food) <= 3) {
|
||||
Point foodMove = findDirectPathToFood(head, possibleMoves);
|
||||
if (foodMove != null) {
|
||||
return foodMove;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Filter out immediately deadly moves
|
||||
possibleMoves = filterImmediatelyDeadlyMoves(possibleMoves);
|
||||
if (possibleMoves.isEmpty()) return head;
|
||||
|
||||
// 2. Second priority: Don't create future traps
|
||||
possibleMoves = filterFutureTraps(possibleMoves, 3); // Look 3 moves ahead
|
||||
if (possibleMoves.isEmpty()) return head;
|
||||
|
||||
// 3. If food is reachable and safe, go for it
|
||||
// 3. If food is reachable via safe path, prioritize it
|
||||
Point foodPathMove = findSafePathToFood(head, possibleMoves);
|
||||
if (foodPathMove != null) {
|
||||
if (foodPathMove != null && !willCreateTrap(foodPathMove)) {
|
||||
return foodPathMove;
|
||||
}
|
||||
|
||||
// 4. Follow Hamiltonian cycle with safety checks
|
||||
return followSuperSafeHamiltonianCycle(head, possibleMoves);
|
||||
}
|
||||
|
||||
private List<Point> filterImmediatelyDeadlyMoves(List<Point> moves) {
|
||||
List<Point> safeMoves = new ArrayList<>();
|
||||
for (Point move : moves) {
|
||||
@@ -593,29 +612,35 @@ public class HamiltonianSnakeAI extends JPanel implements ActionListener {
|
||||
return bestMove;
|
||||
}
|
||||
|
||||
private boolean willCreateTrap(Point move) {
|
||||
// Simulate the move
|
||||
List<Point> simulatedBody = new ArrayList<>(snake.getBody());
|
||||
simulatedBody.add(0, move);
|
||||
simulatedBody.remove(simulatedBody.size() - 1);
|
||||
|
||||
// Check if this would leave enough space
|
||||
int reachable = countReachableCells(move, new HashSet<>(simulatedBody));
|
||||
return reachable < snake.getLength() * 0.5; // Adjust threshold as needed
|
||||
}
|
||||
|
||||
private Point followSuperSafeHamiltonianCycle(Point head, List<Point> possibleMoves) {
|
||||
int currentIndex = hamiltonianPath[head.y][head.x];
|
||||
int nextIndex = (currentIndex + 1) % (gridSize * gridSize);
|
||||
|
||||
// Find the safest move along the cycle
|
||||
Point bestMove = null;
|
||||
int bestSafetyScore = -1;
|
||||
|
||||
for (Point move : possibleMoves) {
|
||||
// Sort moves by how much they progress along the cycle
|
||||
possibleMoves.sort(Comparator.comparingInt(move -> {
|
||||
int moveIndex = hamiltonianPath[move.y][move.x];
|
||||
int cycleProgress = (moveIndex - currentIndex + gridSize * gridSize) % (gridSize * gridSize);
|
||||
return (moveIndex - currentIndex + gridSize * gridSize) % (gridSize * gridSize);
|
||||
}));
|
||||
|
||||
// Calculate safety score (higher is better)
|
||||
int safetyScore = (gridSize * gridSize - cycleProgress) + countSafeExits(move, new HashSet<>(snake.getBody()));
|
||||
|
||||
if (safetyScore > bestSafetyScore ||
|
||||
(safetyScore == bestSafetyScore && cycleProgress < (gridSize * gridSize) / 2)) {
|
||||
bestSafetyScore = safetyScore;
|
||||
bestMove = move;
|
||||
// Return the move that makes most progress while being safe
|
||||
for (Point move : possibleMoves) {
|
||||
if (!willCreateTrap(move)) {
|
||||
return move;
|
||||
}
|
||||
}
|
||||
|
||||
return bestMove != null ? bestMove : possibleMoves.get(0);
|
||||
// Fallback to first possible move if all would create traps
|
||||
return possibleMoves.get(0);
|
||||
}
|
||||
|
||||
private Point findOptimalPathToFood(Point head, List<Point> possibleMoves) {
|
||||
@@ -982,4 +1007,12 @@ class Snake {
|
||||
public boolean contains(Point point) {
|
||||
return body.contains(point);
|
||||
}
|
||||
|
||||
public int getGridSize() {
|
||||
return gridSize;
|
||||
}
|
||||
|
||||
public void setGridSize(int gridSize) {
|
||||
this.gridSize = gridSize;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user