Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.ArrayList;
- import java.util.Scanner;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.awt.Point;
- public class NeverEndingSnake {
- public enum Result {COMPLETE, INCOMPLETE, DEATH};
- public enum Cell {START, EMPTY, FOOD, HOLE, VISITED, VISITED_FOOD};
- private Result evaluate(Cell[][] map, Path path) {
- int x = 0;
- int y = 0;
- for (int i = 0; i < map.length; i++) {
- for (int j = 0; j < map[0].length; j++) {
- if (map[i][j] == Cell.START) {
- x = i;
- y = j;
- }
- }
- }
- for (char dir : path.getPath().toCharArray()) {
- x += dir == 'l' ? -1 : dir == 'r' ? 1 : 0;
- y += dir == 'u' ? -1 : dir == 'd' ? 1 : 0;
- if (x < 0 || x >= map.length || y < 0 || y >= map[0].length) {
- return Result.DEATH;
- } else {
- if (map[x][y] == Cell.HOLE || map[x][y] == Cell.START || map[x][y] == Cell.VISITED || map[x][y] == Cell.VISITED_FOOD) {
- return Result.DEATH;
- }
- }
- map[x][y] = map[x][y] == Cell.FOOD ? Cell.VISITED_FOOD : Cell.VISITED;
- }
- boolean complete = true;
- for (int i = 0; i < map.length; i++) {
- for (int j = 0; j < map[0].length; j++) {
- complete = complete && map[i][j] != Cell.FOOD;
- }
- }
- return complete ? Result.COMPLETE : Result.INCOMPLETE;
- }
- private void solve(Cell[][] map) {
- ArrayList<Path> paths = new ArrayList<>();
- paths.add(new Path("", map));
- while (!paths.isEmpty()) {
- paths.sort((Path path1, Path path2) -> path1.getPriority() - path2.getPriority());
- Path path = paths.get(0);
- switch (evaluate(map, path)) {
- case COMPLETE:
- char last = ' ';
- int count = 1;
- for (char dir : path.getPath().toCharArray()) {
- if (dir == last) {
- count++;
- } else {
- if (count != 1) {
- System.out.print(count);
- }
- count = 1;
- System.out.print(dir);
- }
- last = dir;
- }
- if (count != 1) {
- System.out.print(count);
- }
- System.out.println();
- return;
- case INCOMPLETE:
- paths.remove(0);
- paths.add(new Path(path.getPath() + 'l', map));
- paths.add(new Path(path.getPath() + 'u', map));
- paths.add(new Path(path.getPath() + 'r', map));
- paths.add(new Path(path.getPath() + 'd', map));
- break;
- case DEATH:
- paths.remove(0);
- break;
- }
- for (int x = 0; x < map.length; x++) {
- for (int y = 0; y < map[0].length; y++) {
- switch (map[x][y]) {
- case VISITED:
- map[x][y] = Cell.EMPTY;
- break;
- case VISITED_FOOD:
- map[x][y] = Cell.FOOD;
- break;
- }
- }
- }
- }
- System.out.println("No solution found.");
- }
- public Cell[][] loadMap(String filename) throws FileNotFoundException {
- File file = new File(filename);
- Scanner scanner = new Scanner(file);
- ArrayList<String> input = new ArrayList<>();
- while (scanner.hasNextLine()) {
- input.add(scanner.nextLine());
- }
- int w = input.get(0).length() - 2;
- int h = input.size() - 2;
- Cell[][] map = new Cell[w][h];
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- switch (input.get(y + 1).charAt(x + 1)) {
- case 's':
- map[x][y] = Cell.START;
- break;
- case '*':
- map[x][y] = Cell.FOOD;
- break;
- case 'O':
- map[x][y] = Cell.HOLE;
- break;
- default:
- map[x][y] = Cell.EMPTY;
- break;
- }
- }
- }
- return map;
- }
- public void neverEndingSnake() throws FileNotFoundException {
- for (int i = 1; i <= 16; i++) {
- String filename = "map" + i + ".txt";
- System.out.print(filename + " ");
- solve(loadMap(filename));
- }
- }
- public static void main(String[] args) throws FileNotFoundException {
- (new NeverEndingSnake()).neverEndingSnake();
- }
- private class Path {
- final private String path;
- final private int priority;
- public Path(String path, Cell[][] map) {
- this.path = path;
- ArrayList<Point> foods = new ArrayList<>();
- Point start = new Point(0, 0);
- for (int x = 0; x < map.length; x++) {
- for (int y = 0; y < map[0].length; y++) {
- switch (map[x][y]) {
- case START:
- start.x = x;
- start.y = y;
- break;
- case FOOD:
- foods.add(new Point(x, y));
- break;
- }
- }
- }
- for (char dir : path.toCharArray()) {
- start.x += dir == 'l' ? -1 : dir == 'r' ? 1 : 0;
- start.y += dir == 'u' ? -1 : dir == 'd' ? 1 : 0;
- }
- int pr = path.length();
- while (!foods.isEmpty()) {
- Point closest = foods.get(0);
- for (Point food : foods) {
- if (Math.abs(food.x - start.x) + Math.abs(food.y - start.y) < Math.abs(closest.x - start.x) + Math.abs(closest.y - start.y)) {
- closest = food;
- }
- }
- pr += Math.abs(closest.x - start.x) + Math.abs(closest.y - start.y);
- start.x = closest.x;
- start.y = closest.y;
- foods.remove(closest);
- }
- priority = pr;
- }
- public String getPath() {
- return path;
- }
- public int getPriority() {
- return priority;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement