@Override
	public void start(Stage primaryStage) throws Exception {
		final int PANEL_HEIGHT = maze.height*SQUARE_SIZE;
		final int PANEL_WIDTH = maze.width*SQUARE_SIZE;
		
		Group root = new Group();
		primaryStage.setTitle("Bob's Maze");
	    primaryStage.setScene(new Scene(root));
	         
	    //Draw the maze 
	    Canvas canvas = new Canvas(PANEL_WIDTH, PANEL_HEIGHT);
	    root.getChildren().add(canvas);   
	    GraphicsContext gc = canvas.getGraphicsContext2D();
	    for (int i=0; i<maze.map.size(); i++){
	    	List<Integer> row = maze.map.get(i);
	    	for (int j=0; j<row.size(); j++){
	    		switch (row.get(j).intValue()) {
				case 1:
					gc.setFill(Color.BLACK);
					gc.fillRect(j*SQUARE_SIZE, i*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
					break;
				case 5:
					gc.setFill(Color.YELLOW);
					gc.fillRect(j*SQUARE_SIZE, i*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
					break;
				case 8:
					gc.setFill(Color.BLUE);
					gc.fillRect(j*SQUARE_SIZE, i*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
					break;
				default:
					break;
				}
	    	}
		}
	    
	    //Update population and draw best solution
	    Canvas canvas2 = new Canvas(PANEL_WIDTH, PANEL_HEIGHT);
	    root.getChildren().add(canvas2);
	    GraphicsContext gc2 = canvas2.getGraphicsContext2D();
	    gc2.setFill(Color.RED);
	    new AnimationTimer(){
	        public void handle(long currentNanoTime){
	        	gc2.clearRect(0, 0, PANEL_WIDTH, PANEL_HEIGHT);
	        	pop.newGeneration();
    	    	Chromo<Integer> best = pop.getFittestChromo();
    	    	Point current = new Point(maze.startP.x, maze.startP.y);
    			for (Integer i : best.getGenes()){
    				move(current, i.intValue());
    				if (!maze.isValidPosition(current))
    					break;
    				gc2.fillRect(current.x*SQUARE_SIZE, current.y*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
    			}
    			if (pop.getNumberOfGenerations() >= MAX_GENERATIONS || maze.distToExit(current)==0)
    				this.stop();
	        }
	    }.start();
	    
	    primaryStage.show();
	}