All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pacman.game.internal.Maze Maven / Gradle / Ivy

There is a newer version: 2.0.1.0
Show newest version
package pacman.game.internal;

import java.util.Scanner;

import static pacman.game.Constants.*;

//import java.util.EnumMap;
//import pacman.game.Constants.MOVE;

/*
 * Stores the actual mazes, each of which is simply a connected graph. The differences between the mazes are the connectivity
 * and the x,y coordinates (used for drawing or to compute the Euclidean distance. There are 3 built-in distance functions in
 * total: Euclidean, Manhattan and Dijkstra's shortest path distance. The latter is pre-computed and loaded, the others are
 * computed on the fly whenever getNextDir(-) is called.
 */
public final class Maze {
    public AStar astar;
    public int[] shortestPathDistances, pillIndices, powerPillIndices, junctionIndices;    //Information for the controllers
    public int initialPacManNodeIndex, lairNodeIndex, initialGhostNodeIndex;                //Maze-specific information
    public Node[] graph;                                                                //The actual maze, stored as a graph (set of nodes)
    public String name;                                                                    //Name of the Maze

    /*
     * Each maze is stored as a (connected) graph: all nodes have neighbours, stored in an array of length 4. The
     * index of the array associates the direction the neighbour is located at: '[up,right,down,left]'.
     * For instance, if node '9' has neighbours '[-1,12,-1,6]', you can reach node '12' by going right, and node
     * 6 by going left. The directions returned by the controllers should thus be in {0,1,2,3} and can be used
     * directly to determine the next node to go to.
     */
    public Maze(int index) {
        loadNodes(nodeNames[index]);
        loadDistances(distNames[index]);

        //create A* graph for shortest paths for the ghosts
        astar = new AStar();
        astar.createGraph(graph);
    }

    //Loads all the nodes from files and initialises all maze-specific information.
    private void loadNodes(String fileName) {

        Scanner scanner = new Scanner(getClass().getResourceAsStream(pathMazes + "/" + fileName + ".txt"));
        String input = scanner.nextLine();

        //preamble
        String[] pr = input.split("\t");

        this.name = pr[0];
        this.initialPacManNodeIndex = Integer.parseInt(pr[1]);
        this.lairNodeIndex = Integer.parseInt(pr[2]);
        this.initialGhostNodeIndex = Integer.parseInt(pr[3]);
        this.graph = new Node[Integer.parseInt(pr[4])];
        this.pillIndices = new int[Integer.parseInt(pr[5])];
        this.powerPillIndices = new int[Integer.parseInt(pr[6])];
        this.junctionIndices = new int[Integer.parseInt(pr[7])];

        int nodeIndex = 0;
        int pillIndex = 0;
        int powerPillIndex = 0;
        int junctionIndex = 0;

        while (scanner.hasNextLine()) {
            input = scanner.nextLine();
            String[] nd = input.split("\t");

            Node node = new Node(Integer.parseInt(nd[0]), Integer.parseInt(nd[1]), Integer.parseInt(nd[2]), Integer.parseInt(nd[7]), Integer.parseInt(nd[8]),
                    new int[]{Integer.parseInt(nd[3]), Integer.parseInt(nd[4]), Integer.parseInt(nd[5]), Integer.parseInt(nd[6])});

            graph[nodeIndex++] = node;

            if (node.pillIndex >= 0) {
                pillIndices[pillIndex++] = node.nodeIndex;
            } else if (node.powerPillIndex >= 0) {
                powerPillIndices[powerPillIndex++] = node.nodeIndex;
            }

            if (node.numNeighbouringNodes > 2) {
                junctionIndices[junctionIndex++] = node.nodeIndex;
            }
        }

        scanner.close();

    }

    /*
     * Loads the shortest path distances which have been pre-computed. The data contains the shortest distance from
     * any node in the maze to any other node. Since the graph is symmetric, the symmetries have been removed to preserve
     * memory and all distances are stored in a 1D array; they are looked-up using getDistance(-).
     */
    private void loadDistances(String fileName) {
        this.shortestPathDistances = new int[((graph.length * (graph.length - 1)) / 2) + graph.length];

        Scanner scanner = new Scanner(getClass().getResourceAsStream(pathDistances + "/" + fileName));
        //        BufferedReader br = new BufferedReader(new InputStreamReader(ClassLoader.getSystemClassLoader().getResourceAsStream(pathDistances + System.getProperty("file.separator") + fileName)));
        String input;
        int index = 0;

        while (scanner.hasNextLine()) {
            input = scanner.nextLine();
            shortestPathDistances[index++] = Integer.parseInt(input);
        }

        scanner.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy