Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Main File
- * Reads in a dungeon file specified as the only argument
- * Creates the maze from the file and displays it
- * Has two buttons, find shortest solution then play back
- * the solution
- *
- * @author Bryan Custer
- * CS416 Fall 2010
- */
- import javax.swing.*;
- import javax.swing.border.Border;
- import javax.swing.border.LineBorder;
- import java.awt.*;
- import java.awt.BorderLayout;
- import java.util.*;
- import java.io.File;
- public class GamePanel extends JPanel
- {
- //----------------------- Instance Variables -------------------------------
- private DrawPanel drawing;
- private GUIPanel gp;
- private int windowSize = 600;
- private Digraph graph;
- private Node startNode;
- private Node endNode;
- private HashMap<String, JLabel> labelCon = null;
- private HashMap<String, Arrow> edgeCon = null;
- private HashMap<String, Node> hash = null;
- private ArrayList<Edge> edgeArr = null;
- private JLabel label[ ] = null;
- private Arrow edges[ ] = null;
- private ArrayList<String> path = null;
- private ArrayList<ArrayList<String>> pList = null;
- private ArrayList<Arrow> eList = null;
- public static double pi = 3.14159268;
- //++++++++++++++++++++++++++++ Constructors ++++++++++++++++++++++++++++++++
- /**
- * Reads in the dungeon file and creates the display
- */
- public GamePanel( String filename )
- {
- setLayout( new BorderLayout() );
- setSize( windowSize, windowSize );
- gp = new GUIPanel( this );
- add( gp, BorderLayout.NORTH );
- drawing = new DrawPanel();
- add( drawing, BorderLayout.CENTER );
- readGraphFile( filename );
- labelCon = graph.getLabels();
- edgeCon = graph.getEdges();
- hash = graph.getNodes();
- edgeArr = graph.getEdgesArray();
- updateLabels( );
- drawLines( );
- }
- //++++++++++++++++++++++++++++ Public Methods ++++++++++++++++++++++++++++++
- //----------------------- drawLines( ) ----------------------------------
- /**
- * Draws the Arrow (edges) forom node to node.
- */
- public void drawLines( )
- {
- edges = new Arrow[ edgeCon.size() ];
- edgeCon.values().toArray( edges );
- for( int i = 0; i < edgeArr.size(); i++ )
- {
- JLabel tempLabelS = labelCon.get( edgeArr.get( i ).start.getId() );
- JLabel tempLabelE = labelCon.get( edgeArr.get( i ).end.getId() );
- Point one = new Point( tempLabelS.getX(), tempLabelS.getY() );
- Point two = new Point( tempLabelE.getX() + tempLabelE.getWidth(),
- tempLabelE.getY() + tempLabelE.getHeight() );
- edgeCon.get( tempLabelS.getText() +
- tempLabelE.getText() ).setLine( one, two );
- drawing.draw( edges[ i ] );
- }
- }
- //----------------------- updateLabels( ) ----------------------------------
- /**
- * Updates the position of the labels around a cirlce and differentiate the
- * start and end nodes.
- */
- public void updateLabels( )
- {
- label = new JLabel[ labelCon.size() ];
- labelCon.values().toArray( label );
- for( int i = 0; i < label.length; i++ )
- {
- Border border = new LineBorder( Color.BLACK, 1 );
- label[ i ].setBorder( border );
- label[ i ].setHorizontalAlignment( JLabel.CENTER );
- label[ i ].setSize( label[ i ].getPreferredSize() );
- label[ i ].setForeground( Color.BLACK );
- label[ i ].setOpaque( true );
- label[ i ].setBackground( Color.WHITE );
- if( startNode != null &&
- label[i].getText().equals( startNode.toString() ) )
- {
- label[ i ].setBackground( new Color(0x3CAB0B) );
- label[ i ].setForeground( Color.WHITE );
- }
- if( endNode != null &&
- label[i].getText().equals( endNode.toString() ) )
- {
- label[ i ].setBackground( Color.RED );
- label[ i ].setForeground( Color.WHITE );
- }
- double r = ( windowSize / 2 ) - 25; // to adjust for size of label
- int x = (int)Math.round( r * Math.cos( i * 2 * pi / label.length ) );
- int y = (int)Math.round( r * Math.sin( i * 2 * pi / label.length ) );
- label[ i ].setLocation( x + 4 + (int)r, y + 4 + (int)r);
- drawing.add( label[ i ] );
- }
- }
- //---------------------- findAPath() --------------------------------
- /**
- * Starts the recursive digraph algorithm to find any path from start to end
- * Start and end room must be defined
- */
- public void findAPath()
- {
- resetGraph();
- path = new ArrayList<String>();
- pList = new ArrayList<ArrayList<String>>();
- eList = new ArrayList<Arrow>();
- if( findPath( path, pList, eList, startNode, endNode, Dungeon.reportLevel) )
- {
- for( int i = 0; i < label.length; i++ )
- hash.get( label[ i ].getText() ).setMarked( false );
- String msg = "Path Found: ";
- //-------------------- REPORT LEVEL ZERO -------------------------------
- if( Dungeon.reportLevel == 0 )
- {
- eList.clear();
- for( int i = 0; i < pList.get( 0 ).size(); i++ )
- {
- if( i < pList.get( 0 ).size() - 1 )
- {
- eList.add( edgeCon.get( pList.get( 0 ).get( i ) +
- pList.get( 0 ).get( i + 1 ) ) );
- showPath();
- }
- msg += pList.get( 0 ).get( i );
- if( i + 1 != pList.get( 0 ).size() )
- msg += " => ";
- }
- showPath();
- System.out.println( msg );
- JOptionPane.showMessageDialog( null, msg );
- }
- //--------------- REPORT LEVEL ONE, TWO, THREE -------------------------
- else if( Dungeon.reportLevel == 1 || Dungeon.reportLevel == 2 ||
- Dungeon.reportLevel == 3 )
- {
- for( int k = 0; k < pList.size(); k++ )
- {
- msg = "Path Found(" + k + "): ";
- eList.clear();
- for( int i = 0; i < pList.get( k ).size(); i++ )
- {
- if( i < pList.get( k ).size() - 1 )
- {
- eList.add( edgeCon.get( pList.get( k ).get( i ) +
- pList.get( k ).get( i + 1 ) ) );
- showPath();
- }
- msg += pList.get( k ).get( i );
- if( Dungeon.reportLevel == 3 )
- JOptionPane.showMessageDialog( null, msg );
- if( i + 1 != pList.get( k ).size() )
- msg += " => ";
- }
- showPath();
- System.out.println( msg );
- JOptionPane.showMessageDialog( null, msg );
- }
- }
- }
- else
- {
- String msg = "No path found";
- JOptionPane.showMessageDialog( null, msg );
- }
- //showPath();
- }
- //--------------------- findAPath( Node, Node ) -----------------------------
- /**
- * The recursive digraph algorithm to find all paths from start to end
- */
- public Boolean findPath( ArrayList<String> p, ArrayList<ArrayList<String>> pL,
- ArrayList<Arrow> eL, Node s, Node e, int n )
- {
- if ( s.getMarked() )
- {
- if( n == 2 )
- {
- String msg = "CYCLE DETECTED: ";
- System.out.println( s.toString() );
- for( int i = 0; i < p.size(); i++ )
- {
- msg += p.get( i );
- if( i + 1 != p.size() )
- msg += " => ";
- }
- JOptionPane.showMessageDialog( null, msg );
- }
- return false;
- }
- // Reached the end
- if ( s.getId().equals( e.getId() ) )
- {
- p.add( s.getId() );
- if( pL.contains( p ) )
- {
- p.remove( s.getId() );
- return false;
- }
- else
- {
- ArrayList<String> tempPath = new ArrayList<String>();;
- tempPath.addAll(p);
- pL.add( tempPath );
- p.remove( s.getId() );
- return true;
- }
- }
- ArrayList<Edge> edges = s.getEdges();
- // No more edges
- if( edges == null )
- {
- p.remove( s.getId() );
- return false;
- }
- p.add( s.getId() );
- s.setMarked( true );
- Boolean tempRet = false;
- for( int i = 0; i < edges.size(); i++ )
- {
- if( findPath( p, pL, eL, edges.get( i ).end, e, n ) )
- {
- tempRet = true;
- }
- }
- s.setMarked( false );
- p.remove( s.getId() );
- return tempRet;
- }
- //---------------------- findShortestPath() --------------------------------
- /**
- * Starts the recursive algorithm to find the shortest path
- * Start and end room must be defined
- */
- public void findShortestPath()
- {
- String msg = "No path found";
- resetGraph();
- findAPath();
- if( pList != null && pList.size() > 0 )
- {
- int min = pList.get( 0 ).size();
- int shortest = 0;
- for( int i = 0; i < pList.size(); i++ )
- {
- if( pList.get( i ).size() < min )
- {
- min = pList.get( i ).size();
- shortest = i;
- }
- }
- int max = pList.get( 0 ).size();
- int longest = 0;
- for( int i = 0; i < pList.size(); i++ )
- {
- if( pList.get( i ).size() > max )
- {
- max = pList.get( i ).size();
- longest = i;
- }
- }
- msg = "Shortest Path: Path(" + shortest + "): ";
- for( int i = 0; i < pList.get( shortest ).size(); i++ )
- {
- msg += pList.get( shortest ).get( i );
- if( i + 1 != pList.get( shortest ).size() )
- msg += " => ";
- }
- msg += "\n" + "Longest acyclic path has length: " + max;
- msg += "\n" + "Total number of acyclic paths: " + pList.size() + 1;
- }
- JOptionPane.showMessageDialog( null, msg );
- showPath();
- }
- //----------------------- showPath() -------------------------------
- /**
- * Change the color and/or width of the edges on the current path
- * so they are clearly distinguishable from other edges.
- *
- * You can have a way to mark the edges so that when the edges
- * are being drawn, you can change the color as you are drawing
- * (in paintComponent or some method called by paintComponent)
- * -- or you can have a color stored with the edge and change it
- * there.
- */
- public void showPath()
- {
- resetGraph(); // may need to "clear" old markers
- for( int i = 0; i < eList.size(); i++ )
- {
- eList.get( i ).setThickness( 3 );
- }
- repaint();
- }
- //--------------------------- resetGraph() --------------------------------
- /**
- * Does whatever may be necessary to restore the graph to basic state:
- * Certainly will need to clear any visited flags and
- * might reset colors of edges and nodes.
- * Probably makes the "current path" null.
- */
- public void resetGraph()
- {
- updateLabels( );
- for( int i = 0; i < edges.length; i++ )
- {
- edges[ i ].setThickness( 1 );
- }
- this.repaint();
- }
- //--------------------- defineStartEnd() --------------------------------
- /**
- * Open a dialog box to define the start and end nodes
- */
- public void defineStartEnd()
- {
- String prompt = "Enter start and stop nodes, separated by space";
- String noNodeMsg = "Node does not exist: ";
- String nodeName;
- Node node;
- String input = JOptionPane.showInputDialog( null, prompt );
- if ( input == null || input.length() == 0 )
- return;
- Scanner scan = new Scanner( input );
- if ( scan.hasNext() )
- {
- nodeName = scan.next();
- node = graph.getNode( nodeName );
- if ( node == null )
- JOptionPane.showMessageDialog( null, noNodeMsg + nodeName );
- else
- startNode = node;
- }
- if ( scan.hasNext() )
- {
- nodeName = scan.next();
- node = graph.getNode( nodeName );
- if ( node == null )
- JOptionPane.showMessageDialog( null, noNodeMsg + nodeName );
- else
- endNode = node;
- }
- resetGraph();
- this.repaint();
- }
- /**************************************************************************/
- //++++++++++++++++++++++++++ Private Methods +++++++++++++++++++++++++++++++
- //------------------------ parseLine -------------------------------------
- /**
- * parse a line of input from the graph file. Lines are of the form:
- * edge node1 node2
- *
- * where node1 and node2 are arbitrary Strings (with no spaces) that
- * represent a node in the graph. If either node id has not yet been
- * encountered create a Node object for it and add it to the Digraph
- * object.
- * Create an Edge from node1 to node2 and add it to the list of edges
- * in the node1 object.
- * Print an error message for lines that don't start with "edge" or that
- * don't have 2 node fields; you can ignore extra characters after the
- * first 3 tokens on the line.
- */
- private void parseLine( String line )
- {
- if ( line == null || line.trim().length() == 0 )
- return;
- String[] tokens = line.split( " +" );
- /////////////////////////////////////////////////////////////////
- // Valid commands are:
- // node n1 n2 n3 ...
- // edge startOfEdge end1 end2 end3 ...
- // start n
- // end n
- /////////////////////////////////////////////////////////////////
- String cmd = tokens[ 0 ];
- if ( cmd.equals( "edge" ) )
- {
- if ( tokens.length < 3 )
- System.err.println( "Error: need 2 args for Edge command: " + line );
- else
- {
- for ( int n = 2; n < tokens.length; n++ )
- {
- graph.addEdge( tokens[ 1 ], tokens[ n ] );
- }
- }
- }
- else if ( cmd.equals( "node" ))
- {
- for ( int n = 1; n < tokens.length; n++ )
- {
- graph.getAddNode( tokens[ n ] );
- }
- }
- else if ( cmd.equals( "start" ))
- {
- if ( tokens.length < 2 )
- System.err.println( "Error: need an argument: " + line );
- else
- startNode = graph.getAddNode( tokens[ 1 ] );
- }
- else if ( cmd.equals( "end" ))
- {
- if ( tokens.length < 2 )
- System.err.println( "Error: need an argument: " + line );
- else
- endNode = graph.getAddNode( tokens[ 1 ] );
- }
- else
- System.err.println( "Error: input not a valid command: " + line );
- }
- //------------------ openDungeonFile( String filename ) --------------------
- /**
- * opens a new dungeon file and resets all the objects
- * The command processor actually parses the file see that for
- * more details
- */
- private void readGraphFile( String filename )
- {
- Scanner reader;
- graph = new Digraph();
- try
- {
- reader = new Scanner( new File( filename ) );
- while ( reader.hasNextLine() )
- {
- String line = reader.nextLine().trim();
- if ( line.length() > 0 && line.charAt( 0 ) != '#' )
- parseLine( line );
- }
- }
- catch ( java.io.FileNotFoundException e )
- {
- System.err.println( e );
- System.exit( 1 );
- }
- }
- //+++++++++++++++++++++++ main +++++++++++++++++++++++++++++++++++++++++++++
- public static void main( String [ ] args )
- {
- Dungeon.main( args );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement