public ArrayList<int[]> findPath(Map m, Block b){
	
		ArrayList<int[]> pathInfo = new ArrayList<int[]>();
		ArrayList<ArrayList> finalMove = new ArrayList<ArrayList>();
		
		//Make a replacement of the original Map and Block class
		//Use replacement for checking
		Map m2 = new Map(0,THA.HEIGHT,0,THA.WIDTH);
		m2.change(m.getMap());
		Block b2 = new Block(0,0,new Color(0,0,128));
		b2.change(b.getShape());
		
		int[] info; // Stores the information used to determine move
					// index:
					// 0: current x position
					// 1: best x position
					// 2: number of turns
		
		//Initialize variables						 
		int curPos = b.getShape()[0][0].getX()/Square.SIZE; //Current position of the Block, does not change
		int[] shapeIndex; //The index range containing the actual tetris piece, USED IN CHECKING HEIGHT
		double height; //The height of the map within a specific index range, used to determine move 
		double gap; //The gap not filled in the Block Square[][] once it's added to map, used to determine move
		double sides; //The number of shape sides in the map, used to determine move
		int maxSides = m.getNumSides(); //The number of shape sides in the map before adding the Block
		int maxHeight = THA.HEIGHT/Square.SIZE; //The maximum height of the map
		int maxGap = b2.getShape().length*b2.getShape()[0].length; //The maximum gaps in Block Square[][].
		double total; //total score of all factors
		double maxTotal = 0;
		
		//Determining move...
		 for(int i=0;i<4;i++){ //number of turns 0-3
			for(int j=0;j<THA.WIDTH/Square.SIZE;j++){ //number of horizontal positions on the map
				
				//Since we are using b and m as reference to reset b2 and m2, therefore it's best to not change them during checking. Therefore 3 more for loops are needed below.
				
				//Turns the shape to the desired position
				for(int l=0;l<i;l++){
					b2.turn();
				}
				
				//Moves the shape to the left most position on the map
				//*Note: it's important to turn first then move because turning on edges may cause bugs
				for(int k=0;k<THA.WIDTH/Square.SIZE;k++){
					b2.moveLeft(m2);
				}
				
				//Moves the shape to the desired x position
				for(int n = 0;n<j;n++){
					b2.moveRight(m2);
				}
				
				//Drop the shape and add it to the map
				b2.completeFall(m2);
				m2.addShape(b2);
				
				//Storing information about the moves
				shapeIndex = b2.getWidthIndex();
				info = new int[3];
				info[0] = curPos; info[1] = j-shapeIndex[0]; info[2] = i;
				
				//Begin checking:
				sides = calcSides(m2,maxSides);
				height = calcHeight(m2,b2,maxHeight,shapeIndex);
				gap = calcGap(m2,b2,maxGap);
				total = sides+height+gap;
				if(total>maxTotal){
					pathInfo = new ArrayList<int[]>();
					pathInfo.add(info);
					maxTotal = total;
				}else if(total==maxTotal && maxTotal!=0){
					pathInfo.add(info);
				}
				
				//Resetting m2 and b2
				b2.change(b.getShape());
				b2.changeHitGround(false);
				m2.change(m.getMap());
			}
		}
		return pathInfo;
	}