Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.17 KB | None | 0 0
  1. /**
  2.  * Main File
  3.  * Reads in a dungeon file specified as the only argument
  4.  * Creates the maze from the file and displays it
  5.  * Has two buttons, find shortest solution then play back
  6.  * the solution
  7.  *
  8.  * @author Bryan Custer
  9.  * CS416 Fall 2010
  10.  */
  11.  
  12. import javax.swing.*;
  13. import javax.swing.border.Border;
  14. import javax.swing.border.LineBorder;
  15. import java.awt.*;
  16. import java.awt.BorderLayout;
  17. import java.util.*;
  18. import java.io.File;
  19.  
  20. public class GamePanel extends JPanel
  21. {
  22.   //----------------------- Instance Variables -------------------------------
  23.   private DrawPanel     drawing;
  24.   private GUIPanel      gp;
  25.   private int           windowSize = 600;
  26.   private Digraph       graph;
  27.   private Node          startNode;
  28.   private Node          endNode;
  29.  
  30.   private HashMap<String, JLabel> labelCon = null;
  31.   private HashMap<String, Arrow> edgeCon = null;
  32.   private HashMap<String, Node> hash = null;
  33.   private ArrayList<Edge> edgeArr = null;
  34.   private JLabel label[ ] = null;
  35.   private Arrow edges[ ] = null;
  36.  
  37.   private ArrayList<String> path = null;
  38.   private ArrayList<ArrayList<String>> pList = null;
  39.   private ArrayList<Arrow> eList = null;
  40.  
  41.   public static double pi = 3.14159268;
  42.   //++++++++++++++++++++++++++++ Constructors ++++++++++++++++++++++++++++++++
  43.   /**
  44.    * Reads in the dungeon file and creates the display
  45.    */
  46.   public GamePanel( String filename )    
  47.   {
  48.     setLayout( new BorderLayout() );
  49.     setSize( windowSize, windowSize );  
  50.    
  51.     gp = new GUIPanel( this );
  52.     add( gp, BorderLayout.NORTH );
  53.    
  54.     drawing = new DrawPanel();
  55.     add( drawing, BorderLayout.CENTER );
  56.    
  57.     readGraphFile( filename );
  58.    
  59.     labelCon = graph.getLabels();
  60.     edgeCon = graph.getEdges();
  61.     hash = graph.getNodes();
  62.     edgeArr = graph.getEdgesArray();
  63.    
  64.     updateLabels( );
  65.     drawLines( );
  66.   }
  67.  
  68.   //++++++++++++++++++++++++++++ Public Methods ++++++++++++++++++++++++++++++
  69.  
  70.   //----------------------- drawLines( ) ----------------------------------
  71.   /**
  72.    * Draws the Arrow (edges) forom node to node.
  73.    */
  74.   public void drawLines( )
  75.   {
  76.     edges = new Arrow[ edgeCon.size() ];
  77.     edgeCon.values().toArray( edges );
  78.  
  79.     for( int i = 0; i < edgeArr.size(); i++ )
  80.     {
  81.  
  82.       JLabel tempLabelS = labelCon.get( edgeArr.get( i ).start.getId() );
  83.       JLabel tempLabelE = labelCon.get( edgeArr.get( i ).end.getId() );
  84.  
  85.       Point one = new Point( tempLabelS.getX(), tempLabelS.getY() );
  86.       Point two = new Point( tempLabelE.getX() + tempLabelE.getWidth(),
  87.                              tempLabelE.getY() + tempLabelE.getHeight() );
  88.       edgeCon.get( tempLabelS.getText() +
  89.                   tempLabelE.getText() ).setLine( one, two );
  90.      
  91.       drawing.draw( edges[ i ] );
  92.     }
  93.   }
  94.   //----------------------- updateLabels( ) ----------------------------------
  95.   /**
  96.    * Updates the position of the labels around a cirlce and differentiate the
  97.    * start and end nodes.
  98.    */
  99.   public void updateLabels( )
  100.   {
  101.     label = new JLabel[ labelCon.size() ];
  102.     labelCon.values().toArray( label );
  103.    
  104.     for( int i = 0; i < label.length; i++ )
  105.     {
  106.       Border border = new LineBorder( Color.BLACK, 1 );
  107.       label[ i ].setBorder( border );
  108.       label[ i ].setHorizontalAlignment( JLabel.CENTER );
  109.       label[ i ].setSize( label[ i ].getPreferredSize() );
  110.       label[ i ].setForeground( Color.BLACK );
  111.       label[ i ].setOpaque( true );
  112.       label[ i ].setBackground( Color.WHITE );
  113.      
  114.       if( startNode != null &&
  115.          label[i].getText().equals( startNode.toString() ) )
  116.       {
  117.         label[ i ].setBackground( new Color(0x3CAB0B) );
  118.         label[ i ].setForeground( Color.WHITE );
  119.       }
  120.       if( endNode != null &&
  121.          label[i].getText().equals( endNode.toString() ) )
  122.       {
  123.         label[ i ].setBackground( Color.RED );
  124.         label[ i ].setForeground( Color.WHITE );
  125.       }
  126.      
  127.       double r = ( windowSize / 2 ) - 25; // to adjust for size of label
  128.       int x = (int)Math.round( r * Math.cos( i * 2 * pi / label.length ) );
  129.       int y = (int)Math.round( r * Math.sin( i * 2 * pi / label.length ) );
  130.       label[ i ].setLocation( x + 4 + (int)r, y + 4 + (int)r);
  131.      
  132.       drawing.add( label[ i ] );
  133.     }
  134.   }
  135.   //---------------------- findAPath() --------------------------------
  136.   /**
  137.    * Starts the recursive digraph algorithm to find any path from start to end
  138.    * Start and end room must be defined
  139.    */
  140.   public void findAPath()
  141.   {
  142.     resetGraph();
  143.    
  144.     path = new ArrayList<String>();
  145.     pList = new ArrayList<ArrayList<String>>();
  146.     eList = new ArrayList<Arrow>();
  147.    
  148.     if( findPath( path, pList, eList, startNode, endNode, Dungeon.reportLevel) )
  149.     {
  150.       for( int i = 0; i < label.length; i++ )
  151.         hash.get( label[ i ].getText() ).setMarked( false );
  152.      
  153.       String msg = "Path Found: ";
  154.       //-------------------- REPORT LEVEL ZERO -------------------------------
  155.       if( Dungeon.reportLevel == 0 )
  156.       {
  157.         eList.clear();
  158.         for( int i = 0; i < pList.get( 0 ).size(); i++ )
  159.         {
  160.           if( i < pList.get( 0 ).size() - 1 )
  161.           {
  162.             eList.add( edgeCon.get( pList.get( 0 ).get( i ) +
  163.                                    pList.get( 0 ).get( i + 1 ) ) );
  164.             showPath();
  165.           }
  166.           msg += pList.get( 0 ).get( i );
  167.           if( i + 1 != pList.get( 0 ).size() )
  168.             msg += " => ";
  169.         }
  170.         showPath();
  171.         System.out.println( msg );
  172.         JOptionPane.showMessageDialog( null, msg );
  173.       }
  174.       //--------------- REPORT LEVEL ONE, TWO, THREE  -------------------------
  175.       else if( Dungeon.reportLevel == 1 || Dungeon.reportLevel == 2 ||
  176.                Dungeon.reportLevel == 3 )
  177.       {
  178.         for( int k = 0; k < pList.size(); k++ )
  179.         {
  180.           msg = "Path Found(" + k + "): ";
  181.           eList.clear();
  182.           for( int i = 0; i < pList.get( k ).size(); i++ )
  183.           {
  184.             if( i < pList.get( k ).size() - 1 )
  185.             {
  186.               eList.add( edgeCon.get( pList.get( k ).get( i ) +
  187.                                      pList.get( k ).get( i + 1 ) ) );
  188.               showPath();
  189.             }
  190.             msg += pList.get( k ).get( i );
  191.             if( Dungeon.reportLevel == 3 )
  192.               JOptionPane.showMessageDialog( null, msg );
  193.             if( i + 1 != pList.get( k ).size() )
  194.               msg += " => ";
  195.           }
  196.           showPath();
  197.           System.out.println( msg );
  198.           JOptionPane.showMessageDialog( null, msg );
  199.         }
  200.       }
  201.     }
  202.     else
  203.     {
  204.       String msg = "No path found";
  205.       JOptionPane.showMessageDialog( null, msg );
  206.     }
  207.     //showPath();
  208.   }
  209.   //--------------------- findAPath( Node, Node ) -----------------------------
  210.   /**
  211.    * The recursive digraph algorithm to find all paths from start to end
  212.    */
  213.   public Boolean findPath( ArrayList<String> p, ArrayList<ArrayList<String>> pL,
  214.                           ArrayList<Arrow> eL, Node s, Node e, int n )
  215.   {
  216.     if ( s.getMarked() )
  217.     {
  218.       if( n == 2 )
  219.       {
  220.         String msg = "CYCLE DETECTED: ";
  221.         System.out.println( s.toString() );
  222.         for( int i = 0; i < p.size(); i++ )
  223.         {
  224.           msg += p.get( i );
  225.           if( i + 1 != p.size() )
  226.             msg += " => ";
  227.         }
  228.         JOptionPane.showMessageDialog( null, msg );
  229.       }
  230.       return false;
  231.     }
  232.      // Reached the end
  233.     if ( s.getId().equals( e.getId() ) )
  234.     {
  235.       p.add( s.getId() );
  236.      
  237.       if( pL.contains( p ) )
  238.       {
  239.         p.remove( s.getId() );
  240.         return false;
  241.       }
  242.       else
  243.       {
  244.         ArrayList<String> tempPath = new ArrayList<String>();;
  245.        
  246.         tempPath.addAll(p);
  247.        
  248.         pL.add( tempPath );
  249.         p.remove( s.getId() );
  250.        
  251.         return true;
  252.       }
  253.     }
  254.    
  255.     ArrayList<Edge> edges = s.getEdges();
  256.     // No more edges
  257.     if( edges == null )
  258.     {
  259.       p.remove( s.getId() );
  260.       return false;
  261.     }
  262.    
  263.     p.add( s.getId() );
  264.     s.setMarked( true );
  265.  
  266.     Boolean tempRet = false;
  267.     for( int i = 0; i < edges.size(); i++ )
  268.     {
  269.       if( findPath( p, pL, eL, edges.get( i ).end, e, n ) )
  270.       {
  271.         tempRet = true;
  272.       }
  273.     }
  274.  
  275.     s.setMarked( false );
  276.     p.remove( s.getId() );
  277.    
  278.     return tempRet;
  279.   }
  280.   //---------------------- findShortestPath() --------------------------------
  281.   /**
  282.    * Starts the recursive algorithm to find the shortest path
  283.    * Start and end room must be defined
  284.    */
  285.   public void findShortestPath()
  286.   {
  287.     String msg = "No path found";
  288.     resetGraph();
  289.    
  290.     findAPath();
  291.  
  292.     if( pList != null && pList.size() > 0 )
  293.     {
  294.       int min = pList.get( 0 ).size();
  295.      
  296.       int shortest = 0;
  297.       for( int i = 0; i < pList.size(); i++ )
  298.       {
  299.         if( pList.get( i ).size() < min )
  300.         {
  301.           min = pList.get( i ).size();
  302.           shortest = i;
  303.         }
  304.       }
  305.      
  306.       int max = pList.get( 0 ).size();
  307.       int longest = 0;
  308.       for( int i = 0; i < pList.size(); i++ )
  309.       {
  310.         if( pList.get( i ).size() > max )
  311.         {
  312.           max = pList.get( i ).size();
  313.           longest = i;
  314.         }
  315.       }
  316.      
  317.       msg = "Shortest Path: Path(" + shortest + "): ";
  318.      
  319.       for( int i = 0; i < pList.get( shortest ).size(); i++ )
  320.       {
  321.         msg += pList.get( shortest ).get( i );
  322.         if( i + 1 != pList.get( shortest ).size() )
  323.           msg += " => ";
  324.       }
  325.       msg += "\n" + "Longest acyclic path has length: " + max;
  326.       msg += "\n" + "Total number of acyclic paths: " + pList.size() + 1;
  327.     }
  328.       JOptionPane.showMessageDialog( null, msg );
  329.       showPath();
  330.   }
  331.  
  332.   //----------------------- showPath() -------------------------------
  333.   /**
  334.    * Change the color and/or width of the edges on the current path
  335.    * so they are clearly distinguishable from other edges.
  336.    *
  337.    * You can have a way to mark the edges so that when the edges
  338.    * are being drawn, you can change the color as you are drawing
  339.    * (in paintComponent or some method called by paintComponent)
  340.    * -- or you can have a color stored with the edge and change it
  341.    * there.
  342.    */
  343.   public void showPath()
  344.   {
  345.     resetGraph();  // may need to "clear" old markers
  346.    
  347.     for( int i = 0; i < eList.size(); i++ )
  348.     {
  349.       eList.get( i ).setThickness( 3 );
  350.     }
  351.    
  352.     repaint();
  353.   }
  354.  
  355.   //--------------------------- resetGraph() --------------------------------
  356.   /**
  357.    * Does whatever may be necessary to restore the graph to basic state:
  358.    *   Certainly will need to clear any visited flags and
  359.    *   might reset colors of edges and nodes.
  360.    * Probably makes the "current path" null.
  361.    */
  362.   public void resetGraph()
  363.   {
  364.     updateLabels( );
  365.    
  366.     for( int i = 0; i < edges.length; i++ )
  367.     {
  368.       edges[ i ].setThickness( 1 );
  369.     }
  370.     this.repaint();
  371.   }
  372.   //--------------------- defineStartEnd() --------------------------------
  373.   /**
  374.    * Open a dialog box to define the start and end nodes
  375.    */
  376.   public void defineStartEnd()
  377.   {
  378.     String prompt = "Enter start and stop nodes, separated by space";
  379.     String noNodeMsg = "Node does not exist: ";
  380.     String nodeName;
  381.    
  382.     Node   node;
  383.    
  384.     String input = JOptionPane.showInputDialog( null, prompt );
  385.     if ( input == null || input.length() == 0 )
  386.       return;
  387.     Scanner scan = new Scanner( input );
  388.     if ( scan.hasNext() )
  389.     {
  390.       nodeName = scan.next();
  391.       node = graph.getNode( nodeName );
  392.       if ( node == null )
  393.         JOptionPane.showMessageDialog( null, noNodeMsg + nodeName );
  394.       else
  395.         startNode = node;
  396.     }
  397.     if ( scan.hasNext() )
  398.     {
  399.       nodeName = scan.next();
  400.       node = graph.getNode( nodeName );
  401.       if ( node == null )
  402.         JOptionPane.showMessageDialog( null, noNodeMsg + nodeName );
  403.       else
  404.         endNode = node;
  405.     }
  406.     resetGraph();
  407.     this.repaint();
  408.   }
  409.   /**************************************************************************/
  410.   //++++++++++++++++++++++++++ Private Methods +++++++++++++++++++++++++++++++
  411.   //------------------------ parseLine -------------------------------------
  412.   /**
  413.    * parse a line of input from the graph file. Lines are of the form:
  414.    *    edge node1 node2
  415.    *
  416.    * where node1 and node2 are arbitrary Strings (with no spaces) that
  417.    *       represent a node in the graph. If either node id has not yet been
  418.    *       encountered create a Node object for it and add it to the Digraph
  419.    *       object.
  420.    * Create an Edge from node1 to node2 and add it to the list of edges
  421.    *    in the node1 object.
  422.    * Print an error message for lines that don't start with "edge" or that
  423.    *    don't have 2 node fields; you can ignore extra characters after the
  424.    *    first 3 tokens on the line.
  425.    */
  426.   private void parseLine( String line )
  427.   {
  428.     if ( line == null || line.trim().length() == 0 )
  429.       return;
  430.     String[] tokens = line.split( " +" );
  431.     /////////////////////////////////////////////////////////////////
  432.     // Valid commands are:
  433.     // node n1 n2 n3 ...
  434.     // edge startOfEdge end1 end2 end3 ...
  435.     // start n
  436.     // end   n
  437.     /////////////////////////////////////////////////////////////////
  438.     String cmd = tokens[ 0 ];
  439.     if ( cmd.equals( "edge" ) )
  440.     {
  441.       if ( tokens.length < 3 )
  442.         System.err.println( "Error: need 2 args for Edge command: " + line );
  443.       else
  444.       {
  445.         for ( int n = 2; n < tokens.length; n++ )
  446.         {
  447.           graph.addEdge( tokens[ 1 ], tokens[ n ] );
  448.         }
  449.       }
  450.     }
  451.     else if ( cmd.equals( "node" ))
  452.     {
  453.       for ( int n = 1; n < tokens.length; n++ )
  454.       {
  455.         graph.getAddNode( tokens[ n ] );
  456.       }
  457.     }
  458.     else if ( cmd.equals( "start" ))
  459.     {
  460.       if ( tokens.length < 2 )
  461.         System.err.println( "Error: need an argument: " + line );
  462.       else
  463.         startNode = graph.getAddNode( tokens[ 1 ] );
  464.     }
  465.     else if ( cmd.equals( "end" ))
  466.     {
  467.       if ( tokens.length < 2 )
  468.         System.err.println( "Error: need an argument: " + line );
  469.       else
  470.         endNode = graph.getAddNode( tokens[ 1 ] );
  471.     }
  472.     else
  473.       System.err.println( "Error: input not a valid command: " + line );      
  474.   }
  475.  
  476.   //------------------ openDungeonFile( String filename ) --------------------
  477.   /**
  478.    * opens a new dungeon file and resets all the objects
  479.    * The command processor actually parses the file see that for
  480.    * more details
  481.    */
  482.   private void readGraphFile( String filename )
  483.   {
  484.     Scanner reader;
  485.     graph = new Digraph();
  486.    
  487.     try
  488.     {
  489.       reader = new Scanner( new File( filename ) );
  490.       while ( reader.hasNextLine() )
  491.       {
  492.         String line = reader.nextLine().trim();
  493.         if ( line.length() > 0 && line.charAt( 0 ) != '#' )
  494.           parseLine( line );
  495.       }
  496.     }
  497.     catch ( java.io.FileNotFoundException e )
  498.     {
  499.       System.err.println( e );
  500.       System.exit( 1 );
  501.     }
  502.   }
  503.  
  504.   //+++++++++++++++++++++++ main +++++++++++++++++++++++++++++++++++++++++++++
  505.   public static void main( String [ ] args )
  506.   {
  507.     Dungeon.main( args );
  508.   }
  509. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement